summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Roster/Roster.cpp')
-rw-r--r--Swiften/Roster/Roster.cpp127
1 files changed, 127 insertions, 0 deletions
diff --git a/Swiften/Roster/Roster.cpp b/Swiften/Roster/Roster.cpp
new file mode 100644
index 0000000..61c0286
--- /dev/null
+++ b/Swiften/Roster/Roster.cpp
@@ -0,0 +1,127 @@
+#include "Swiften/Roster/Roster.h"
+
+#include "Swiften/Base/foreach.h"
+#include "Swiften/Base/String.h"
+#include "Swiften/JID/JID.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+#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 <deque>
+
+namespace Swift {
+
+Roster::Roster(TreeWidget *treeWidget, TreeWidgetFactory *widgetFactory) : treeWidget_(treeWidget), widgetFactory_(widgetFactory) {
+}
+
+Roster::~Roster() {
+ foreach (RosterItem* item, items_) {
+ delete item;
+ }
+ delete treeWidget_;
+}
+
+TreeWidget* Roster::getWidget() {
+ return treeWidget_;
+}
+
+GroupRosterItem* Roster::getGroup(const String& groupName) {
+ foreach (RosterItem *item, children_) {
+ GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item);
+ if (group && group->getName() == groupName) {
+ return group;
+ }
+ }
+ GroupRosterItem* group = new GroupRosterItem(groupName, treeWidget_, widgetFactory_);
+ children_.push_back(group);
+ items_.push_back(group);
+ return group;
+}
+
+void Roster::handleUserAction(boost::shared_ptr<UserRosterAction> action) {
+ onUserAction(action);
+}
+
+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);
+ item->onUserAction.connect(boost::bind(&Roster::handleUserAction, this, _1));
+ filterItem(item);
+
+}
+
+void Roster::removeContact(const JID& jid) {
+ 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);
+ }
+ it++;
+ }
+}
+
+void Roster::applyOnItems(const RosterItemOperation& operation) {
+ std::deque<RosterItem*> queue(children_.begin(), children_.end());
+ while (!queue.empty()) {
+ RosterItem* item = *queue.begin();
+ queue.pop_front();
+ operation(item);
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
+ }
+ }
+ filterAll();
+}
+
+void Roster::removeFilter(RosterFilter *filter) {
+ for (unsigned int i = 0; i < filters_.size(); i++) {
+ if (filters_[i] == filter) {
+ filters_.erase(filters_.begin() + i);
+ break;
+ }
+ }
+ filterAll();
+}
+
+
+void Roster::filterItem(RosterItem* rosterItem) {
+ ContactRosterItem *item = dynamic_cast<ContactRosterItem*>(rosterItem);
+ if (!item) {
+ return;
+ }
+ bool hide = true;
+ foreach (RosterFilter *filter, filters_) {
+ hide &= (*filter)(item);
+ }
+ filters_.size() > 0 && hide ? item->hide() : item->show();
+}
+
+void Roster::filterAll() {
+ std::deque<RosterItem*> queue(children_.begin(), children_.end());
+ 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);
+ }
+ }
+}
+
+}
+