summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp4
-rw-r--r--Swift/Controllers/Chat/ChatController.h2
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp4
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h3
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp7
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h6
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp23
-rw-r--r--Swift/Controllers/Chat/MUCController.h6
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp39
-rw-r--r--Swift/Controllers/MainController.cpp10
-rw-r--r--Swift/Controllers/MainController.h4
-rw-r--r--Swift/Controllers/RosterController.cpp48
-rw-r--r--Swift/Controllers/RosterController.h7
-rw-r--r--Swift/Controllers/UIEvents/RemoveItemRosterAction.h21
-rw-r--r--Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h24
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h4
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindowFactory.h4
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindow.h4
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h2
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindow.h11
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindowFactory.h8
-rw-r--r--Swift/Controllers/UnitTest/RosterControllerTest.cpp48
-rw-r--r--Swift/Controllers/XMPPRosterController.cpp2
-rw-r--r--Swift/QtUI/ChatList/QtChatListWindow.cpp1
-rw-r--r--Swift/QtUI/ContextMenus/QtContextMenu.h4
-rw-r--r--Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp14
-rw-r--r--Swift/QtUI/ContextMenus/QtRosterContextMenu.h5
-rw-r--r--Swift/QtUI/QtChatWindow.cpp10
-rw-r--r--Swift/QtUI/QtChatWindow.h7
-rw-r--r--Swift/QtUI/QtChatWindowFactory.cpp8
-rw-r--r--Swift/QtUI/QtChatWindowFactory.h11
-rw-r--r--Swift/QtUI/QtMainWindow.cpp13
-rw-r--r--Swift/QtUI/QtMainWindow.h4
-rw-r--r--Swift/QtUI/QtMainWindowFactory.cpp5
-rw-r--r--Swift/QtUI/QtMainWindowFactory.h3
-rw-r--r--Swift/QtUI/QtSwift.cpp9
-rw-r--r--Swift/QtUI/QtSwift.h2
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.cpp121
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.h19
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.cpp6
-rw-r--r--Swift/QtUI/Roster/QtTreeWidgetFactory.h49
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.cpp29
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.h5
-rw-r--r--Swift/QtUI/Roster/RosterModel.cpp184
-rw-r--r--Swift/QtUI/Roster/RosterModel.h58
-rw-r--r--Swift/QtUI/SConscript2
-rw-r--r--Swiften/Roster/AppearOffline.h2
-rw-r--r--Swiften/Roster/ContactRosterItem.cpp76
-rw-r--r--Swiften/Roster/ContactRosterItem.h37
-rw-r--r--Swiften/Roster/GroupRosterItem.cpp140
-rw-r--r--Swiften/Roster/GroupRosterItem.h69
-rw-r--r--Swiften/Roster/OpenChatRosterAction.h26
-rw-r--r--Swiften/Roster/Roster.cpp128
-rw-r--r--Swiften/Roster/Roster.h32
-rw-r--r--Swiften/Roster/RosterItem.cpp44
-rw-r--r--Swiften/Roster/RosterItem.h30
-rw-r--r--Swiften/Roster/RosterItemOperation.h5
-rw-r--r--Swiften/Roster/SetName.h2
-rw-r--r--Swiften/Roster/SetPresence.h12
-rw-r--r--Swiften/Roster/TreeWidget.h19
-rw-r--r--Swiften/Roster/TreeWidgetFactory.h26
-rw-r--r--Swiften/Roster/TreeWidgetItem.h40
-rw-r--r--Swiften/Roster/UnitTest/MockTreeWidget.h20
-rw-r--r--Swiften/Roster/UnitTest/MockTreeWidgetFactory.h74
-rw-r--r--Swiften/Roster/UnitTest/MockTreeWidgetItem.cpp19
-rw-r--r--Swiften/Roster/UnitTest/MockTreeWidgetItem.h38
-rw-r--r--Swiften/Roster/UnitTest/RosterTest.cpp25
-rw-r--r--Swiften/Roster/UserRosterAction.h38
-rw-r--r--Swiften/SConscript3
69 files changed, 846 insertions, 919 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 6056fc5..2e1b1c8 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -21,8 +21,8 @@ namespace Swift {
/**
* The controller does not gain ownership of the stanzaChannel, nor the factory.
*/
-ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency)
- : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency) {
+ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream)
+ : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream) {
isInMUC_ = isInMUC;
chatStateNotifier_ = new ChatStateNotifier();
chatStateMessageSender_ = new ChatStateMessageSender(chatStateNotifier_, stanzaChannel, contact);
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index 3821a6e..7d2072d 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -17,7 +17,7 @@ namespace Swift {
class NickResolver;
class ChatController : public ChatControllerBase {
public:
- ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency);
+ ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream);
virtual void setToJID(const JID& jid);
private:
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index f3e6bbe..5f27efb 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -22,8 +22,8 @@
namespace Swift {
-ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency) {
- chatWindow_ = chatWindowFactory_->createChatWindow(toJID);
+ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency) {
+ chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);
chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1));
setEnabled(stanzaChannel->isAvailable() && iqRouter->isAvailable());
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index 8317da8..f7cf087 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -28,6 +28,7 @@ namespace Swift {
class ChatWindow;
class ChatWindowFactory;
class AvatarManager;
+ class UIEventStream;
class ChatControllerBase {
public:
@@ -40,7 +41,7 @@ namespace Swift {
void setEnabled(bool enabled);
virtual void setToJID(const JID& jid) {toJID_ = jid;};
protected:
- ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency);
+ ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream);
virtual void postSendMessage(const String&) {};
virtual String senderDisplayNameFromMessage(const JID& from) = 0;
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index d0b4716..312af76 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -28,12 +28,11 @@ namespace Swift {
typedef std::pair<JID, ChatController*> JIDChatControllerPair;
typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
-ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency) : jid_(jid), useDelayForLatency_(useDelayForLatency) {
+ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency) : jid_(jid), useDelayForLatency_(useDelayForLatency) {
eventController_ = eventController;
stanzaChannel_ = stanzaChannel;
iqRouter_ = iqRouter;
chatWindowFactory_ = chatWindowFactory;
- treeWidgetFactory_ = treeWidgetFactory;
nickResolver_ = nickResolver;
presenceOracle_ = presenceOracle;
avatarManager_ = NULL;
@@ -185,7 +184,7 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact)
}
ChatController* ChatsManager::createNewChatController(const JID& contact) {
- ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, isMUC(contact.toBare()), useDelayForLatency_);
+ ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_);
chatControllers_[contact] = controller;
controller->setAvailableServerFeatures(serverDiscoInfo_);
return controller;
@@ -221,7 +220,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &muc, const boost::optional<St
//FIXME: What's correct behaviour here?
} else {
String nick = nickMaybe ? nickMaybe.get() : "Swift user";
- MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, treeWidgetFactory_, presenceOracle_, avatarManager_, uiEventStream_, false);
+ MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false);
mucControllers_[muc] = controller;
controller->setAvailableServerFeatures(serverDiscoInfo_);
controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index d45d81d..59d4ec3 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -24,7 +24,6 @@ namespace Swift {
class ChatController;
class MUCController;
class ChatWindowFactory;
- class TreeWidgetFactory;
class NickResolver;
class PresenceOracle;
class AvatarManager;
@@ -37,14 +36,14 @@ namespace Swift {
class ChatsManager : public MUCRegistry {
public:
- ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency);
+ ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency);
~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setEnabled(bool enabled);
void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<Message> message);
- void handleChatRequest(const String& contact);
private:
+ void handleChatRequest(const String& contact);
void handleJoinMUCRequest(const JID& muc, const boost::optional<String>& nick);
void rebindControllerJID(const JID& from, const JID& to);
void handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> lastPresence);
@@ -65,7 +64,6 @@ namespace Swift {
StanzaChannel* stanzaChannel_;
IQRouter* iqRouter_;;
ChatWindowFactory* chatWindowFactory_;
- TreeWidgetFactory* treeWidgetFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 737ad82..7e9a9ea 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -17,10 +17,8 @@
#include "Swiften/MUC/MUC.h"
#include "Swiften/Client/StanzaChannel.h"
#include "Swiften/Roster/Roster.h"
-#include "Swiften/Roster/OpenChatRosterAction.h"
#include "Swiften/Roster/SetAvatar.h"
#include "Swiften/Roster/SetPresence.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
namespace Swift {
@@ -35,19 +33,17 @@ MUCController::MUCController (
PresenceSender* presenceSender,
IQRouter* iqRouter,
ChatWindowFactory* chatWindowFactory,
- TreeWidgetFactory *treeWidgetFactory,
PresenceOracle* presenceOracle,
AvatarManager* avatarManager,
UIEventStream* uiEventStream,
bool useDelayForLatency) :
- ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager, useDelayForLatency),
+ ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager, useDelayForLatency, uiEventStream),
muc_(new MUC(stanzaChannel, presenceSender, muc)),
- nick_(nick),
- treeWidgetFactory_(treeWidgetFactory) {
+ nick_(nick) {
parting_ = false;
events_ = uiEventStream;
- roster_ = new Roster(chatWindow_->getTreeWidget(), treeWidgetFactory_);
- roster_->onUserAction.connect(boost::bind(&MUCController::handleUserAction, this, _1));
+ roster_ = new Roster();
+ chatWindow_->setRosterModel(roster_);
chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this));
muc_->joinAs(nick);
muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
@@ -61,19 +57,10 @@ MUCController::MUCController (
MUCController::~MUCController() {
delete muc_;
+ chatWindow_->setRosterModel(NULL);
delete roster_;
}
-void MUCController::handleUserAction(boost::shared_ptr<UserRosterAction> action) {
- boost::shared_ptr<OpenChatRosterAction> chatAction = boost::dynamic_pointer_cast<OpenChatRosterAction>(action);
- if (chatAction.get() != NULL) {
- ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(chatAction->getRosterItem());
- assert(contactItem);
- events_->send(boost::shared_ptr<RequestChatUIEvent>(new RequestChatUIEvent(contactItem->getJID())));
- return;
- }
-}
-
void MUCController::handleAvatarChanged(const JID& jid, const String&) {
if (parting_) {
return;
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 2252357..8e6e01b 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -15,7 +15,6 @@
#include "Swift/Controllers/Chat/ChatControllerBase.h"
#include "Swiften/Elements/Message.h"
#include "Swiften/Elements/DiscoInfo.h"
-#include "Swiften/Roster/UserRosterAction.h"
#include "Swiften/JID/JID.h"
#include "Swiften/MUC/MUC.h"
#include "Swiften/MUC/MUCOccupant.h"
@@ -26,13 +25,12 @@ namespace Swift {
class ChatWindow;
class ChatWindowFactory;
class Roster;
- class TreeWidgetFactory;
class AvatarManager;
class UIEventStream;
class MUCController : public ChatControllerBase {
public:
- MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, TreeWidgetFactory *treeWidgetFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency);
+ MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency);
~MUCController();
boost::signal<void ()> onUserLeft;
@@ -47,13 +45,11 @@ namespace Swift {
void handleOccupantJoined(const MUCOccupant& occupant);
void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const String& reason);
void handleOccupantPresenceChange(boost::shared_ptr<Presence> presence);
- void handleUserAction(boost::shared_ptr<UserRosterAction> action);
private:
MUC* muc_;
UIEventStream* events_;
String nick_;
- TreeWidgetFactory* treeWidgetFactory_;
Roster* roster_;
bool parting_;
boost::bsignals::scoped_connection avatarChangedConnection_;
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 5caedab..f671fb1 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -13,7 +13,6 @@
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swift/Controllers/UIInterfaces/ChatListWindowFactory.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swiften/Client/Client.h"
#include "Swift/Controllers/Chat/ChatController.h"
#include "Swift/Controllers/EventController.h"
@@ -26,6 +25,7 @@
#include "Swiften/Client/DummyStanzaChannel.h"
#include "Swiften/Queries/DummyIQChannel.h"
#include "Swiften/Presence/PresenceOracle.h"
+#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
#include "Swift/Controllers/UIEvents/UIEventStream.h"
@@ -54,7 +54,6 @@ public:
iqRouter_ = new IQRouter(iqChannel_);
eventController_ = new EventController();
chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
- treeWidgetFactory_ = NULL;
xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
nickResolver_ = new NickResolver(xmppRoster_);
presenceOracle_ = new PresenceOracle(stanzaChannel_);
@@ -63,7 +62,7 @@ public:
uiEventStream_ = new UIEventStream();
chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createWindow).With(uiEventStream_).Return(NULL);
- manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, true);
+ manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, true);
avatarManager_ = new MockAvatarManager();
manager_->setAvatarManager(avatarManager_);
};
@@ -74,7 +73,6 @@ public:
delete presenceSender_;
delete presenceOracle_;
delete nickResolver_;
- delete treeWidgetFactory_;
delete stanzaChannel_;
delete eventController_;
delete iqChannel_;
@@ -87,7 +85,7 @@ public:
JID messageJID("testling@test.com/resource1");
MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID).Return(window);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
boost::shared_ptr<Message> message(new Message());
message->setFrom(messageJID);
@@ -101,7 +99,7 @@ public:
JID messageJID1("testling@test.com/resource1");
MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1).Return(window1);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
boost::shared_ptr<Message> message1(new Message());
message1->setFrom(messageJID1);
@@ -113,7 +111,7 @@ public:
JID messageJID2("testling@test.com/resource2");
MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2).Return(window2);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2);
boost::shared_ptr<Message> message2(new Message());
message2->setFrom(messageJID2);
@@ -127,9 +125,9 @@ public:
String messageJIDString("testling@test.com");
ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString)).Return(window);
-
- manager_->handleChatRequest(messageJIDString);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString), uiEventStream_).Return(window);
+
+ uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString))));
}
@@ -138,8 +136,8 @@ public:
String fullJIDString("testling@test.com/resource1");
MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString)).Return(window);
- manager_->handleChatRequest(bareJIDString);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
+ uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString))));
boost::shared_ptr<Message> message(new Message());
message->setFrom(JID(fullJIDString));
@@ -152,14 +150,14 @@ public:
void testSecondWindow() {
String messageJIDString1("testling1@test.com");
ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1)).Return(window1);
- manager_->handleChatRequest(messageJIDString1);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
+ uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1))));
String messageJIDString2("testling2@test.com");
ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2)).Return(window2);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
- manager_->handleChatRequest(messageJIDString2);
+ uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2))));
}
/** Complete cycle.
@@ -174,8 +172,8 @@ public:
String fullJIDString2("testling@test.com/resource2");
MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString)).Return(window);
- manager_->handleChatRequest(bareJIDString);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
+ uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString))));
boost::shared_ptr<Message> message1(new Message());
message1->setFrom(JID(fullJIDString1));
@@ -212,7 +210,7 @@ public:
JID messageJID1("testling@test.com/resource1");
MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1).Return(window1);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
boost::shared_ptr<Message> message1(new Message());
message1->setFrom(messageJID1);
@@ -222,7 +220,7 @@ public:
JID messageJID2("testling@test.com/resource2");
MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2).Return(window2);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2);
boost::shared_ptr<Message> message2(new Message());
message2->setFrom(messageJID2);
@@ -268,7 +266,6 @@ private:
IQRouter* iqRouter_;
EventController* eventController_;
ChatWindowFactory* chatWindowFactory_;
- TreeWidgetFactory* treeWidgetFactory_;
NickResolver* nickResolver_;
PresenceOracle* presenceOracle_;
AvatarManager* avatarManager_;
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 3656de3..e6dfe47 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -42,7 +42,6 @@
#include "Swiften/Elements/Presence.h"
#include "Swiften/Elements/VCardUpdate.h"
#include "Swiften/Queries/Responders/SoftwareVersionResponder.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swiften/Settings/SettingsProvider.h"
#include "Swiften/Elements/DiscoInfo.h"
#include "Swiften/Queries/Responders/DiscoInfoResponder.h"
@@ -61,8 +60,8 @@ static const String CLIENT_VERSION = "0.3";
static const String CLIENT_NODE = "http://swift.im";
-MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory *treeWidgetFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency)
- : timerFactory_(&boostIOServiceThread_.getIOService()), idleDetector_(&idleQuerier_, &timerFactory_, 100), chatWindowFactory_(chatWindowFactory), mainWindowFactory_(mainWindowFactory), loginWindowFactory_(loginWindowFactory), treeWidgetFactory_(treeWidgetFactory), settings_(settings), loginWindow_(NULL), useDelayForLatency_(useDelayForLatency) {
+MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency)
+ : timerFactory_(&boostIOServiceThread_.getIOService()), idleDetector_(&idleQuerier_, &timerFactory_, 100), chatWindowFactory_(chatWindowFactory), mainWindowFactory_(mainWindowFactory), loginWindowFactory_(loginWindowFactory), settings_(settings), loginWindow_(NULL), useDelayForLatency_(useDelayForLatency) {
application_ = application;
presenceOracle_ = NULL;
avatarManager_ = NULL;
@@ -176,15 +175,14 @@ void MainController::handleConnected() {
avatarManager_ = new AvatarManager(client_, client_, avatarStorage_);
- rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, eventController_, uiEventStream_, client_);
+ rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, eventController_, uiEventStream_, client_);
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
- chatsManager_ = new ChatsManager(jid_, client_, client_, eventController_, chatWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_);
+ chatsManager_ = new ChatsManager(jid_, client_, client_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_);
nickResolver_->setMUCRegistry(chatsManager_);
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
chatsManager_->setAvatarManager(avatarManager_);
- rosterController_->onStartChatRequest.connect(boost::bind(&ChatsManager::handleChatRequest, chatsManager_, _1));
avatarManager_->setMUCRegistry(chatsManager_);
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 2ed922c..5d3f998 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -47,7 +47,6 @@ namespace Swift {
class EventLoop;
class SoftwareVersionResponder;
class LoginWindowFactory;
- class TreeWidgetFactory;
class MUCController;
class PresenceOracle;
class SystemTray;
@@ -62,7 +61,7 @@ namespace Swift {
class MainController {
public:
- MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory* treeWidgetFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory_, bool useDelayForLatency);
+ MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, EventWindowFactory* eventWindowFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory, ChatListWindowFactory* chatListWindowFactory_, bool useDelayForLatency);
~MainController();
@@ -94,7 +93,6 @@ namespace Swift {
ChatWindowFactory* chatWindowFactory_;
MainWindowFactory* mainWindowFactory_;
LoginWindowFactory* loginWindowFactory_;
- TreeWidgetFactory* treeWidgetFactory_;
EventWindowFactory* eventWindowFactory_;
SettingsProvider *settings_;
Application* application_;
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index 3bbc9f8..4738d76 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -25,11 +25,9 @@
#include "Swiften/Roster/SetAvatar.h"
#include "Swiften/Roster/SetName.h"
#include "Swiften/Roster/OfflineRosterFilter.h"
-#include "Swiften/Roster/OpenChatRosterAction.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swiften/Roster/XMPPRoster.h"
#include "Swift/Controllers/UIEvents/AddContactUIEvent.h"
-#include "Swift/Controllers/UIEvents/RemoveItemRosterAction.h"
+#include "Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h"
namespace Swift {
@@ -37,17 +35,17 @@ namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-RosterController::RosterController(const JID& jid, boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter)
- : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), treeWidgetFactory_(treeWidgetFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster(mainWindow_->getTreeWidget(), treeWidgetFactory_)), offlineFilter_(new OfflineRosterFilter()) {
+RosterController::RosterController(const JID& jid, boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter)
+ : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()) {
iqRouter_ = iqRouter;
presenceOracle_ = presenceOracle;
eventController_ = eventController;
roster_->addFilter(offlineFilter_);
+ mainWindow_->setRosterModel(roster_);
changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));
showOfflineConnection_ = mainWindow_->onShowOfflineToggled.connect(boost::bind(&RosterController::handleShowOfflineToggled, this, _1));
signOutConnection_ = mainWindow_->onSignOutRequest.connect(boost::bind(boost::ref(onSignOutRequest)));
- roster_->onUserAction.connect(boost::bind(&RosterController::handleUserAction, this, _1));
xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1));
xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3));
xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1));
@@ -101,31 +99,6 @@ void RosterController::handleChangeStatusRequest(StatusShow::Type show, const St
onChangeStatusRequest(show, statusText);
}
-void RosterController::handleUserAction(boost::shared_ptr<UserRosterAction> action) {
- boost::shared_ptr<OpenChatRosterAction> chatAction = boost::dynamic_pointer_cast<OpenChatRosterAction>(action);
- if (chatAction) {
- ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(chatAction->getRosterItem());
- assert(contactItem);
- onStartChatRequest(contactItem->getJID().toBare());
- return;
- }
-
- boost::shared_ptr<RemoveItemRosterAction> removeAction = boost::dynamic_pointer_cast<RemoveItemRosterAction>(action);
- if (removeAction) {
- ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(removeAction->getRosterItem());
- assert(contactItem);
-
- RosterItemPayload item(contactItem->getJID(), "", RosterItemPayload::Remove);
- boost::shared_ptr<RosterPayload> roster(new RosterPayload());
- roster->addItem(item);
- boost::shared_ptr<SetRosterRequest> request(new SetRosterRequest(roster, iqRouter_));
- request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
- request->send();
-
- return;
- }
-}
-
void RosterController::handleOnJIDAdded(const JID& jid) {
std::vector<String> groups = xmppRoster_->getGroupsForJID(jid);
String name = xmppRoster_->getNameForJID(jid);
@@ -182,7 +155,20 @@ void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
request->send();
presenceOracle_->requestSubscription(addContactEvent->getJID());
+ return;
}
+ boost::shared_ptr<RemoveRosterItemUIEvent> removeEvent = boost::dynamic_pointer_cast<RemoveRosterItemUIEvent>(event);
+ if (removeEvent) {
+ RosterItemPayload item(removeEvent->getJID(), "", RosterItemPayload::Remove);
+ boost::shared_ptr<RosterPayload> roster(new RosterPayload());
+ roster->addItem(item);
+ boost::shared_ptr<SetRosterRequest> request(new SetRosterRequest(roster, iqRouter_));
+ request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
+ request->send();
+
+ return;
+ }
+
}
void RosterController::handleRosterSetError(boost::optional<ErrorPayload> error, boost::shared_ptr<RosterPayload> rosterPayload) {
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index e9561bb..eca4e33 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -11,7 +11,6 @@
#include "Swiften/Base/String.h"
#include "Swiften/Elements/Presence.h"
#include "Swiften/Elements/RosterPayload.h"
-#include "Swiften/Roster/UserRosterAction.h"
#include "Swiften/Avatars/AvatarManager.h"
#include "Swift/Controllers/UIEvents/UIEvent.h"
@@ -24,7 +23,6 @@ namespace Swift {
class XMPPRoster;
class MainWindow;
class MainWindowFactory;
- class TreeWidgetFactory;
class OfflineRosterFilter;
class NickResolver;
class PresenceOracle;
@@ -35,13 +33,12 @@ namespace Swift {
class RosterController {
public:
- RosterController(const JID& jid, boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, TreeWidgetFactory* treeWidgetFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_);
+ RosterController(const JID& jid, boost::shared_ptr<XMPPRoster> xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_);
~RosterController();
void showRosterWindow();
MainWindow* getWindow() {return mainWindow_;};
void setAvatarManager(AvatarManager* avatarManager);
void setNickResolver(NickResolver* nickResolver);
- boost::signal<void (const JID&)> onStartChatRequest;
boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest;
boost::signal<void ()> onSignOutRequest;
void handleAvatarChanged(const JID& jid, const String& hash);
@@ -51,7 +48,6 @@ namespace Swift {
void handleOnJIDRemoved(const JID &jid);
void handleOnJIDUpdated(const JID &jid, const String& oldName, const std::vector<String> oldGroups);
void handleStartChatRequest(const JID& contact);
- void handleUserAction(boost::shared_ptr<UserRosterAction> action);
void handleChangeStatusRequest(StatusShow::Type show, const String &statusText);
void handleShowOfflineToggled(bool state);
void handleIncomingPresence(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> oldPresence);
@@ -63,7 +59,6 @@ namespace Swift {
JID myJID_;
boost::shared_ptr<XMPPRoster> xmppRoster_;
MainWindowFactory* mainWindowFactory_;
- TreeWidgetFactory* treeWidgetFactory_;
MainWindow* mainWindow_;
Roster* roster_;
OfflineRosterFilter* offlineFilter_;
diff --git a/Swift/Controllers/UIEvents/RemoveItemRosterAction.h b/Swift/Controllers/UIEvents/RemoveItemRosterAction.h
deleted file mode 100644
index 751e248..0000000
--- a/Swift/Controllers/UIEvents/RemoveItemRosterAction.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#pragma once
-
-#include "Swiften/Roster/UserRosterAction.h"
-
-namespace Swift {
-class RosterItem;
-class TreeWidgetItem;
-
-class RemoveItemRosterAction : public UserRosterAction {
- public:
- virtual ~RemoveItemRosterAction() {};
-
-};
-
-}
diff --git a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
new file mode 100644
index 0000000..7e5236a
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swiften/JID/JID.h"
+#include "Swift/Controllers/UIEvents/UIEvent.h"
+
+namespace Swift {
+
+class RemoveRosterItemUIEvent : public UIEvent {
+ public:
+ RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {};
+ virtual ~RemoveRosterItemUIEvent() {};
+ JID getJID() {return jid_;};
+ private:
+ JID jid_;
+
+};
+
+}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 0463508..33133f3 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -19,6 +19,7 @@
namespace Swift {
class AvatarManager;
class TreeWidget;
+ class Roster;
class ChatWindow {
public:
@@ -38,10 +39,11 @@ namespace Swift {
virtual void setSecurityLabelsEnabled(bool enabled) = 0;
virtual void setUnreadMessageCount(int count) = 0;
virtual void convertToMUC() = 0;
- virtual TreeWidget *getTreeWidget() = 0;
+// virtual TreeWidget *getTreeWidget() = 0;
virtual void setSecurityLabelsError() = 0;
virtual SecurityLabel getSelectedSecurityLabel() = 0;
virtual void setInputEnabled(bool enabled) = 0;
+ virtual void setRosterModel(Roster* model) = 0;
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
index 3ea2416..b7b4479 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
@@ -11,14 +11,14 @@
namespace Swift {
class ChatWindow;
-
+ class UIEventStream;
class ChatWindowFactory {
public:
virtual ~ChatWindowFactory() {};
/**
* Transfers ownership of result.
*/
- virtual ChatWindow* createChatWindow(const JID &contact) = 0;
+ virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream) = 0;
};
}
diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h
index ce8b877..6d6e980 100644
--- a/Swift/Controllers/UIInterfaces/MainWindow.h
+++ b/Swift/Controllers/UIInterfaces/MainWindow.h
@@ -15,16 +15,16 @@
#include <boost/shared_ptr.hpp>
namespace Swift {
- class TreeWidget;
+ class Roster;
class MainWindow {
public:
virtual ~MainWindow() {};
- virtual TreeWidget* getTreeWidget() = 0;
virtual void setMyName(const String& name) = 0;
virtual void setMyAvatarPath(const String& path) = 0;
virtual void setMyStatusText(const String& status) = 0;
virtual void setMyStatusType(StatusShow::Type type) = 0;
+ virtual void setRosterModel(Roster* roster) = 0;
boost::signal<void (const JID&)> onStartChatRequest;
boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest;
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index fecd665..1ce87ff 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -27,10 +27,10 @@ namespace Swift {
virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;};
virtual void setUnreadMessageCount(int /*count*/) {};
virtual void convertToMUC() {};
- virtual TreeWidget *getTreeWidget() {return NULL;};
virtual void setSecurityLabelsError() {};
virtual SecurityLabel getSelectedSecurityLabel() {return SecurityLabel();};
virtual void setInputEnabled(bool /*enabled*/) {};
+ virtual void setRosterModel(Roster* /*roster*/) {};
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
diff --git a/Swift/Controllers/UnitTest/MockMainWindow.h b/Swift/Controllers/UnitTest/MockMainWindow.h
index f6134da..4d0c67a 100644
--- a/Swift/Controllers/UnitTest/MockMainWindow.h
+++ b/Swift/Controllers/UnitTest/MockMainWindow.h
@@ -7,20 +7,19 @@
#pragma once
#include "Swift/Controllers/UIInterfaces/MainWindow.h"
-#include "Swiften/Roster/TreeWidget.h"
namespace Swift {
+ class Roster;
class MockMainWindow : public MainWindow {
public:
- MockMainWindow(TreeWidget* treeWidget) {treeWidget_ = treeWidget;};
+ MockMainWindow() {};
virtual ~MockMainWindow() {};
- virtual TreeWidget* getTreeWidget() {return treeWidget_;};
+ virtual void setRosterModel(Roster* roster) {this->roster = roster;};
virtual void setMyName(const String& /*name*/) {};;
virtual void setMyAvatarPath(const String& /*path*/) {};
virtual void setMyStatusText(const String& /*status*/) {};
virtual void setMyStatusType(StatusShow::Type /*type*/) {};
-
- private:
- TreeWidget* treeWidget_;
+ Roster* roster;
+
};
}
diff --git a/Swift/Controllers/UnitTest/MockMainWindowFactory.h b/Swift/Controllers/UnitTest/MockMainWindowFactory.h
index 2f0559b..8a35d1a 100644
--- a/Swift/Controllers/UnitTest/MockMainWindowFactory.h
+++ b/Swift/Controllers/UnitTest/MockMainWindowFactory.h
@@ -7,21 +7,19 @@
#pragma once
#include "Swift/Controllers/UIInterfaces/MainWindowFactory.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swift/Controllers/UnitTest/MockMainWindow.h"
namespace Swift {
class MockMainWindowFactory : public MainWindowFactory {
public:
- MockMainWindowFactory(TreeWidgetFactory* treeWidgetFactory) {factory_ = treeWidgetFactory;};
+ MockMainWindowFactory() {};
virtual ~MockMainWindowFactory() {};
/**
* Transfers ownership of result.
*/
- virtual MainWindow* createMainWindow(UIEventStream*) {return new MockMainWindow(factory_->createTreeWidget());};
- private:
- TreeWidgetFactory* factory_;
+ virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;};
+ MockMainWindow* last;
};
}
diff --git a/Swift/Controllers/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
index 1177bd7..4bb3a08 100644
--- a/Swift/Controllers/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
@@ -10,7 +10,6 @@
#include "Swift/Controllers/RosterController.h"
#include "Swift/Controllers/UnitTest/MockMainWindowFactory.h"
-#include "Swiften/Roster/UnitTest/MockTreeWidgetFactory.h"
// #include "Swiften/Elements/Payload.h"
// #include "Swiften/Elements/RosterItemPayload.h"
// #include "Swiften/Elements/RosterPayload.h"
@@ -18,6 +17,9 @@
#include "Swiften/Client/DummyStanzaChannel.h"
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Roster/XMPPRoster.h"
+#include "Swiften/Roster/Roster.h"
+#include "Swiften/Roster/GroupRosterItem.h"
+#include "Swiften/Roster/ContactRosterItem.h"
#include "Swift/Controllers/EventController.h"
#include "Swiften/Presence/PresenceOracle.h"
#include "Swift/Controllers/NickResolver.h"
@@ -25,6 +27,7 @@
using namespace Swift;
+#define CHILDREN mainWindow_->roster->getRoot()->getChildren()
class RosterControllerTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(RosterControllerTest);
@@ -40,8 +43,7 @@ class RosterControllerTest : public CppUnit::TestFixture
jid_ = JID("testjid@swift.im/swift");
xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
avatarManager_ = NULL;//new AvatarManager();
- treeWidgetFactory_ = new MockTreeWidgetFactory();
- mainWindowFactory_ = new MockMainWindowFactory(treeWidgetFactory_);
+ mainWindowFactory_ = new MockMainWindowFactory();
nickResolver_ = new NickResolver(xmppRoster_);
channel_ = new DummyIQChannel();
router_ = new IQRouter(channel_);
@@ -49,9 +51,8 @@ class RosterControllerTest : public CppUnit::TestFixture
presenceOracle_ = new PresenceOracle(stanzaChannel_);
eventController_ = new EventController();
uiEventStream_ = new UIEventStream();
- rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, treeWidgetFactory_, nickResolver_, presenceOracle_, eventController_, uiEventStream_, router_);
-
-
+ rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, eventController_, uiEventStream_, router_);
+ mainWindow_ = mainWindowFactory_->last;
};
void tearDown() {
@@ -65,16 +66,19 @@ class RosterControllerTest : public CppUnit::TestFixture
delete presenceOracle_;
delete stanzaChannel_;
delete uiEventStream_;
- delete treeWidgetFactory_;
};
+ GroupRosterItem* groupChild(size_t i) {
+ return dynamic_cast<GroupRosterItem*>(CHILDREN[i]);
+ }
+
void testAdd() {
std::vector<String> groups;
groups.push_back("testGroup1");
groups.push_back("testGroup2");
xmppRoster_->addContact(JID("test@testdomain.com/bob"), "name", groups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(2, (int)treeWidgetFactory_->getGroups().size());
+ CPPUNIT_ASSERT_EQUAL(2, (int)CHILDREN.size());
//CPPUNIT_ASSERT_EQUAL(String("Bob"), xmppRoster_->getNameForJID(JID("foo@bar.com")));
};
@@ -83,15 +87,15 @@ class RosterControllerTest : public CppUnit::TestFixture
JID jid("test@testdomain.com");
xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::None);
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroups().size());
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroupMembers("Contacts").size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)CHILDREN.size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)groupChild(0)->getChildren().size());
xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::To);
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroups().size());
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroupMembers("Contacts").size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)CHILDREN.size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)groupChild(0)->getChildren().size());
xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroups().size());
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroupMembers("Contacts").size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)CHILDREN.size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)groupChild(0)->getChildren().size());
};
@@ -100,20 +104,20 @@ class RosterControllerTest : public CppUnit::TestFixture
JID jid("test@testdomain.com");
xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroups().size());
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroupMembers("Contacts").size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)CHILDREN.size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)groupChild(0)->getChildren().size());
+ CPPUNIT_ASSERT_EQUAL(String("name"), groupChild(0)->getChildren()[0]->getDisplayName());
xmppRoster_->addContact(jid, "NewName", groups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroups().size());
- CPPUNIT_ASSERT_EQUAL(1, (int)treeWidgetFactory_->getGroupMembers("Contacts").size());
- CPPUNIT_ASSERT_EQUAL(String("NewName"), treeWidgetFactory_->getGroupMembers("Contacts")[0]->getText());
+ CPPUNIT_ASSERT_EQUAL(1, (int)CHILDREN.size());
+ CPPUNIT_ASSERT_EQUAL(1, (int)groupChild(0)->getChildren().size());
+ CPPUNIT_ASSERT_EQUAL(String("NewName"), groupChild(0)->getChildren()[0]->getDisplayName());
};
private:
JID jid_;
boost::shared_ptr<XMPPRoster> xmppRoster_;
AvatarManager* avatarManager_;
- MainWindowFactory* mainWindowFactory_;
- MockTreeWidgetFactory* treeWidgetFactory_;
+ MockMainWindowFactory* mainWindowFactory_;
NickResolver* nickResolver_;
RosterController* rosterController_;
DummyIQChannel* channel_;
@@ -122,6 +126,8 @@ class RosterControllerTest : public CppUnit::TestFixture
PresenceOracle* presenceOracle_;
EventController* eventController_;
UIEventStream* uiEventStream_;
+ MockMainWindow* mainWindow_;
};
+#undef children
CPPUNIT_TEST_SUITE_REGISTRATION(RosterControllerTest);
diff --git a/Swift/Controllers/XMPPRosterController.cpp b/Swift/Controllers/XMPPRosterController.cpp
index a7e634a..de5ff8c 100644
--- a/Swift/Controllers/XMPPRosterController.cpp
+++ b/Swift/Controllers/XMPPRosterController.cpp
@@ -16,8 +16,6 @@
#include "Swiften/Roster/Roster.h"
#include "Swiften/Roster/SetPresence.h"
#include "Swiften/Roster/OfflineRosterFilter.h"
-#include "Swiften/Roster/OpenChatRosterAction.h"
-#include "Swiften/Roster/TreeWidgetFactory.h"
#include "Swiften/Roster/XMPPRoster.h"
namespace Swift {
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp
index 7d307f9..9b70881 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.cpp
+++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp
@@ -29,6 +29,7 @@ QtChatListWindow::QtChatListWindow(UIEventStream *uiEventStream, QWidget* parent
#ifdef SWIFT_PLATFORM_MACOSX
setAlternatingRowColors(true);
#endif
+ expandAll();
setAnimated(true);
setIndentation(0);
setRootIsDecorated(true);
diff --git a/Swift/QtUI/ContextMenus/QtContextMenu.h b/Swift/QtUI/ContextMenus/QtContextMenu.h
index baa0180..9e73ef9 100644
--- a/Swift/QtUI/ContextMenus/QtContextMenu.h
+++ b/Swift/QtUI/ContextMenus/QtContextMenu.h
@@ -7,11 +7,11 @@
#pragma once
namespace Swift {
- class QtTreeWidgetItem;
+ class RosterItem;
class QtContextMenu {
public:
virtual ~QtContextMenu();
- virtual void show(QtTreeWidgetItem* item) = 0;
+ virtual void show(RosterItem* item) = 0;
};
}
diff --git a/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp b/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp
index 10e0b56..e6b5ae5 100644
--- a/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp
+++ b/Swift/QtUI/ContextMenus/QtRosterContextMenu.cpp
@@ -11,9 +11,10 @@
#include <boost/shared_ptr.hpp>
+#include "Swiften/Roster/ContactRosterItem.h"
#include "Swiften/Base/String.h"
-#include "Swift/Controllers/UIEvents/RemoveItemRosterAction.h"
-#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include "Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h"
#include "Swift/QtUI/QtSwiftUtil.h"
namespace Swift {
@@ -22,8 +23,9 @@ QtRosterContextMenu::QtRosterContextMenu(UIEventStream* eventStream) {
eventStream_ = eventStream;
}
-void QtRosterContextMenu::show(QtTreeWidgetItem* item) {
- if (!item->isContact()) {
+void QtRosterContextMenu::show(RosterItem* item) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) {
return;
}
item_ = item;
@@ -33,7 +35,9 @@ void QtRosterContextMenu::show(QtTreeWidgetItem* item) {
}
void QtRosterContextMenu::handleRemove() {
- item_->performUserAction(boost::shared_ptr<UserRosterAction>(new RemoveItemRosterAction()));
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item_);
+ assert(contact);
+ eventStream_->send(boost::shared_ptr<UIEvent>(new RemoveRosterItemUIEvent(contact->getJID())));
}
}
diff --git a/Swift/QtUI/ContextMenus/QtRosterContextMenu.h b/Swift/QtUI/ContextMenus/QtRosterContextMenu.h
index ffa8ba6..51556e4 100644
--- a/Swift/QtUI/ContextMenus/QtRosterContextMenu.h
+++ b/Swift/QtUI/ContextMenus/QtRosterContextMenu.h
@@ -12,17 +12,18 @@
#include "Swift/Controllers/UIEvents/UIEventStream.h"
namespace Swift {
+ class RosterItem;
class QtRosterContextMenu : public QObject, public QtContextMenu {
Q_OBJECT
public:
QtRosterContextMenu(UIEventStream* eventStream);
- void show(QtTreeWidgetItem* item);
+ void show(RosterItem* item);
private slots:
void handleRemove();
private:
- QtTreeWidgetItem* item_;
+ RosterItem* item_;
UIEventStream* eventStream_;
};
}
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 5bedc22..d1b3194 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -6,8 +6,8 @@
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
+#include "Swiften/Roster/Roster.h"
#include "Roster/QtTreeWidget.h"
-#include "Roster/QtTreeWidgetFactory.h"
#include "SwifTools/Linkify.h"
#include "QtChatView.h"
#include "MessageSnippet.h"
@@ -26,7 +26,7 @@
#include <QUrl>
namespace Swift {
-QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidgetFactory) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageWasSystem_(false) {
+QtChatWindow::QtChatWindow(const QString &contact, UIEventStream* eventStream) : QtTabbable(), contact_(contact), previousMessageWasSelf_(false), previousMessageWasSystem_(false), eventStream_(eventStream) {
unreadCount_ = 0;
updateTitleWithUnreadCount();
@@ -42,7 +42,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidg
messageLog_->setFocusPolicy(Qt::NoFocus);
logRosterSplitter->addWidget(messageLog_);
- treeWidget_ = dynamic_cast<QtTreeWidget*>(treeWidgetFactory->createTreeWidget());
+ treeWidget_ = new QtTreeWidget(eventStream_);
treeWidget_->hide();
logRosterSplitter->addWidget(treeWidget_);
@@ -79,8 +79,8 @@ QtChatWindow::~QtChatWindow() {
}
-TreeWidget* QtChatWindow::getTreeWidget() {
- return treeWidget_;
+void QtChatWindow::setRosterModel(Roster* roster) {
+ treeWidget_->setRosterModel(roster);
}
void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) {
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index f9b401c..0b22ea1 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -21,10 +21,11 @@ namespace Swift {
class QtTreeWidgetFactory;
class TreeWidget;
class QtTextEdit;
+ class UIEventStream;
class QtChatWindow : public QtTabbable, public ChatWindow {
Q_OBJECT
public:
- QtChatWindow(const QString &contact, QtTreeWidgetFactory* treeWidgetFactory);
+ QtChatWindow(const QString &contact, UIEventStream* eventStream);
~QtChatWindow();
void addMessage(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath);
void addAction(const String &message, const String &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath);
@@ -34,7 +35,7 @@ namespace Swift {
void activate();
void setUnreadMessageCount(int count);
void convertToMUC();
- TreeWidget *getTreeWidget();
+// TreeWidget *getTreeWidget();
void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels);
void setSecurityLabelsEnabled(bool enabled);
void setSecurityLabelsError();
@@ -43,6 +44,7 @@ namespace Swift {
void setInputEnabled(bool enabled);
QtTabbable::AlertType getWidgetAlertState();
void setContactChatState(ChatState::ChatStateType state);
+ void setRosterModel(Roster* roster);
protected slots:
void qAppFocusChanged(QWidget* old, QWidget* now);
@@ -70,6 +72,7 @@ namespace Swift {
bool previousMessageWasSystem_;
QString previousSenderName_;
bool inputClearing_;
+ UIEventStream* eventStream_;
};
}
diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp
index d96fa2b..5029324 100644
--- a/Swift/QtUI/QtChatWindowFactory.cpp
+++ b/Swift/QtUI/QtChatWindowFactory.cpp
@@ -11,11 +11,10 @@
#include "QtChatTabs.h"
#include "QtChatWindow.h"
#include "QtSwiftUtil.h"
-#include "Roster/QtTreeWidgetFactory.h"
namespace Swift {
-QtChatWindowFactory::QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory, QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs) : treeWidgetFactory_(treeWidgetFactory) {
+QtChatWindowFactory::QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs) {
settings_ = settings;
tabs_ = tabs;
if (splitter) {
@@ -29,10 +28,9 @@ QtChatWindowFactory::QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory,
}
}
-ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact) {
- QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), treeWidgetFactory_);
+ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact,UIEventStream* eventStream) {
+ QtChatWindow *chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), eventStream);
tabs_->addTab(chatWindow);
- //chatWindow->show();
return chatWindow;
}
diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h
index dc43146..4ffac88 100644
--- a/Swift/QtUI/QtChatWindowFactory.h
+++ b/Swift/QtUI/QtChatWindowFactory.h
@@ -4,8 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFT_QtChatWindowFactory_H
-#define SWIFT_QtChatWindowFactory_H
+#pragma once
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swiften/JID/JID.h"
@@ -14,20 +13,18 @@
#include <QObject>
#include <QSplitter>
namespace Swift {
- class QtTreeWidgetFactory;
class QtChatTabs;
+ class UIEventStream;
class QtChatWindowFactory : public QObject, public ChatWindowFactory {
Q_OBJECT
public:
- QtChatWindowFactory(QtTreeWidgetFactory *treeWidgetFactory, QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs);
- ChatWindow* createChatWindow(const JID &contact);
+ QtChatWindowFactory(QSplitter* splitter, QtSettingsProvider* settings, QtChatTabs* tabs);
+ ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
private slots:
void handleWindowGeometryChanged();
private:
- QtTreeWidgetFactory* treeWidgetFactory_;
QtSettingsProvider* settings_;
QtChatTabs* tabs_;
};
}
-#endif
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index fe4b179..0381d9e 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -23,14 +23,13 @@
#include "QtJoinMUCDialog.h"
#include "QtSwiftUtil.h"
#include "QtTabWidget.h"
-#include "Roster/QtTreeWidgetFactory.h"
#include "Roster/QtTreeWidget.h"
#include "Swift/Controllers/UIEvents/AddContactUIEvent.h"
#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
namespace Swift {
-QtMainWindow::QtMainWindow(UIEventStream* uiEventStream, QtTreeWidgetFactory *treeWidgetFactory) : QWidget() {
+QtMainWindow::QtMainWindow(UIEventStream* uiEventStream) : QWidget() {
uiEventStream_ = uiEventStream;
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
@@ -53,7 +52,7 @@ QtMainWindow::QtMainWindow(UIEventStream* uiEventStream, QtTreeWidgetFactory *tr
contactTabLayout->setSpacing(0);
contactTabLayout->setContentsMargins(0, 0, 0, 0);
- treeWidget_ = dynamic_cast<QtTreeWidget*>(treeWidgetFactory->createTreeWidget());
+ treeWidget_ = new QtTreeWidget(uiEventStream_);
contextMenu_ = new QtRosterContextMenu(uiEventStream_);
treeWidget_->setContextMenu(contextMenu_);
treeWidget_->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
@@ -104,6 +103,10 @@ QtChatListWindow* QtMainWindow::getChatListWindow() {
return chatListWindow_;
}
+void QtMainWindow::setRosterModel(Roster* roster) {
+ treeWidget_->setRosterModel(roster);
+}
+
void QtMainWindow::handleEventCountUpdated(int count) {
QColor eventTabColor = (count == 0) ? QColor(-1, -1, -1) : QColor(255, 0, 0); // invalid resets to default
int eventIndex = 1;
@@ -131,10 +134,6 @@ void QtMainWindow::handleAddContactDialogComplete(const JID& contact, const QStr
uiEventStream_->send(event);
}
-TreeWidget* QtMainWindow::getTreeWidget() {
- return treeWidget_;
-}
-
void QtMainWindow::handleJoinMUCAction() {
QtJoinMUCDialog* joinMUC = new QtJoinMUCDialog("jabber@conference.jabber.org", "SwiftUser", this);
connect(joinMUC, SIGNAL(onJoinCommand(const JID&, const QString&)), SLOT(handleJoinMUCDialogComplete(const JID&, const QString&)));
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index 45dbda6..3c20d66 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -35,9 +35,8 @@ namespace Swift {
class QtMainWindow : public QWidget, public MainWindow {
Q_OBJECT
public:
- QtMainWindow(UIEventStream* eventStream, QtTreeWidgetFactory *treeWidgetFactory);
+ QtMainWindow(UIEventStream* eventStream);
~QtMainWindow();
- TreeWidget* getTreeWidget();
std::vector<QMenu*> getMenus() {return menus_;}
void setMyName(const String& name);
void setMyAvatarPath(const String& path);
@@ -45,6 +44,7 @@ namespace Swift {
void setMyStatusType(const StatusShow::Type type);
QtEventWindow* getEventWindow();
QtChatListWindow* getChatListWindow();
+ void setRosterModel(Roster* roster);
private slots:
void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage);
void handleShowOfflineToggled(bool);
diff --git a/Swift/QtUI/QtMainWindowFactory.cpp b/Swift/QtUI/QtMainWindowFactory.cpp
index 12e3532..4405239 100644
--- a/Swift/QtUI/QtMainWindowFactory.cpp
+++ b/Swift/QtUI/QtMainWindowFactory.cpp
@@ -6,16 +6,15 @@
#include "QtMainWindowFactory.h"
#include "QtMainWindow.h"
-#include "Roster/QtTreeWidgetFactory.h"
namespace Swift {
-QtMainWindowFactory::QtMainWindowFactory(QtTreeWidgetFactory *treeWidgetFactory) : treeWidgetFactory_(treeWidgetFactory) {
+QtMainWindowFactory::QtMainWindowFactory() {
lastWindow_ = NULL;
}
MainWindow* QtMainWindowFactory::createMainWindow(UIEventStream* eventStream) {
- lastWindow_ = new QtMainWindow(eventStream, treeWidgetFactory_);
+ lastWindow_ = new QtMainWindow(eventStream);
return lastWindow_;
}
diff --git a/Swift/QtUI/QtMainWindowFactory.h b/Swift/QtUI/QtMainWindowFactory.h
index c16d229..17eb53c 100644
--- a/Swift/QtUI/QtMainWindowFactory.h
+++ b/Swift/QtUI/QtMainWindowFactory.h
@@ -13,11 +13,10 @@ namespace Swift {
class QtTreeWidgetFactory;
class QtMainWindowFactory : public MainWindowFactory{
public:
- QtMainWindowFactory(QtTreeWidgetFactory *treeWidgetFactory);
+ QtMainWindowFactory();
MainWindow* createMainWindow(UIEventStream* eventStream);
MainWindow* getLastCreatedWindow();
private:
- QtTreeWidgetFactory *treeWidgetFactory_;
MainWindow* lastWindow_;
};
}
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index fc5f4cb..534697b 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -11,7 +11,6 @@
#include "QtLoginWindow.h"
#include "QtChatTabs.h"
#include "QtMainWindowFactory.h"
-#include "Roster/QtTreeWidgetFactory.h"
#include "QtSystemTray.h"
#include "QtSoundPlayer.h"
#include "QtXMLConsoleWidgetFactory.h"
@@ -65,11 +64,10 @@ QtSwift::QtSwift(po::variables_map options) : autoUpdater_(NULL) {
tabs_ = new QtChatTabs();
settings_ = new QtSettingsProvider();
application_ = new PlatformApplication(SWIFT_APPLICATION_NAME);
- treeWidgetFactory_ = new QtTreeWidgetFactory();
systemTray_ = new QtSystemTray();
loginWindowFactory_ = new QtLoginWindowFactory(splitter_, systemTray_, settings_);
- chatWindowFactory_ = new QtChatWindowFactory(treeWidgetFactory_, splitter_, settings_, tabs_);
- rosterWindowFactory_ = new QtMainWindowFactory(treeWidgetFactory_);
+ chatWindowFactory_ = new QtChatWindowFactory(splitter_, settings_, tabs_);
+ rosterWindowFactory_ = new QtMainWindowFactory();
eventWindowFactory_ = new QtEventWindowFactory(rosterWindowFactory_);
xmlConsoleWidgetFactory_ = new QtXMLConsoleWidgetFactory(tabs_);
chatListWindowFactory_ = new QtChatListWindowFactory(rosterWindowFactory_);
@@ -77,7 +75,7 @@ QtSwift::QtSwift(po::variables_map options) : autoUpdater_(NULL) {
if (splitter_) {
splitter_->show();
}
- mainController_ = new MainController(chatWindowFactory_, rosterWindowFactory_, loginWindowFactory_, treeWidgetFactory_, eventWindowFactory_, settings_, application_, systemTray_, soundPlayer_, xmlConsoleWidgetFactory_, chatListWindowFactory_, options.count("latency-debug") > 0);
+ mainController_ = new MainController(chatWindowFactory_, rosterWindowFactory_, loginWindowFactory_, eventWindowFactory_, settings_, application_, systemTray_, soundPlayer_, xmlConsoleWidgetFactory_, chatListWindowFactory_, options.count("latency-debug") > 0);
PlatformAutoUpdaterFactory autoUpdaterFactory;
if (autoUpdaterFactory.isSupported()) {
@@ -91,7 +89,6 @@ QtSwift::~QtSwift() {
delete chatWindowFactory_;
delete rosterWindowFactory_;
delete loginWindowFactory_;
- delete treeWidgetFactory_;
delete mainController_;
delete settings_;
delete application_;
diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h
index 72343d8..d0141b2 100644
--- a/Swift/QtUI/QtSwift.h
+++ b/Swift/QtUI/QtSwift.h
@@ -28,7 +28,6 @@ namespace Swift {
class QtChatWindowFactory;
class QtMainWindowFactory;
class QtLoginWindowFactory;
- class QtTreeWidgetFactory;
class QtXMLConsoleWidgetFactory;
class QtSystemTray;
class QtSoundPlayer;
@@ -43,7 +42,6 @@ namespace Swift {
~QtSwift();
private:
MainController *mainController_;
- QtTreeWidgetFactory *treeWidgetFactory_;
QtChatWindowFactory *chatWindowFactory_;
QtChatListWindowFactory *chatListWindowFactory_;
QtMainWindowFactory *rosterWindowFactory_;
diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index 9dabc81..97b055b 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -7,7 +7,9 @@
#include "Roster/QtTreeWidget.h"
#include "Swiften/Base/Platform.h"
-#include "Swiften/Roster/OpenChatRosterAction.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+#include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
#include <qdebug.h>
#include <QMenu>
@@ -15,26 +17,26 @@
namespace Swift {
-QtTreeWidget::QtTreeWidget(QWidget* parent) : QTreeView(parent) {
- treeRoot_ = new QtTreeWidgetItem(NULL);
- model_ = new RosterModel();
- model_->setRoot(treeRoot_);
+QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, QWidget* parent) : QTreeView(parent) {
+ eventStream_ = eventStream;
+ model_ = new RosterModel(this);
setModel(model_);
- delegate_ = new RosterDelegate();
+ delegate_ = new RosterDelegate(this);
setItemDelegate(delegate_);
setHeaderHidden(true);
contextMenu_ = NULL;
#ifdef SWIFT_PLATFORM_MACOSX
setAlternatingRowColors(true);
#endif
+ expandAll();
setAnimated(true);
setIndentation(0);
setRootIsDecorated(true);
connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
- connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleModelItemExpanded(const QModelIndex&, bool)));
- connect(model_, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleDataChanged(const QModelIndex&, const QModelIndex&)));
- connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&)));
- connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&)));
+// connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleModelItemExpanded(const QModelIndex&, bool)));
+// connect(model_, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleDataChanged(const QModelIndex&, const QModelIndex&)));
+// connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&)));
+// connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&)));
}
QtTreeWidget::~QtTreeWidget() {
@@ -42,6 +44,11 @@ QtTreeWidget::~QtTreeWidget() {
delete delegate_;
}
+void QtTreeWidget::setRosterModel(Roster* roster) {
+ model_->setRoster(roster);
+ expandAll();
+}
+
void QtTreeWidget::setContextMenu(QtContextMenu* contextMenu) {
contextMenu_ = contextMenu;
}
@@ -51,9 +58,10 @@ QtTreeWidgetItem* QtTreeWidget::getRoot() {
}
void QtTreeWidget::handleItemActivated(const QModelIndex& index) {
- QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
- if (qtItem) {
- qtItem->performUserAction(boost::shared_ptr<UserRosterAction>(new OpenChatRosterAction()));
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact) {
+ eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(contact->getJID())));
}
}
@@ -62,53 +70,52 @@ void QtTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
return;
}
QModelIndex index = indexAt(event->pos());
- QtTreeWidgetItem* qtItem = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL;
- if (qtItem) {
- contextMenu_->show(qtItem);
- }
-}
-
-void QtTreeWidget::handleExpanded(const QModelIndex& index) {
- QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
- if (qtItem) {
- qtItem->setExpanded(true);
- }
-}
-
-void QtTreeWidget::handleCollapsed(const QModelIndex& index) {
- QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
- if (qtItem) {
- qtItem->setExpanded(false);
- }
-}
-
-void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) {
- if (this->isExpanded(index) == shouldExpand) {
- return;
- }
- //setExpanded(index, shouldExpand);
- if (shouldExpand) {
- expand(index);
- emit expanded(index);
- } else {
- collapse(index);
- emit collapsed(index);
+ RosterItem* item = index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL;
+ if (item) {
+ contextMenu_->show(item);
}
}
-void QtTreeWidget::handleDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) {
- Q_UNUSED(bottomRight);
- //in our model, this is only thrown with topLeft == bottomRight
- if (!topLeft.isValid()) {
- return;
- }
- QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(topLeft.internalPointer());
- if (qtItem) {
- setExpanded(topLeft, qtItem->isExpanded());
- //qDebug() << "Item changed, passing expanded state to view: " << qtItem->isExpanded() << " giving an expanded state of " << isExpanded(topLeft);
- }
-
-}
+//void QtTreeWidget::handleExpanded(const QModelIndex& index) {
+// QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+// if (qtItem) {
+// qtItem->setExpanded(true);
+// }
+//}
+
+//void QtTreeWidget::handleCollapsed(const QModelIndex& index) {
+// QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(index.internalPointer());
+// if (qtItem) {
+// qtItem->setExpanded(false);
+// }
+//}
+
+//void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) {
+// if (this->isExpanded(index) == shouldExpand) {
+// return;
+// }
+// //setExpanded(index, shouldExpand);
+// if (shouldExpand) {
+// expand(index);
+// emit expanded(index);
+// } else {
+// collapse(index);
+// emit collapsed(index);
+// }
+//}
+
+// void QtTreeWidget::handleDataChanged(const QModelIndex& topLeft, const QModelIndex& /*bottomRight*/) {
+// //in our model, this is only thrown with topLeft == bottomRight
+// if (!topLeft.isValid()) {
+// return;
+// }
+// QtTreeWidgetItem* qtItem = static_cast<QtTreeWidgetItem*>(topLeft.internalPointer());
+// if (qtItem) {
+// setExpanded(topLeft, qtItem->isExpanded());
+// //qDebug() << "Item changed, passing expanded state to view: " << qtItem->isExpanded() << " giving an expanded state of " << isExpanded(topLeft);
+// }
+
+// }
void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
}
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index d6e6038..c03f2e2 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -9,31 +9,29 @@
#include <QTreeView>
#include <QModelIndex>
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
#include "Swift/QtUI/Roster/QtTreeWidget.h"
#include "Swift/QtUI/Roster/RosterModel.h"
#include "Swift/QtUI/Roster/RosterDelegate.h"
#include "Swift/QtUI/ContextMenus/QtContextMenu.h"
namespace Swift {
+class UIEventStream;
-class QtTreeWidget : public QTreeView, public TreeWidget {
+class QtTreeWidget : public QTreeView{
Q_OBJECT
public:
- QtTreeWidget(QWidget* parent = 0);
+ QtTreeWidget(UIEventStream* eventStream, QWidget* parent = 0);
~QtTreeWidget();
void show();
QtTreeWidgetItem* getRoot();
void setContextMenu(QtContextMenu* contextMenu);
+ void setRosterModel(Roster* roster);
private slots:
void handleItemActivated(const QModelIndex&);
- void handleModelItemExpanded(const QModelIndex&, bool expanded);
- void handleExpanded(const QModelIndex&);
- void handleCollapsed(const QModelIndex&);
- void handleDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
+// void handleModelItemExpanded(const QModelIndex&, bool expanded);
+// void handleExpanded(const QModelIndex&);
+// void handleCollapsed(const QModelIndex&);
+// void handleDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
protected:
void contextMenuEvent(QContextMenuEvent* event);
@@ -43,6 +41,7 @@ class QtTreeWidget : public QTreeView, public TreeWidget {
RosterDelegate* delegate_;
QtTreeWidgetItem* treeRoot_;
QtContextMenu* contextMenu_;
+ UIEventStream* eventStream_;
};
}
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp b/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
deleted file mode 100644
index d4a8e4b..0000000
--- a/Swift/QtUI/Roster/QtTreeWidgetFactory.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
diff --git a/Swift/QtUI/Roster/QtTreeWidgetFactory.h b/Swift/QtUI/Roster/QtTreeWidgetFactory.h
deleted file mode 100644
index b72a508..0000000
--- a/Swift/QtUI/Roster/QtTreeWidgetFactory.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#ifndef SWIFT_QtTreeWidgetFactory_H
-#define SWIFT_QtTreeWidgetFactory_H
-
-#include "Swiften/Roster/TreeWidgetFactory.h"
-#include "Swiften/Roster/TreeWidget.h"
-#include "Swiften/Roster/TreeWidgetItem.h"
-#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
-#include "Swift/QtUI/Roster/QtTreeWidget.h"
-
-namespace Swift {
-
-class QtTreeWidgetFactory : public TreeWidgetFactory {
- public:
- QtTreeWidgetFactory() {
- }
-
- TreeWidget* createTreeWidget() {
- return new QtTreeWidget();
- }
-
- TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* item) {
- QtTreeWidgetItem* qtItem = dynamic_cast<QtTreeWidgetItem*>(item);
- assert(qtItem);
- QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
- qtItem->addChild(newItem);
- return newItem;
- }
-
- TreeWidgetItem* createTreeWidgetItem(TreeWidget* item) {
- QtTreeWidget* treeItem = dynamic_cast<QtTreeWidget*>(item);
- assert(treeItem);
- QtTreeWidgetItem* qtItem = treeItem->getRoot();
- QtTreeWidgetItem* newItem = new QtTreeWidgetItem(qtItem);
- //qtItem->setItemWidget(newItem, 0, newItem->getCollapsedRosterWidget());
- qtItem->addChild(newItem);
- newItem->setExpanded(true);
- return newItem;
- }
-};
-
-}
-#endif
-
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index 0c12d6e..b7ba71b 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -15,11 +15,16 @@
#include <QPolygon>
#include <qdebug.h>
-#include "QtTreeWidgetItem.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+#include "Swiften/Roster/GroupRosterItem.h"
+
+#include "QtTreeWidget.h"
+#include "RosterModel.h"
namespace Swift {
-RosterDelegate::RosterDelegate() {
+RosterDelegate::RosterDelegate(QtTreeWidget* tree) {
+ tree_ = tree;
groupDelegate_ = new GroupItemDelegate();
}
@@ -28,16 +33,14 @@ RosterDelegate::~RosterDelegate() {
}
QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
- QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
- if (!item || !item->isContact()) {
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (dynamic_cast<GroupRosterItem*>(item)) {
return groupDelegate_->sizeHint(option, index);
}
return contactSizeHint(option, index);
}
-QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
- Q_UNUSED(option);
- Q_UNUSED(index);
+QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const {
int heightByAvatar = avatarSize_ + common_.verticalMargin * 2;
QFontMetrics nameMetrics(common_.nameFont);
QFontMetrics statusMetrics(common_.detailFont);
@@ -49,8 +52,8 @@ QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& option, const
}
void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
- if (item && !item->isContact()) {
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (dynamic_cast<GroupRosterItem*>(item)) {
paintGroup(painter, option, index);
} else {
paintContact(painter, option, index);
@@ -58,15 +61,11 @@ void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
}
void RosterDelegate::paintGroup(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- QtTreeWidgetItem* item = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL;
- if (item) {
- groupDelegate_->paint(painter, option, index.data(Qt::DisplayRole).toString(), item->rowCount(), item->isExpanded());
+ if (index.isValid()) {
+ groupDelegate_->paint(painter, option, index.data(Qt::DisplayRole).toString(), index.data(ChildCountRole).toInt(), tree_->isExpanded(index));
}
}
-
-
-
void RosterDelegate::paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
//qDebug() << "painting" << index.data(Qt::DisplayRole).toString();
painter->save();
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
index 696ea03..e6a16f2 100644
--- a/Swift/QtUI/Roster/RosterDelegate.h
+++ b/Swift/QtUI/Roster/RosterDelegate.h
@@ -14,10 +14,10 @@
#include "DelegateCommons.h"
namespace Swift {
- class QtTreeWidgetItem;
+ class QtTreeWidget;
class RosterDelegate : public QStyledItemDelegate {
public:
- RosterDelegate();
+ RosterDelegate(QtTreeWidget* tree);
~RosterDelegate();
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
@@ -27,6 +27,7 @@ namespace Swift {
void paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
DelegateCommons common_;
GroupItemDelegate* groupDelegate_;
+ QtTreeWidget* tree_;
static const int avatarSize_;
static const int presenceIconHeight_;
static const int presenceIconWidth_;
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index c4cf57e..408cc3e 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -6,74 +6,184 @@
#include "RosterModel.h"
+#include <boost/bind.hpp>
+
+#include <QColor>
+#include <QIcon>
+#include <qdebug.h>
+
+#include "Swiften/Elements/StatusShow.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+#include "Swiften/Roster/GroupRosterItem.h"
+
+#include "QtSwiftUtil.h"
+#include "Swift/QtUI/Roster/QtTreeWidget.h"
+
namespace Swift {
-RosterModel::RosterModel() {
+RosterModel::RosterModel(QtTreeWidget* view) : view_(view) {
+ roster_ = NULL;
}
RosterModel::~RosterModel() {
- delete tree_;
}
-void RosterModel::setRoot(QtTreeWidgetItem* root) {
- tree_ = root;
- connect(tree_, SIGNAL(changed(QtTreeWidgetItem*)), this, SLOT(handleItemChanged(QtTreeWidgetItem*)));
+void RosterModel::setRoster(Roster* roster) {
+ roster_ = roster;
+ if (!roster_) return;
+ roster->onChildrenChanged.connect(boost::bind(&RosterModel::handleChildrenChanged, this, _1));
+ roster->onDataChanged.connect(boost::bind(&RosterModel::handleDataChanged, this, _1));
+ roster->onGroupAdded.connect(boost::bind(&RosterModel::handleGroupAdded, this, _1));
+ emit layoutChanged();
}
-
-void RosterModel::handleItemChanged(QtTreeWidgetItem* item) {
- if (!item->isShown()) {
- return;
- }
+void RosterModel::handleGroupAdded(GroupRosterItem* group) {
+ view_->setExpanded(index(group), true);
+}
+
+void RosterModel::handleChildrenChanged(GroupRosterItem* /*group*/) {
+ emit layoutChanged();
+}
+
+void RosterModel::handleDataChanged(RosterItem* item) {
Q_ASSERT(item);
QModelIndex modelIndex = index(item);
- Q_ASSERT(modelIndex.isValid());
- emit itemExpanded(modelIndex, item->isExpanded());
- emit dataChanged(modelIndex, modelIndex);
- emit dataChanged(parent(modelIndex), parent(modelIndex));
- emit layoutChanged();
+ if (modelIndex.isValid()) {
+ //emit itemExpanded(modelIndex, item->isExpanded());
+ emit dataChanged(modelIndex, modelIndex);
+ }
}
-int RosterModel::columnCount(const QModelIndex& parent) const {
- Q_UNUSED(parent);
+int RosterModel::columnCount(const QModelIndex& /*parent*/) const {
return 1;
}
+RosterItem* RosterModel::getItem(const QModelIndex& index) const {
+ return index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL;
+}
+
QVariant RosterModel::data(const QModelIndex& index, int role) const {
- QtTreeWidgetItem* item = index.isValid() ? static_cast<QtTreeWidgetItem*>(index.internalPointer()) : NULL;
- return item ? item->data(role) : QVariant();
+ RosterItem* item = getItem(index);
+ if (!item) return QVariant();
+
+ switch (role) {
+ case Qt::DisplayRole: return P2QSTRING(item->getDisplayName());
+ case Qt::TextColorRole: return getTextColor(item);
+ case Qt::BackgroundColorRole: return getBackgroundColor(item);
+ case Qt::ToolTipRole: return getToolTip(item);
+ case StatusTextRole: return getStatusText(item);
+ case AvatarRole: return getAvatar(item);
+ case PresenceIconRole: return getPresenceIcon(item);
+ case ChildCountRole: return getChildCount(item);
+ default: return QVariant();
+ }
}
-QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
- QtTreeWidgetItem* parentItem = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_;
- Q_ASSERT(parentItem);
-
- return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
+int RosterModel::getChildCount(RosterItem* item) const {
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ return group ? group->getDisplayedChildren().size() : 0;
}
-QModelIndex RosterModel::index(QtTreeWidgetItem* item) const {
- return createIndex(item->row(), 0, item);
+QColor RosterModel::intToColor(int color) const {
+ return QColor(
+ ((color & 0xFF0000)>>16),
+ ((color & 0xFF00)>>8),
+ (color & 0xFF));
}
-QModelIndex RosterModel::parent(const QModelIndex& index) const {
- if (!index.isValid()) {
- return QModelIndex();
+QColor RosterModel::getTextColor(RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ int color = 0;
+ if (contact) {
+ switch (contact->getStatusShow()) {
+ case StatusShow::Online: color = 0x000000; break;
+ case StatusShow::Away: color = 0x336699; break;
+ case StatusShow::XA: color = 0x336699; break;
+ case StatusShow::FFC: color = 0x000000; break;
+ case StatusShow::DND: color = 0x990000; break;
+ case StatusShow::None: color = 0x7F7F7F;break;
+ }
}
+ return intToColor(color);
+}
+
+QColor RosterModel::getBackgroundColor(RosterItem* item) const {
+ return dynamic_cast<ContactRosterItem*>(item) ? intToColor(0xFFFFFF) : intToColor(0x969696);
+}
+
+QString RosterModel::getToolTip(RosterItem* item) const {
+ return dynamic_cast<ContactRosterItem*>(item) ? P2QSTRING(item->getDisplayName()) + "\n" + getStatusText(item) : P2QSTRING(item->getDisplayName());
+}
+
+QIcon RosterModel::getAvatar(RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) return QIcon();
+ String path = contact->getAvatarPath();
- QtTreeWidgetItem* item = static_cast<QtTreeWidgetItem*>(index.internalPointer());
- Q_ASSERT(item);
+ return path.isEmpty() ? QIcon() : QIcon(P2QSTRING(path));
+}
- QtTreeWidgetItem* parentItem = item->getParentItem();
- /* parentItem_ == NULL can happen during destruction.*/
- return parentItem == tree_ || parentItem == NULL ? QModelIndex() : createIndex(parentItem->row(), 0, parentItem);
+QString RosterModel::getStatusText(RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) return "";
+ return P2QSTRING(contact->getStatusText());
+}
+QIcon RosterModel::getPresenceIcon(RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) return QIcon();
+ QString iconString;
+ switch (contact->getStatusShow()) {
+ case StatusShow::Online: iconString = "online";break;
+ case StatusShow::Away: iconString = "away";break;
+ case StatusShow::XA: iconString = "away";break;
+ case StatusShow::FFC: iconString = "online";break;
+ case StatusShow::DND: iconString = "dnd";break;
+ case StatusShow::None: iconString = "offline";break;
+ }
+ return QIcon(":/icons/" + iconString + ".png");
+}
+
+
+QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
+ GroupRosterItem* parentItem;
+ if (!parent.isValid()) {
+ //top level
+ parentItem = roster_->getRoot();
+ } else {
+ parentItem = dynamic_cast<GroupRosterItem*>(getItem(parent));
+ if (!parentItem) return QModelIndex();
+ }
+ return (size_t)row < parentItem->getDisplayedChildren().size() ? createIndex(row, column, parentItem->getDisplayedChildren()[row]) : QModelIndex();
+}
+
+QModelIndex RosterModel::index(RosterItem* item) const {
+ GroupRosterItem* parent = item->getParent();
+ for (size_t i = 0; i < parent->getDisplayedChildren().size(); i++) {
+ if (parent->getDisplayedChildren()[i] == item) {
+ return createIndex(i, 0, item);
+ }
+ }
+ return QModelIndex();
+}
+
+QModelIndex RosterModel::parent(const QModelIndex& child) const {
+ if (!child.isValid()) {
+ return QModelIndex();
+ }
+
+ GroupRosterItem* parent = getItem(child)->getParent();
+ return (parent != roster_->getRoot()) ? index(parent) : QModelIndex();
}
int RosterModel::rowCount(const QModelIndex& parent) const {
- QtTreeWidgetItem* item = parent.isValid() ? static_cast<QtTreeWidgetItem*>(parent.internalPointer()) : tree_;
+ if (!roster_) return 0;
+ RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : roster_->getRoot();
Q_ASSERT(item);
-
- return item->rowCount();
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ int count = group ? group->getDisplayedChildren().size() : 0;
+ qDebug() << "rowCount = " << count << " where parent.isValid() == " << parent.isValid() << ", group == " << (group ? P2QSTRING(group->getDisplayName()) : "*contact*");
+ return count;
}
}
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
index 998f879..17fdd3e 100644
--- a/Swift/QtUI/Roster/RosterModel.h
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -6,30 +6,48 @@
#pragma once
-#include "Swift/QtUI/Roster/QtTreeWidgetItem.h"
+#include "Swiften/Roster/Roster.h"
#include <QAbstractItemModel>
#include <QList>
namespace Swift {
-class RosterModel : public QAbstractItemModel {
-Q_OBJECT
-public:
- RosterModel();
- ~RosterModel();
- void setRoot(QtTreeWidgetItem* tree);
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
- QModelIndex index(QtTreeWidgetItem* item) const;
- QModelIndex parent(const QModelIndex& index) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
-signals:
- void itemExpanded(const QModelIndex& item, bool expanded);
-private slots:
- void handleItemChanged(QtTreeWidgetItem* item);
-private:
- QtTreeWidgetItem* tree_;
-};
+ enum RosterRoles {
+ StatusTextRole = Qt::UserRole,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2,
+ StatusShowTypeRole = Qt::UserRole + 3,
+ ChildCountRole = Qt::UserRole + 4,
+ };
+ class QtTreeWidget;
+
+ class RosterModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ RosterModel(QtTreeWidget* view);
+ ~RosterModel();
+ void setRoster(Roster* swiftRoster);
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex index(RosterItem* item) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ private:
+ void handleDataChanged(RosterItem* item);
+ void handleChildrenChanged(GroupRosterItem* item);
+ void handleGroupAdded(GroupRosterItem* group);
+ RosterItem* getItem(const QModelIndex& index) const;
+ QColor intToColor(int color) const;
+ QColor getTextColor(RosterItem* item) const;
+ QColor getBackgroundColor(RosterItem* item) const;
+ QString getToolTip(RosterItem* item) const;
+ QIcon getAvatar(RosterItem* item) const;
+ QString getStatusText(RosterItem* item) const;
+ QIcon getPresenceIcon(RosterItem* item) const;
+ int getChildCount(RosterItem* item) const;
+ Roster* roster_;
+ QtTreeWidget* view_;
+ };
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index b4f8f64..4311623 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -80,7 +80,7 @@ sources = [
"SystemMessageSnippet.cpp",
"Roster/RosterModel.cpp",
"Roster/QtTreeWidget.cpp",
- "Roster/QtTreeWidgetItem.cpp",
+# "Roster/QtTreeWidgetItem.cpp",
"Roster/RosterDelegate.cpp",
"Roster/GroupItemDelegate.cpp",
"Roster/DelegateCommons.cpp",
diff --git a/Swiften/Roster/AppearOffline.h b/Swiften/Roster/AppearOffline.h
index 792cec1..8e14190 100644
--- a/Swiften/Roster/AppearOffline.h
+++ b/Swiften/Roster/AppearOffline.h
@@ -21,7 +21,7 @@ class AppearOffline : public RosterItemOperation {
virtual void operator() (RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (contact) {
- contact->setStatusShow(StatusShow::None);
+ contact->clearPresence();
}
}
diff --git a/Swiften/Roster/ContactRosterItem.cpp b/Swiften/Roster/ContactRosterItem.cpp
index 39e96bd..2d5082c 100644
--- a/Swiften/Roster/ContactRosterItem.cpp
+++ b/Swiften/Roster/ContactRosterItem.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -10,49 +10,77 @@
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(const JID& jid, const String& name, GroupRosterItem* parent) : RosterItem(name, parent), jid_(jid) {
}
ContactRosterItem::~ContactRosterItem() {
- delete widget_;
}
-void ContactRosterItem::setName(const String& name) {
- widget_->setText(name);
+StatusShow::Type ContactRosterItem::getStatusShow() const {
+ return shownPresence_ ? shownPresence_->getShow() : StatusShow::None;
}
-StatusShow::Type ContactRosterItem::getStatusShow() {
- return statusShow_;
+StatusShow::Type ContactRosterItem::getSimplifiedStatusShow() const {
+ switch (shownPresence_ ? shownPresence_->getShow() : StatusShow::None) {
+ case StatusShow::Online: return StatusShow::Online; break;
+ case StatusShow::Away: return StatusShow::Away; break;
+ case StatusShow::XA: return StatusShow::Away; break;
+ case StatusShow::FFC: return StatusShow::Online; break;
+ case StatusShow::DND: return StatusShow::DND; break;
+ case StatusShow::None: return StatusShow::None; break;
+ }
+ assert(false);
}
-void ContactRosterItem::setStatusShow(StatusShow::Type show) {
- statusShow_ = show;
- widget_->setStatusShow(show);
-}
-
-void ContactRosterItem::setStatusText(const String& status) {
- widget_->setStatusText(status);
+String ContactRosterItem::getStatusText() const {
+ return shownPresence_ ? shownPresence_->getStatus() : "";
}
void ContactRosterItem::setAvatarPath(const String& path) {
- widget_->setAvatarPath(path);
+ avatarPath_ = path;
+ onDataChanged();
+}
+const String& ContactRosterItem::getAvatarPath() const {
+ return avatarPath_;
}
const JID& ContactRosterItem::getJID() const {
return jid_;
}
-void ContactRosterItem::show() {
- widget_->show();
+typedef std::pair<String, boost::shared_ptr<Presence> > StringPresencePair;
+
+void ContactRosterItem::calculateShownPresence() {
+ shownPresence_ = offlinePresence_;
+ foreach (StringPresencePair presencePair, presences_) {
+ boost::shared_ptr<Presence> presence = presencePair.second;
+ if (!shownPresence_ || presence->getPriority() > shownPresence_->getPriority() || presence->getShow() < shownPresence_->getShow()) {
+ shownPresence_ = presence;
+ }
+ }
+}
+
+void ContactRosterItem::clearPresence() {
+ presences_.clear();
+ calculateShownPresence();
}
-void ContactRosterItem::hide() {
- widget_->hide();
+void ContactRosterItem::applyPresence(const String& resource, boost::shared_ptr<Presence> presence) {
+ if (offlinePresence_) {
+ offlinePresence_ = boost::shared_ptr<Presence>();
+ }
+ if (presence->getType() == Presence::Unavailable) {
+ if (presences_.find(resource) != presences_.end()) {
+ presences_.erase(resource);
+ }
+ if (presences_.size() > 0) {
+ offlinePresence_ = presence;
+ }
+ } else {
+ presences_[resource] = presence;
+ }
+ calculateShownPresence();
+ onDataChanged();
}
}
diff --git a/Swiften/Roster/ContactRosterItem.h b/Swiften/Roster/ContactRosterItem.h
index 92b3056..bd49e05 100644
--- a/Swiften/Roster/ContactRosterItem.h
+++ b/Swiften/Roster/ContactRosterItem.h
@@ -1,48 +1,47 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_ContactRosterItem_H
-#define SWIFTEN_ContactRosterItem_H
+#pragma once
#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 "Swiften/Elements/Presence.h"
+#include <map>
#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();
+ ContactRosterItem(const JID& jid, const String& name, GroupRosterItem* parent);
+ virtual ~ContactRosterItem();
- StatusShow::Type getStatusShow();
- void setStatusShow(StatusShow::Type show);
- void setStatusText(const String& status);
+ StatusShow::Type getStatusShow() const;
+ StatusShow::Type getSimplifiedStatusShow() const;
+ String getStatusText() const;
void setAvatarPath(const String& path);
+ const String& getAvatarPath() const;
const JID& getJID() const;
- void setName(const String& name);
- void show();
- void hide();
-
+ void applyPresence(const String& resource, boost::shared_ptr<Presence> presence);
+ void clearPresence();
+ void calculateShownPresence();
private:
JID jid_;
- String name_;
- TreeWidgetItem *widget_;
- StatusShow::Type statusShow_;
+ String avatarPath_;
+ bool hidden_;
+ std::map<String, boost::shared_ptr<Presence> > presences_;
+ boost::shared_ptr<Presence> offlinePresence_;
+ boost::shared_ptr<Presence> shownPresence_;
};
}
-#endif
diff --git a/Swiften/Roster/GroupRosterItem.cpp b/Swiften/Roster/GroupRosterItem.cpp
new file mode 100644
index 0000000..05530ec
--- /dev/null
+++ b/Swiften/Roster/GroupRosterItem.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swiften/Roster/GroupRosterItem.h"
+
+#include <boost/bind.hpp>
+#include <iostream>
+
+namespace Swift {
+
+GroupRosterItem::GroupRosterItem(const String& name, GroupRosterItem* parent) : RosterItem(name, parent) {
+
+}
+
+GroupRosterItem::~GroupRosterItem() {
+
+}
+
+const std::vector<RosterItem*>& GroupRosterItem::getChildren() const {
+ return children_;
+}
+
+const std::vector<RosterItem*>& GroupRosterItem::getDisplayedChildren() const {
+// std::cout << "Fetching displayed children for " << getDisplayName() << " and found " << displayedChildren_.size() << std::endl;
+ return displayedChildren_;
+}
+
+void GroupRosterItem::addChild(RosterItem* item) {
+ children_.push_back(item);
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ group->onChildrenChanged.connect(boost::bind(&GroupRosterItem::handleChildrenChanged, this, group));
+ }
+ onChildrenChanged();
+ onDataChanged();
+}
+
+/**
+ * Returns the removed item - but only if it's the only one, otherwise
+ * the return result is undefined.
+ */
+ContactRosterItem* GroupRosterItem::removeChild(const JID& jid) {
+ std::vector<RosterItem*>::iterator it = children_.begin();
+ ContactRosterItem* removed = NULL;
+ while (it != children_.end()) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it);
+ if (contact && contact->getJID() == jid) {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), contact), displayedChildren_.end());
+ removed = contact;
+ delete contact;
+ it = children_.erase(it);
+ continue;
+ }
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
+ if (group) {
+ ContactRosterItem* groupRemoved = group->removeChild(jid);
+ if (groupRemoved) {
+ removed = groupRemoved;
+ }
+ }
+ it++;
+ }
+ onChildrenChanged();
+ onDataChanged();
+ return removed;
+}
+
+void GroupRosterItem::sortDisplayed() {
+ std::stable_sort(displayedChildren_.begin(), displayedChildren_.end(), itemLessThan);
+}
+
+bool GroupRosterItem::itemLessThan(const RosterItem* left, const RosterItem* right) {
+ const ContactRosterItem* leftContact = dynamic_cast<const ContactRosterItem*>(left);
+ const ContactRosterItem* rightContact = dynamic_cast<const ContactRosterItem*>(right);
+ if (leftContact) {
+ if (rightContact) {
+ return false;
+ }
+ StatusShow::Type leftType = leftContact->getSimplifiedStatusShow();
+ StatusShow::Type rightType = rightContact->getSimplifiedStatusShow();
+ if (leftType == rightType) {
+ return left->getSortableDisplayName() < right->getSortableDisplayName();
+ } else {
+ return leftType < rightType;
+ }
+ } else {
+ if (rightContact) {
+ return true;
+ }
+ return left->getSortableDisplayName() < right->getSortableDisplayName();
+ }
+}
+
+void GroupRosterItem::setDisplayed(RosterItem* item, bool displayed) {
+ bool found = false;
+ for (size_t i = 0; i < displayedChildren_.size(); i++) {
+ if (displayedChildren_[i] == item) {
+ found = true;
+ }
+ }
+ if (found == displayed) {
+ return;
+ }
+ if (displayed) {
+ displayedChildren_.push_back(item);
+ sortDisplayed();
+ } else {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), item), displayedChildren_.end());
+ }
+ onDataChanged();
+ onChildrenChanged();
+}
+
+void GroupRosterItem::handleChildrenChanged(GroupRosterItem* group) {
+ size_t oldSize = getDisplayedChildren().size();
+ if (group->getDisplayedChildren().size() > 0) {
+ bool found = false;
+ for (size_t i = 0; i < displayedChildren_.size(); i++) {
+ if (displayedChildren_[i] == group) {
+ found = true;
+ }
+ }
+ if (!found) {
+ displayedChildren_.push_back(group);
+ sortDisplayed();
+ }
+ } else {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end());
+ }
+ if (oldSize != getDisplayedChildren().size()) {
+ onDataChanged();
+ onChildrenChanged();
+ }
+}
+
+
+}
diff --git a/Swiften/Roster/GroupRosterItem.h b/Swiften/Roster/GroupRosterItem.h
index 83128a5..5e16b2b 100644
--- a/Swiften/Roster/GroupRosterItem.h
+++ b/Swiften/Roster/GroupRosterItem.h
@@ -1,74 +1,37 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_GroupRosterItem_H
-#define SWIFTEN_GroupRosterItem_H
+#pragma once
#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>
+#include <vector>
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);
- }
-
- ~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++;
- }
- }
-
+ GroupRosterItem(const String& name, GroupRosterItem* parent);
+ virtual ~GroupRosterItem();
+ const std::vector<RosterItem*>& getChildren() const;
+ const std::vector<RosterItem*>& getDisplayedChildren() const;
+ void addChild(RosterItem* item);
+ ContactRosterItem* removeChild(const JID& jid);
+ void setDisplayed(RosterItem* item, bool displayed);
+ boost::signal<void ()> onChildrenChanged;
+ static bool itemLessThan(const RosterItem* left, const RosterItem* right);
private:
+ void handleChildrenChanged(GroupRosterItem* group);
+ void sortDisplayed();
String name_;
- TreeWidgetItem* widget_;
- std::list<RosterItem*> children_;
+ std::vector<RosterItem*> children_;
+ std::vector<RosterItem*> displayedChildren_;
};
}
-#endif
diff --git a/Swiften/Roster/OpenChatRosterAction.h b/Swiften/Roster/OpenChatRosterAction.h
deleted file mode 100644
index b0784f5..0000000
--- a/Swiften/Roster/OpenChatRosterAction.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#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
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);
}
}
}
diff --git a/Swiften/Roster/Roster.h b/Swiften/Roster/Roster.h
index 5fc3cfb..3af89d7 100644
--- a/Swiften/Roster/Roster.h
+++ b/Swiften/Roster/Roster.h
@@ -10,7 +10,6 @@
#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>
@@ -20,39 +19,38 @@
namespace Swift {
-class TreeWidgetFactory;
-class TreeWidget;
class RosterItem;
class GroupRosterItem;
+class ContactRosterItem;
class Roster {
public:
- Roster(TreeWidget *treeWidget, TreeWidgetFactory *widgetFactory);
+ Roster();
~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 removeContactFromGroup(const JID& jid, const String& group);
void applyOnItems(const RosterItemOperation& operation);
void applyOnAllItems(const RosterItemOperation& operation);
void applyOnItem(const RosterItemOperation& operation, const JID& jid);
- boost::signal<void (boost::shared_ptr<UserRosterAction>)> onUserAction;
- void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();}
+ void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();};
void removeFilter(RosterFilter *filter);
- std::vector<RosterFilter*> getFilters() {return filters_;}
-
+ GroupRosterItem* getRoot();
+ std::vector<RosterFilter*> getFilters() {return filters_;};
+ boost::signal<void (GroupRosterItem*)> onChildrenChanged;
+ boost::signal<void (GroupRosterItem*)> onGroupAdded;
+ boost::signal<void (RosterItem*)> onDataChanged;
private:
- void filterItem(RosterItem* item);
+ GroupRosterItem* getGroup(const String& groupName);
+ void handleDataChanged(RosterItem* item);
+ void handleChildrenChanged(GroupRosterItem* item);
+ void filterGroup(GroupRosterItem* item);
+ void filterContact(ContactRosterItem* contact, GroupRosterItem* group);
void filterAll();
- void handleUserAction(boost::shared_ptr<UserRosterAction> action);
- TreeWidget *treeWidget_;
- TreeWidgetFactory *widgetFactory_;
- std::vector<RosterItem*> children_;
- std::vector<RosterItem*> items_;
+ GroupRosterItem* root_;
std::vector<RosterFilter*> filters_;
- std::map<JID, std::vector<RosterItem*> > itemMap_;
+ std::map<JID, std::vector<ContactRosterItem*> > itemMap_;
};
}
diff --git a/Swiften/Roster/RosterItem.cpp b/Swiften/Roster/RosterItem.cpp
new file mode 100644
index 0000000..7229199
--- /dev/null
+++ b/Swiften/Roster/RosterItem.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swiften/Roster/RosterItem.h"
+
+#include "Swiften/Roster/GroupRosterItem.h"
+
+namespace Swift {
+
+RosterItem::RosterItem(const String& name, GroupRosterItem* parent) : name_(name), parent_(parent) {
+ /* The following would be good, but because of C++'s inheritance not working in constructors, it's not going to work. */
+ //if (parent) {
+ // parent_->addChild(this);
+ //}
+}
+
+RosterItem::~RosterItem() {
+
+}
+
+GroupRosterItem* RosterItem::getParent() const {
+ return parent_;
+}
+
+void RosterItem::setDisplayName(const String& name) {
+ name_ = name;
+ sortableDisplayName_ = name_.getLowerCase();
+ onDataChanged();
+}
+
+String RosterItem::getDisplayName() const {
+ return name_;
+}
+
+String RosterItem::getSortableDisplayName() const {
+ return sortableDisplayName_;
+}
+
+
+}
+
diff --git a/Swiften/Roster/RosterItem.h b/Swiften/Roster/RosterItem.h
index 2c2a7e4..3a1a1b1 100644
--- a/Swiften/Roster/RosterItem.h
+++ b/Swiften/Roster/RosterItem.h
@@ -1,30 +1,32 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_RosterItem_H
-#define SWIFTEN_RosterItem_H
-
-#include "Swiften/Roster/UserRosterAction.h"
+#pragma once
#include <boost/signal.hpp>
#include <boost/shared_ptr.hpp>
-namespace Swift {
+#include "Swiften/Base/String.h"
+namespace Swift {
+class GroupRosterItem;
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);
- }
+ RosterItem(const String& name, GroupRosterItem* parent);
+ virtual ~RosterItem();
+ boost::signal<void ()> onDataChanged;
+ GroupRosterItem* getParent() const;
+ void setDisplayName(const String& name);
+ String getDisplayName() const;
+ String getSortableDisplayName() const;
+ private:
+ String name_;
+ String sortableDisplayName_;
+ GroupRosterItem* parent_;
};
}
-#endif
diff --git a/Swiften/Roster/RosterItemOperation.h b/Swiften/Roster/RosterItemOperation.h
index a901fb4..e27e68b 100644
--- a/Swiften/Roster/RosterItemOperation.h
+++ b/Swiften/Roster/RosterItemOperation.h
@@ -17,6 +17,11 @@ class RosterItemOperation {
virtual ~RosterItemOperation() {};
bool requiresLookup() const {return requiresLookup_;};
const JID& lookupJID() const {return lookupJID_;};
+ /**
+ * This is called when iterating over possible subjects, so must check it's
+ * applying to the right items - even if requiresLookup() is true an item
+ * with the same bare JID but different full JID may be passed.
+ */
virtual void operator() (RosterItem*) const = 0;
private:
bool requiresLookup_;
diff --git a/Swiften/Roster/SetName.h b/Swiften/Roster/SetName.h
index 33dd521..d3f7749 100644
--- a/Swiften/Roster/SetName.h
+++ b/Swiften/Roster/SetName.h
@@ -22,7 +22,7 @@ class SetName : public RosterItemOperation {
virtual void operator() (RosterItem* item) const {
ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
if (contact && contact->getJID().equals(jid_, compareType_)) {
- contact->setName(name_);
+ contact->setDisplayName(name_);
}
}
diff --git a/Swiften/Roster/SetPresence.h b/Swiften/Roster/SetPresence.h
index 9cc3ba9..134a63d 100644
--- a/Swiften/Roster/SetPresence.h
+++ b/Swiften/Roster/SetPresence.h
@@ -4,8 +4,7 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_SetPresence_H
-#define SWIFTEN_SetPresence_H
+#pragma once
#include "Swiften/Elements/Presence.h"
#include "Swiften/JID/JID.h"
@@ -24,13 +23,7 @@ class SetPresence : public RosterItemOperation {
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);
- contact->setStatusText(presence_->getStatus());
- } else {
- contact->setStatusShow(presence_->getShow());
- contact->setStatusText(presence_->getStatus());
- }
+ contact->applyPresence(presence_->getFrom().getResource(), presence_);
}
}
@@ -40,5 +33,4 @@ class SetPresence : public RosterItemOperation {
};
}
-#endif
diff --git a/Swiften/Roster/TreeWidget.h b/Swiften/Roster/TreeWidget.h
deleted file mode 100644
index 78b67b7..0000000
--- a/Swiften/Roster/TreeWidget.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#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
deleted file mode 100644
index fbc4417..0000000
--- a/Swiften/Roster/TreeWidgetFactory.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#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
deleted file mode 100644
index 1718776..0000000
--- a/Swiften/Roster/TreeWidgetItem.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#ifndef SWIFTEN_TreeWidgetItem_H
-#define SWIFTEN_TreeWidgetItem_H
-
-#include "Swiften/Base/String.h"
-#include "Swiften/Roster/UserRosterAction.h"
-#include "Swiften/Elements/StatusShow.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 setStatusText(const String& text) = 0;
- virtual void setAvatarPath(const String& path) = 0;
- virtual void setExpanded(bool b) = 0;
- //virtual void setTextColor(unsigned long color) = 0;
- virtual void setStatusShow(StatusShow::Type show) = 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/MockTreeWidget.h b/Swiften/Roster/UnitTest/MockTreeWidget.h
deleted file mode 100644
index 97dd796..0000000
--- a/Swiften/Roster/UnitTest/MockTreeWidget.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#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
deleted file mode 100644
index d94c859..0000000
--- a/Swiften/Roster/UnitTest/MockTreeWidgetFactory.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#ifndef SWIFTEN_MockTreeWidgetFactory_H
-#define SWIFTEN_MockTreeWidgetFactory_H
-
-#include "Swiften/Roster/TreeWidgetFactory.h"
-
-#include <vector>
-#include "Swiften/Base/foreach.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() {
- root_ = new MockTreeWidget();
- return root_;
- };
- virtual TreeWidgetItem* createTreeWidgetItem(TreeWidgetItem* group) {
- MockTreeWidgetItem* entry = new MockTreeWidgetItem(this);
- groupMembers_[group].push_back(entry);
- return entry;
- };
- virtual TreeWidgetItem* createTreeWidgetItem(TreeWidget*) {
- MockTreeWidgetItem* group = new MockTreeWidgetItem(this);
- groups_.push_back(group);
- return group;
- };
- virtual std::vector<String> getGroups() {
- std::vector<String> groupNames;
- foreach (MockTreeWidgetItem* group, groups_) {
- groupNames.push_back(group->getText());
- }
- return groupNames;
- };
-
- typedef std::map<TreeWidgetItem*, std::vector<MockTreeWidgetItem*> > itemMap;
-
- virtual std::vector<MockTreeWidgetItem*> getGroupMembers(const String& group) {
- for (itemMap::iterator it = groupMembers_.begin(); it != groupMembers_.end(); it++) {
- if (((MockTreeWidgetItem*)(it->first))->getText() == group) {
- return it->second;
- }
- }
- return std::vector<MockTreeWidgetItem*>();
- };
-
- virtual void removeItem(MockTreeWidgetItem* item) {
- foreach (TreeWidgetItem* groupItem, groups_) {
- std::vector<MockTreeWidgetItem*>& members = groupMembers_[groupItem];
- members.erase(std::remove(members.begin(), members.end(), item), members.end());
- }
- };
- private:
- std::vector<MockTreeWidgetItem*> groups_;
- std::map<TreeWidgetItem*, std::vector<MockTreeWidgetItem*> > groupMembers_;
- MockTreeWidget* root_;
-};
-
-}
-
-#endif
-
-
diff --git a/Swiften/Roster/UnitTest/MockTreeWidgetItem.cpp b/Swiften/Roster/UnitTest/MockTreeWidgetItem.cpp
deleted file mode 100644
index 4238ead..0000000
--- a/Swiften/Roster/UnitTest/MockTreeWidgetItem.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-#include "Swiften/Roster/UnitTest/MockTreeWidgetItem.h"
-
-#include "Swiften/Roster/UnitTest/MockTreeWidgetFactory.h"
-
-namespace Swift {
-
-MockTreeWidgetItem::~MockTreeWidgetItem() {
- factory_->removeItem(this);
-}
-
-}
-
-
-
diff --git a/Swiften/Roster/UnitTest/MockTreeWidgetItem.h b/Swiften/Roster/UnitTest/MockTreeWidgetItem.h
deleted file mode 100644
index 08b9f1a..0000000
--- a/Swiften/Roster/UnitTest/MockTreeWidgetItem.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010 Kevin Smith
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#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 MockTreeWidgetFactory;
-class MockTreeWidgetItem : public TreeWidgetItem {
- public:
- MockTreeWidgetItem(MockTreeWidgetFactory* factory) {factory_ = factory;};
- virtual ~MockTreeWidgetItem();
- virtual void setText(const String& text) {text_ = text;};
- String getText() {return text_;};
- virtual void setStatusText(const String&) {};
- virtual void setAvatarPath(const String&) {};
- virtual void setExpanded(bool) {};
- virtual void setStatusShow(StatusShow::Type /*show*/) {};
- virtual void show() {};
- virtual void hide() {};
- private:
- String text_;
- MockTreeWidgetFactory* factory_;
-};
-
-}
-#endif
-
-
diff --git a/Swiften/Roster/UnitTest/RosterTest.cpp b/Swiften/Roster/UnitTest/RosterTest.cpp
index 5a2a3e3..f9dff33 100644
--- a/Swiften/Roster/UnitTest/RosterTest.cpp
+++ b/Swiften/Roster/UnitTest/RosterTest.cpp
@@ -9,9 +9,7 @@
#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"
+#include "Swiften/Roster/GroupRosterItem.h"
using namespace Swift;
@@ -23,8 +21,6 @@ class RosterTest : public CppUnit::TestFixture
private:
Roster *roster_;
- TreeWidget *widget_;
- TreeWidgetFactory *factory_;
JID jid1_;
JID jid2_;
JID jid3_;
@@ -34,15 +30,11 @@ class RosterTest : public CppUnit::TestFixture
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_);
+ roster_ = new Roster();
}
void tearDown() {
delete roster_;
- //delete widget_;
- delete factory_;
}
void testGetGroup() {
@@ -50,12 +42,13 @@ class RosterTest : public CppUnit::TestFixture
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_ASSERT_EQUAL(2, (int)roster_->getRoot()->getChildren().size());
+ CPPUNIT_ASSERT_EQUAL(String("group1"), roster_->getRoot()->getChildren()[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(String("group2"), roster_->getRoot()->getChildren()[1]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(String("Bert"), ((GroupRosterItem*)roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(String("Cookie"), ((GroupRosterItem*)roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(String("Ernie"), ((GroupRosterItem*)roster_->getRoot()->getChildren()[1])->getChildren()[0]->getDisplayName());
+
}
};
diff --git a/Swiften/Roster/UserRosterAction.h b/Swiften/Roster/UserRosterAction.h
deleted file mode 100644
index b869530..0000000
--- a/Swiften/Roster/UserRosterAction.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
- */
-
-#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/SConscript b/Swiften/SConscript
index dfda3ba..a95635a 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -54,6 +54,8 @@ if env["SCONS_STAGE"] == "build" :
"Queries/Responders/DiscoInfoResponder.cpp",
"Queries/Responders/SoftwareVersionResponder.cpp",
"Roster/ContactRosterItem.cpp",
+ "Roster/GroupRosterItem.cpp",
+ "Roster/RosterItem.cpp",
"Roster/Roster.cpp",
"Roster/XMPPRoster.cpp",
"Serializer/AuthRequestSerializer.cpp",
@@ -191,7 +193,6 @@ if env["SCONS_STAGE"] == "build" :
File("Roster/UnitTest/OfflineRosterFilterTest.cpp"),
File("Roster/UnitTest/RosterTest.cpp"),
File("Roster/UnitTest/XMPPRosterTest.cpp"),
- File("Roster/UnitTest/MockTreeWidgetItem.cpp"),
File("SASL/UnitTest/PLAINMessageTest.cpp"),
File("SASL/UnitTest/PLAINClientAuthenticatorTest.cpp"),
File("SASL/UnitTest/SCRAMSHA1ClientAuthenticatorTest.cpp"),