diff options
Diffstat (limited to 'Swiften/Roster')
24 files changed, 776 insertions, 0 deletions
diff --git a/Swiften/Roster/ContactRosterItem.cpp b/Swiften/Roster/ContactRosterItem.cpp new file mode 100644 index 0000000..f38b0f7 --- /dev/null +++ b/Swiften/Roster/ContactRosterItem.cpp @@ -0,0 +1,51 @@ +#include "Swiften/Roster/ContactRosterItem.h" +#include "Swiften/Roster/GroupRosterItem.h" + +namespace Swift { + + +ContactRosterItem::ContactRosterItem(const JID& jid, const String& name, GroupRosterItem* parent, TreeWidgetFactory* factory) : jid_(jid), name_(name) { + parent->addChild(this); + widget_ = factory->createTreeWidgetItem(parent->getWidget()); + widget_->setText(name.isEmpty() ? jid.toString() : name); + widget_->onUserAction.connect(boost::bind(&ContactRosterItem::handleUserAction, this, _1)); + setStatusShow(StatusShow::None); +} + +ContactRosterItem::~ContactRosterItem() { + delete widget_; +} + +StatusShow::Type ContactRosterItem::getStatusShow() { + return statusShow_; +} + +void ContactRosterItem::setStatusShow(StatusShow::Type show) { + statusShow_ = show; + int colour = 0; + switch (show) { + case StatusShow::Online: colour = 0x000000;break; + case StatusShow::Away: colour = 0x336699;break; + case StatusShow::XA: colour = 0x336699;break; + case StatusShow::FFC: colour = 0x000000;break; + case StatusShow::DND: colour = 0x990000;break; + case StatusShow::None: colour = 0x7F7F7F;break; + } + widget_->setTextColor(colour); +} + +const JID& ContactRosterItem::getJID() const { + return jid_; +} + +void ContactRosterItem::show() { + widget_->show(); +} + +void ContactRosterItem::hide() { + widget_->hide(); +} + +} + + diff --git a/Swiften/Roster/ContactRosterItem.h b/Swiften/Roster/ContactRosterItem.h new file mode 100644 index 0000000..20f9f65 --- /dev/null +++ b/Swiften/Roster/ContactRosterItem.h @@ -0,0 +1,39 @@ +#ifndef SWIFTEN_ContactRosterItem_H +#define SWIFTEN_ContactRosterItem_H + +#include "Swiften/Base/String.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Roster/TreeWidgetFactory.h" +#include "Swiften/Roster/RosterItem.h" +#include "Swiften/Roster/UserRosterAction.h" +#include "Swiften/Elements/StatusShow.h" + +#include <boost/bind.hpp> +#include <boost/signal.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + +class TreeWidgetItem; +class GroupRosterItem; +class ContactRosterItem : public RosterItem { + public: + ContactRosterItem(const JID& jid, const String& name, GroupRosterItem* parent, TreeWidgetFactory* factory); + ~ContactRosterItem(); + + StatusShow::Type getStatusShow(); + void setStatusShow(StatusShow::Type show); + const JID& getJID() const; + void show(); + void hide(); + + private: + JID jid_; + String name_; + TreeWidgetItem *widget_; + StatusShow::Type statusShow_; +}; + +} +#endif + diff --git a/Swiften/Roster/GroupRosterItem.h b/Swiften/Roster/GroupRosterItem.h new file mode 100644 index 0000000..f96a868 --- /dev/null +++ b/Swiften/Roster/GroupRosterItem.h @@ -0,0 +1,70 @@ +#ifndef SWIFTEN_GroupRosterItem_H +#define SWIFTEN_GroupRosterItem_H + +#include "Swiften/Roster/RosterItem.h" +#include "Swiften/Base/String.h" +#include "Swiften/Roster/TreeWidget.h" +#include "Swiften/Roster/TreeWidgetFactory.h" +#include "Swiften/Roster/TreeWidgetItem.h" +#include "Swiften/Roster/ContactRosterItem.h" + +#include <list> + +namespace Swift { + +class GroupRosterItem : public RosterItem { + public: + GroupRosterItem(const String& name, TreeWidget* tree, TreeWidgetFactory* factory) : name_(name) { + widget_ = factory->createTreeWidgetItem(tree); + widget_->setExpanded(true); + widget_->setText(name); + widget_->setTextColor(0xFFFFFF); + widget_->setBackgroundColor(0x969696); + } + + ~GroupRosterItem() { + delete widget_; + } + + const String& getName() const { + return name_; + } + + TreeWidgetItem* getWidget() const { + return widget_; + } + + const std::list<RosterItem*>& getChildren() const { + return children_; + } + + void addChild(RosterItem* item) { + children_.push_back(item); + } + + void removeChild(const JID& jid) { + std::list<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++; + } + } + + private: + String name_; + TreeWidgetItem* widget_; + std::list<RosterItem*> children_; +}; + +} +#endif + diff --git a/Swiften/Roster/Makefile.inc b/Swiften/Roster/Makefile.inc new file mode 100644 index 0000000..7c5b007 --- /dev/null +++ b/Swiften/Roster/Makefile.inc @@ -0,0 +1,6 @@ +SWIFTEN_SOURCES += \ + Swiften/Roster/ContactRosterItem.cpp \ + Swiften/Roster/Roster.cpp \ + Swiften/Roster/XMPPRoster.cpp + +include Swiften/Roster/UnitTest/Makefile.inc diff --git a/Swiften/Roster/OfflineRosterFilter.h b/Swiften/Roster/OfflineRosterFilter.h new file mode 100644 index 0000000..512d074 --- /dev/null +++ b/Swiften/Roster/OfflineRosterFilter.h @@ -0,0 +1,24 @@ +#ifndef SWIFTEN_OfflineRosterFilter_H +#define SWIFTEN_OfflineRosterFilter_H + +#include "Swiften/Roster/ContactRosterItem.h" +#include "Swiften/Roster/RosterItem.h" +#include "Swiften/Roster/RosterFilter.h" +#include "Swiften/Elements/StatusShow.h" + +namespace Swift { + +class OfflineRosterFilter : public RosterFilter { + public: + virtual ~OfflineRosterFilter() {} + virtual bool operator() (RosterItem *item) const { + ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item); + return contactItem && contactItem->getStatusShow() == StatusShow::None; + } +}; + +} +#endif + + + diff --git a/Swiften/Roster/OpenChatRosterAction.h b/Swiften/Roster/OpenChatRosterAction.h new file mode 100644 index 0000000..03715a5 --- /dev/null +++ b/Swiften/Roster/OpenChatRosterAction.h @@ -0,0 +1,20 @@ +#ifndef SWIFTEN_OpenChatRosterAction_H +#define SWIFTEN_OpenChatRosterAction_H + +#include "Swiften/Roster/UserRosterAction.h" + +namespace Swift { +class RosterItem; +class TreeWidgetItem; + +class OpenChatRosterAction : public UserRosterAction { + public: + virtual ~OpenChatRosterAction() {}; + +}; + +} +#endif + + + 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); + } + } +} + +} + diff --git a/Swiften/Roster/Roster.h b/Swiften/Roster/Roster.h new file mode 100644 index 0000000..cdd1407 --- /dev/null +++ b/Swiften/Roster/Roster.h @@ -0,0 +1,48 @@ +#ifndef SWIFTEN_Roster_H +#define SWIFTEN_Roster_H + +#include "Swiften/Base/String.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Roster/RosterItemOperation.h" +#include "Swiften/Roster/UserRosterAction.h" +#include "Swiften/Roster/RosterFilter.h" + +#include <vector> +#include <boost/signal.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + +class TreeWidgetFactory; +class TreeWidget; +class RosterItem; +class GroupRosterItem; + +class Roster { + public: + Roster(TreeWidget *treeWidget, TreeWidgetFactory *widgetFactory); + ~Roster(); + + TreeWidget* getWidget(); + GroupRosterItem* getGroup(const String& groupName); + void addContact(const JID& jid, const String& name, const String& group); + void removeContact(const JID& jid); + void applyOnItems(const RosterItemOperation& operation); + boost::signal<void (boost::shared_ptr<UserRosterAction>)> onUserAction; + void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();} + void removeFilter(RosterFilter *filter); + std::vector<RosterFilter*> getFilters() {return filters_;} + + private: + void filterItem(RosterItem* item); + void filterAll(); + void handleUserAction(boost::shared_ptr<UserRosterAction> action); + TreeWidget *treeWidget_; + TreeWidgetFactory *widgetFactory_; + std::vector<RosterItem*> children_; + std::vector<RosterItem*> items_; + std::vector<RosterFilter*> filters_; +}; +} + +#endif diff --git a/Swiften/Roster/RosterFilter.h b/Swiften/Roster/RosterFilter.h new file mode 100644 index 0000000..a824304 --- /dev/null +++ b/Swiften/Roster/RosterFilter.h @@ -0,0 +1,17 @@ +#ifndef SWIFTEN_RosterFilter_H +#define SWIFTEN_RosterFilter_H + +#include "Swiften/Roster/RosterItem.h" + +namespace Swift { + +class RosterFilter { + public: + virtual ~RosterFilter() {} + virtual bool operator() (RosterItem* item) const = 0; +}; + +} +#endif + + diff --git a/Swiften/Roster/RosterItem.h b/Swiften/Roster/RosterItem.h new file mode 100644 index 0000000..2707920 --- /dev/null +++ b/Swiften/Roster/RosterItem.h @@ -0,0 +1,24 @@ +#ifndef SWIFTEN_RosterItem_H +#define SWIFTEN_RosterItem_H + +#include "Swiften/Roster/UserRosterAction.h" + +#include <boost/signal.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + +class RosterItem { + public: + virtual ~RosterItem() {}; + boost::signal<void (boost::shared_ptr<UserRosterAction>)> onUserAction; + protected: + void handleUserAction(boost::shared_ptr<UserRosterAction> action) { + action->setRosterItem(this); + onUserAction(action); + } +}; + +} +#endif + diff --git a/Swiften/Roster/RosterItemOperation.h b/Swiften/Roster/RosterItemOperation.h new file mode 100644 index 0000000..ea8e723 --- /dev/null +++ b/Swiften/Roster/RosterItemOperation.h @@ -0,0 +1,16 @@ +#ifndef SWIFTEN_RosterItemOperation_H +#define SWIFTEN_RosterItemOperation_H + +#include "Swiften/Roster/RosterItem.h" + +namespace Swift { + +class RosterItemOperation { + public: + virtual ~RosterItemOperation() {} + virtual void operator() (RosterItem*) const = 0; +}; + +} +#endif + diff --git a/Swiften/Roster/SetPresence.h b/Swiften/Roster/SetPresence.h new file mode 100644 index 0000000..aa36a52 --- /dev/null +++ b/Swiften/Roster/SetPresence.h @@ -0,0 +1,36 @@ +#ifndef SWIFTEN_SetPresence_H +#define SWIFTEN_SetPresence_H + +#include "Swiften/Elements/Presence.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Roster/RosterItemOperation.h" +#include "Swiften/Roster/ContactRosterItem.h" + +namespace Swift { + +class RosterItem; + +class SetPresence : public RosterItemOperation { + public: + SetPresence(boost::shared_ptr<Presence> presence, JID::CompareType compareType = JID::WithoutResource) : presence_(presence), compareType_(compareType) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(presence_->getFrom(), compareType_)) { + if (presence_->getType() != Presence::Available) { + contact->setStatusShow(StatusShow::None); + } else { + contact->setStatusShow(presence_->getShow()); + } + } + } + + private: + boost::shared_ptr<Presence> presence_; + JID::CompareType compareType_; +}; + +} +#endif + diff --git a/Swiften/Roster/TreeWidget.h b/Swiften/Roster/TreeWidget.h new file mode 100644 index 0000000..a26003e --- /dev/null +++ b/Swiften/Roster/TreeWidget.h @@ -0,0 +1,13 @@ +#ifndef SWIFTEN_TreeWidget_H +#define SWIFTEN_TreeWidget_H + +namespace Swift { + +class TreeWidget { + public: + virtual ~TreeWidget() {} +}; + +} +#endif + diff --git a/Swiften/Roster/TreeWidgetFactory.h b/Swiften/Roster/TreeWidgetFactory.h new file mode 100644 index 0000000..f4ba68d --- /dev/null +++ b/Swiften/Roster/TreeWidgetFactory.h @@ -0,0 +1,20 @@ +#ifndef SWIFTEN_TreeWidgetFactory_H +#define SWIFTEN_TreeWidgetFactory_H + +namespace Swift { + +class TreeWidgetItem; +class TreeWidget; + +class TreeWidgetFactory { + public: + virtual ~TreeWidgetFactory() {} + virtual TreeWidget* createTreeWidget() = 0; + virtual TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* item) = 0; + virtual TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) = 0; +}; + +} + +#endif + diff --git a/Swiften/Roster/TreeWidgetItem.h b/Swiften/Roster/TreeWidgetItem.h new file mode 100644 index 0000000..5a96a41 --- /dev/null +++ b/Swiften/Roster/TreeWidgetItem.h @@ -0,0 +1,30 @@ +#ifndef SWIFTEN_TreeWidgetItem_H +#define SWIFTEN_TreeWidgetItem_H + +#include "Swiften/Base/String.h" +#include "Swiften/Roster/UserRosterAction.h" + +#include <boost/signal.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + +class TreeWidgetItem { + public: + virtual ~TreeWidgetItem() {} + virtual void setText(const String& text) = 0; + virtual void setExpanded(bool b) = 0; + virtual void setTextColor(unsigned long color) = 0; + virtual void setBackgroundColor(unsigned long color) = 0; + boost::signal<void (boost::shared_ptr<UserRosterAction>)> onUserAction; + virtual void show() = 0; + virtual void hide() = 0; + void performUserAction(boost::shared_ptr<UserRosterAction> action) { + action->setTreeWidgetItem(this); + onUserAction(action); + } +}; + +} +#endif + diff --git a/Swiften/Roster/UnitTest/Makefile.inc b/Swiften/Roster/UnitTest/Makefile.inc new file mode 100644 index 0000000..5631641 --- /dev/null +++ b/Swiften/Roster/UnitTest/Makefile.inc @@ -0,0 +1,4 @@ +UNITTEST_SOURCES += \ + Swiften/Roster/UnitTest/RosterTest.cpp \ + Swiften/Roster/UnitTest/OfflineRosterFilterTest.cpp + diff --git a/Swiften/Roster/UnitTest/MockTreeWidget.h b/Swiften/Roster/UnitTest/MockTreeWidget.h new file mode 100644 index 0000000..e6f6def --- /dev/null +++ b/Swiften/Roster/UnitTest/MockTreeWidget.h @@ -0,0 +1,14 @@ +#ifndef SWIFTEN_MockTreeWidget_H +#define SWIFTEN_MockTreeWidget_H + +#include "Swiften/Roster/TreeWidget.h" + +namespace Swift { + +class MockTreeWidget : public TreeWidget { + public: + virtual ~MockTreeWidget() {} +}; + +} +#endif diff --git a/Swiften/Roster/UnitTest/MockTreeWidgetFactory.h b/Swiften/Roster/UnitTest/MockTreeWidgetFactory.h new file mode 100644 index 0000000..09e4742 --- /dev/null +++ b/Swiften/Roster/UnitTest/MockTreeWidgetFactory.h @@ -0,0 +1,31 @@ +#ifndef SWIFTEN_MockTreeWidgetFactory_H +#define SWIFTEN_MockTreeWidgetFactory_H + +#include "Swiften/Roster/TreeWidgetFactory.h" +#include "Swiften/Roster/UnitTest/MockTreeWidget.h" +#include "Swiften/Roster/UnitTest/MockTreeWidgetItem.h" + +namespace Swift { + +class MockTreeWidgetItem; +class MockTreeWidget; + +class MockTreeWidgetFactory : public TreeWidgetFactory { + public: + virtual ~MockTreeWidgetFactory() {} + virtual TreeWidget* createTreeWidget() { + return new MockTreeWidget(); + }; + virtual TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem*) { + return new MockTreeWidgetItem(); + }; + virtual TreeWidgetItem* createTreeWidgetItem(TreeWidget*) { + return new MockTreeWidgetItem(); + } +}; + +} + +#endif + + diff --git a/Swiften/Roster/UnitTest/MockTreeWidgetItem.h b/Swiften/Roster/UnitTest/MockTreeWidgetItem.h new file mode 100644 index 0000000..f352936 --- /dev/null +++ b/Swiften/Roster/UnitTest/MockTreeWidgetItem.h @@ -0,0 +1,26 @@ +#ifndef SWIFTEN_MockTreeWidgetItem_H +#define SWIFTEN_MockTreeWidgetItem_H + +#include "Swiften/Base/String.h" +#include "Swiften/Roster/TreeWidgetItem.h" + +#include <boost/signal.hpp> +#include <boost/shared_ptr.hpp> + +namespace Swift { + +class MockTreeWidgetItem : public TreeWidgetItem { + public: + virtual ~MockTreeWidgetItem() {}; + virtual void setText(const String&) {}; + virtual void setExpanded(bool) {}; + virtual void setTextColor(unsigned long) {}; + virtual void setBackgroundColor(unsigned long) {}; + virtual void show() {}; + virtual void hide() {}; +}; + +} +#endif + + diff --git a/Swiften/Roster/UnitTest/OfflineRosterFilterTest.cpp b/Swiften/Roster/UnitTest/OfflineRosterFilterTest.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Swiften/Roster/UnitTest/OfflineRosterFilterTest.cpp diff --git a/Swiften/Roster/UnitTest/RosterTest.cpp b/Swiften/Roster/UnitTest/RosterTest.cpp new file mode 100644 index 0000000..b43a41c --- /dev/null +++ b/Swiften/Roster/UnitTest/RosterTest.cpp @@ -0,0 +1,57 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <boost/shared_ptr.hpp> + +#include "Swiften/Roster/Roster.h" +#include "Swiften/Roster/UnitTest/MockTreeWidget.h" +#include "Swiften/Roster/UnitTest/MockTreeWidgetFactory.h" +#include "Swiften/Roster/UnitTest/MockTreeWidgetItem.h" + +using namespace Swift; + +class RosterTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(RosterTest); + CPPUNIT_TEST(testGetGroup); + CPPUNIT_TEST_SUITE_END(); + + private: + Roster *roster_; + TreeWidget *widget_; + TreeWidgetFactory *factory_; + JID jid1_; + JID jid2_; + JID jid3_; + + public: + + RosterTest() : jid1_(JID("a@b.c")), jid2_(JID("b@c.d")), jid3_(JID("c@d.e")) {} + + void setUp() { + factory_ = new MockTreeWidgetFactory(); + widget_ = factory_->createTreeWidget(); + roster_ = new Roster(widget_, factory_); + } + + void tearDown() { + delete roster_; + //delete widget_; + delete factory_; + } + + void testGetGroup() { + roster_->addContact(jid1_, "Bert", "group1"); + roster_->addContact(jid2_, "Ernie", "group2"); + roster_->addContact(jid3_, "Cookie", "group1"); + + CPPUNIT_ASSERT_EQUAL(roster_->getGroup("group1"), roster_->getGroup("group1")); + CPPUNIT_ASSERT_EQUAL(roster_->getGroup("group2"), roster_->getGroup("group2")); + CPPUNIT_ASSERT_EQUAL(roster_->getGroup("group3"), roster_->getGroup("group3")); + CPPUNIT_ASSERT(roster_->getGroup("group1") != roster_->getGroup("group2")); + CPPUNIT_ASSERT(roster_->getGroup("group2") != roster_->getGroup("group3")); + CPPUNIT_ASSERT(roster_->getGroup("group3") != roster_->getGroup("group1")); + } + +}; +CPPUNIT_TEST_SUITE_REGISTRATION(RosterTest); + diff --git a/Swiften/Roster/UserRosterAction.h b/Swiften/Roster/UserRosterAction.h new file mode 100644 index 0000000..80ace68 --- /dev/null +++ b/Swiften/Roster/UserRosterAction.h @@ -0,0 +1,32 @@ +#ifndef SWIFTEN_UserRosterAction_H +#define SWIFTEN_UserRosterAction_H + +namespace Swift { +class RosterItem; +class TreeWidgetItem; + +class UserRosterAction { + public: + virtual ~UserRosterAction() {}; + void setRosterItem(RosterItem *item) { + rosterItem_ = item; + }; + void setTreeWidgetItem(TreeWidgetItem *item) { + treeWidgetItem_ = item; + } + RosterItem* getRosterItem() { + return rosterItem_; + } + TreeWidgetItem* getTreeWidgetItem() { + return treeWidgetItem_; + } + + private: + RosterItem *rosterItem_; + TreeWidgetItem *treeWidgetItem_; +}; + +} +#endif + + diff --git a/Swiften/Roster/XMPPRoster.cpp b/Swiften/Roster/XMPPRoster.cpp new file mode 100644 index 0000000..9661171 --- /dev/null +++ b/Swiften/Roster/XMPPRoster.cpp @@ -0,0 +1,37 @@ +#include "Swiften/Roster/XMPPRoster.h" + +namespace Swift { + +void XMPPRoster::addContact(const JID& jid, const String& name, const std::vector<String>& groups) { + JID bareJID(jid.toBare()); + bool exists = containsJID(bareJID); + if (exists) { + entries_.erase(bareJID); + } + entries_[bareJID] = std::pair<String, std::vector<String> >(name, groups); + if (exists) { + onJIDUpdated(bareJID); + } else { + onJIDAdded(bareJID); + } +} + +void XMPPRoster::removeContact(const JID& jid) { + entries_.erase(JID(jid.toBare())); + onJIDRemoved(jid); +} + +bool XMPPRoster::containsJID(const JID& jid) { + return entries_.find(JID(jid.toBare())) != entries_.end(); +} + +const String& XMPPRoster::getNameForJID(const JID& jid) { + return entries_[JID(jid.toBare())].first; +} + +const std::vector<String>& XMPPRoster::getGroupsForJID(const JID& jid) { + return entries_[JID(jid.toBare())].second; +} + +} + diff --git a/Swiften/Roster/XMPPRoster.h b/Swiften/Roster/XMPPRoster.h new file mode 100644 index 0000000..f2afbb3 --- /dev/null +++ b/Swiften/Roster/XMPPRoster.h @@ -0,0 +1,34 @@ +#ifndef SWIFTEN_XMPPRoster_H +#define SWIFTEN_XMPPRoster_H + +#include "Swiften/Base/String.h" +#include "Swiften/JID/JID.h" + +#include <map> +#include <vector> +#include <boost/signal.hpp> + +namespace Swift { + +class XMPPRoster { + public: + XMPPRoster() {}; + ~XMPPRoster() {}; + + void addContact(const JID& jid, const String& name, const std::vector<String>& groups); + bool containsJID(const JID& jid); + void removeContact(const JID& jid); + const String& getNameForJID(const JID& jid); + const std::vector<String>& getGroupsForJID(const JID& jid); + + boost::signal<void (const JID&)> onJIDAdded; + boost::signal<void (const JID&)> onJIDRemoved; + boost::signal<void (const JID&)> onJIDUpdated; + + private: + std::map<JID, std::pair<String, std::vector<String> > > entries_; +}; +} + +#endif + |