summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Roster/Roster.cpp')
-rw-r--r--Swiften/Roster/Roster.cpp128
1 files changed, 77 insertions, 51 deletions
diff --git a/Swiften/Roster/Roster.cpp b/Swiften/Roster/Roster.cpp
index 8c2aa0e..c25fd41 100644
--- a/Swiften/Roster/Roster.cpp
+++ b/Swiften/Roster/Roster.cpp
@@ -13,79 +13,93 @@
#include "Swiften/Roster/RosterItem.h"
#include "Swiften/Roster/GroupRosterItem.h"
#include "Swiften/Roster/RosterItemOperation.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
#include <boost/bind.hpp>
+#include <iostream>
#include <deque>
namespace Swift {
-Roster::Roster(TreeWidget *treeWidget, TreeWidgetFactory *widgetFactory) : treeWidget_(treeWidget), widgetFactory_(widgetFactory) {
+Roster::Roster() {
+ root_ = new GroupRosterItem("Dummy-Root", NULL);
}
Roster::~Roster() {
- foreach (RosterItem* item, items_) {
+ std::deque<RosterItem*> queue;
+ queue.push_back(root_);
+ while (!queue.empty()) {
+ RosterItem* item = *queue.begin();
+ queue.pop_front();
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
+ }
delete item;
}
- delete treeWidget_;
}
-TreeWidget* Roster::getWidget() {
- return treeWidget_;
+GroupRosterItem* Roster::getRoot() {
+ return root_;
}
GroupRosterItem* Roster::getGroup(const String& groupName) {
- foreach (RosterItem *item, children_) {
+ foreach (RosterItem *item, root_->getChildren()) {
GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item);
- if (group && group->getName() == groupName) {
+ if (group && group->getDisplayName() == groupName) {
return group;
}
}
- GroupRosterItem* group = new GroupRosterItem(groupName, treeWidget_, widgetFactory_);
- children_.push_back(group);
- items_.push_back(group);
+ GroupRosterItem* group = new GroupRosterItem(groupName, root_);
+ root_->addChild(group);
+// std::cout << "Added " << groupName << " to root" << std::endl;
+ group->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, group));
+ group->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, group));
return group;
}
-void Roster::handleUserAction(boost::shared_ptr<UserRosterAction> action) {
- onUserAction(action);
+void Roster::handleDataChanged(RosterItem* item) {
+ onDataChanged(item);
}
-void Roster::addContact(const JID& jid, const String& name, const String& group) {
- ContactRosterItem *item = new ContactRosterItem(jid, name, getGroup(group), widgetFactory_);
- items_.push_back(item);
- itemMap_[jid.toBare()].push_back(item);
- item->onUserAction.connect(boost::bind(&Roster::handleUserAction, this, _1));
- filterItem(item);
+void Roster::handleChildrenChanged(GroupRosterItem* item) {
+ onChildrenChanged(item);
+}
+void Roster::addContact(const JID& jid, const String& name, const String& groupName) {
+ GroupRosterItem* group(getGroup(groupName));
+ ContactRosterItem *item = new ContactRosterItem(jid, name, group);
+ group->addChild(item);
+ itemMap_[jid.toBare()].push_back(item);
+ item->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, item));
+ filterContact(item, group);
}
+
void Roster::removeContact(const JID& jid) {
- itemMap_.erase(jid.toBare());
- std::vector<RosterItem*>::iterator it = children_.begin();
- while (it != children_.end()) {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it);
- if (contact && contact->getJID() == jid) {
- delete contact;
- it = children_.erase(it);
- continue;
- }
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
- if (group) {
- group->removeChild(jid);
+ std::vector<ContactRosterItem*> items = itemMap_[jid.toBare()];
+ std::vector<ContactRosterItem*>::iterator it = items.begin();
+ while (it != items.end()) {
+ if (jid == (*it)->getJID()) {
+ it = items.erase(it);
}
- it++;
}
+ if (items.size() == 0) {
+ itemMap_.erase(jid.toBare());
+ }
+ //Causes the delete
+ root_->removeChild(jid);
}
void Roster::removeContactFromGroup(const JID& jid, const String& groupName) {
- std::vector<RosterItem*>::iterator it = children_.begin();
- while (it != children_.end()) {
+ std::vector<RosterItem*> children = root_->getChildren();
+ std::vector<RosterItem*>::iterator it = children.begin();
+ while (it != children.end()) {
GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
- if (group && group->getName() == groupName) {
- group->removeChild(jid);
+ if (group && group->getDisplayName() == groupName) {
+ ContactRosterItem* deleted = group->removeChild(jid);
+ std::vector<ContactRosterItem*> items = itemMap_[jid.toBare()];
+ items.erase(std::remove(items.begin(), items.end(), deleted), items.end());
}
it++;
}
@@ -101,14 +115,15 @@ void Roster::applyOnItems(const RosterItemOperation& operation) {
}
void Roster::applyOnItem(const RosterItemOperation& operation, const JID& jid) {
- foreach (RosterItem* item, itemMap_[jid]) {
+ foreach (ContactRosterItem* item, itemMap_[jid.toBare()]) {
operation(item);
- filterItem(item);
+ filterContact(item, item->getParent());
}
}
void Roster::applyOnAllItems(const RosterItemOperation& operation) {
- std::deque<RosterItem*> queue(children_.begin(), children_.end());
+ std::deque<RosterItem*> queue;
+ queue.push_back(root_);
while (!queue.empty()) {
RosterItem* item = *queue.begin();
queue.pop_front();
@@ -131,29 +146,40 @@ void Roster::removeFilter(RosterFilter *filter) {
filterAll();
}
-
-void Roster::filterItem(RosterItem* rosterItem) {
- ContactRosterItem *item = dynamic_cast<ContactRosterItem*>(rosterItem);
- if (!item) {
- return;
- }
+void Roster::filterContact(ContactRosterItem* contact, GroupRosterItem* group) {
+ int oldDisplayedSize = group->getDisplayedChildren().size();
bool hide = true;
foreach (RosterFilter *filter, filters_) {
- hide &= (*filter)(item);
+ hide &= (*filter)(contact);
+ }
+ group->setDisplayed(contact, filters_.size() == 0 || !hide);
+ int newDisplayedSize = group->getDisplayedChildren().size();
+// std::cout << ", new size = " << newDisplayedSize << std::endl;
+ if (oldDisplayedSize == 0 && newDisplayedSize > 0) {
+// std::cout << "Newly created" << std::endl;
+ onGroupAdded(group);
+ }
+}
+
+void Roster::filterGroup(GroupRosterItem* group) {
+ foreach (RosterItem* child, group->getChildren()) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(child);
+ if (contact) {
+ filterContact(contact, group);
+ }
}
- filters_.size() > 0 && hide ? item->hide() : item->show();
}
void Roster::filterAll() {
- std::deque<RosterItem*> queue(children_.begin(), children_.end());
+ std::deque<RosterItem*> queue;
+ queue.push_back(root_);
while (!queue.empty()) {
RosterItem *item = *queue.begin();
queue.pop_front();
GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
if (group) {
queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
- } else {
- filterItem(item);
+ filterGroup(group);
}
}
}