From 815af99155f7f59fb4e43d75e271a5061706449b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 10 Oct 2010 20:14:14 +0200
Subject: Moved XMPP roster & controller from Swift to Client.


diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index c8f2f78..bbc9609 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -26,7 +26,7 @@ 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, NickResolver* nickResolver, PresenceOracle* presenceOracle, boost::shared_ptr<DiscoInfo> serverDiscoInfo, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsManager* entityCapsManager) : jid_(jid), useDelayForLatency_(useDelayForLatency), mucRegistry_(mucRegistry), entityCapsManager_(entityCapsManager) {
+ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsManager* entityCapsManager) : jid_(jid), useDelayForLatency_(useDelayForLatency), mucRegistry_(mucRegistry), entityCapsManager_(entityCapsManager) {
 	timerFactory_ = timerFactory;
 	eventController_ = eventController;
 	stanzaChannel_ = stanzaChannel;
@@ -35,7 +35,7 @@ ChatsManager::ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRo
 	nickResolver_ = nickResolver;
 	presenceOracle_ = presenceOracle;
 	avatarManager_ = NULL;
-	serverDiscoInfo_ = serverDiscoInfo;
+	serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 	presenceSender_ = presenceSender;
 	uiEventStream_ = uiEventStream;
 	mucBookmarkManager_ = new MUCBookmarkManager(iqRouter);
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 326a540..724701c 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -38,7 +38,7 @@ namespace Swift {
 
 	class ChatsManager {
 		public:
-			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, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsManager* entityCapsManager);
+			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsManager* entityCapsManager);
 			virtual ~ChatsManager();
 			void setAvatarManager(AvatarManager* avatarManager);
 			void setOnline(bool enabled);
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index e770e88..46b5580 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -76,7 +76,7 @@ public:
 		entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
 		chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
 		mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createWindow).With(uiEventStream_).Return(NULL);
-		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_);
+		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_);
 
 		avatarManager_ = new NullAvatarManager();
 		manager_->setAvatarManager(avatarManager_);
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index d7801f3..c4599b0 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -35,7 +35,6 @@
 #include "Swift/Controllers/SystemTray.h"
 #include "Swift/Controllers/SystemTrayController.h"
 #include "Swift/Controllers/XMLConsoleController.h"
-#include "Swiften/Roster/XMPPRosterController.h"
 #include "Swift/Controllers/UIEvents/UIEventStream.h"
 #include "Swift/Controllers/PresenceNotifier.h"
 #include "Swift/Controllers/EventNotifier.h"
@@ -103,7 +102,6 @@ MainController::MainController(
 	presenceSender_ = NULL;
 	presenceOracle_ = NULL;
 	mucRegistry_ = NULL;
-	xmppRoster_ = NULL;
 	vcardManager_ = NULL;
 	avatarManager_ = NULL;
 	capsManager_ = NULL;
@@ -112,7 +110,6 @@ MainController::MainController(
 	eventNotifier_ = NULL;
 	nickResolver_ = NULL;
 	rosterController_ = NULL;
-	xmppRosterController_ = NULL;
 	chatsManager_ = NULL;
 	eventWindowController_ = NULL;
 	discoResponder_ = NULL;
@@ -191,7 +188,6 @@ MainController::~MainController() {
 void MainController::resetClient() {
 	resetCurrentError();
 	resetPendingReconnects();
-	serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>();
 	delete mucSearchController_;
 	mucSearchController_ = NULL;
 	if (discoResponder_) {
@@ -201,8 +197,6 @@ void MainController::resetClient() {
 	}
 	delete eventWindowController_;
 	eventWindowController_ = NULL;
-	delete xmppRosterController_;
-	xmppRosterController_ = NULL;
 	delete chatsManager_;
 	chatsManager_ = NULL;
 	delete rosterController_;
@@ -221,8 +215,6 @@ void MainController::resetClient() {
 	nickResolver_ = NULL;
 	delete vcardManager_;
 	vcardManager_ = NULL;
-	delete xmppRoster_;
-	xmppRoster_ = NULL;
 	delete mucRegistry_;
 	mucRegistry_ = NULL;
 	delete presenceOracle_;
@@ -272,18 +264,14 @@ void MainController::handleConnected() {
 	bool freshLogin = rosterController_ == NULL;
 	myStatusLooksOnline_ = true;
 	if (freshLogin) {
-		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
-
-		rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, eventController_, uiEventStream_, client_->getIQRouter(), settings_);
+		rosterController_ = new RosterController(jid_, client_->getRoster(), avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, eventController_, uiEventStream_, client_->getIQRouter(), settings_);
 		rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
 		rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
 
-		chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_, &timerFactory_, mucRegistry_, entityCapsManager_);
+		chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_, &timerFactory_, mucRegistry_, entityCapsManager_);
 		client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
 		chatsManager_->setAvatarManager(avatarManager_);
 
-		xmppRosterController_ = new XMPPRosterController(client_->getIQRouter(), xmppRoster_);
-
 		eventWindowController_ = new EventWindowController(eventController_, eventWindowFactory_);
 
 		loginWindow_->morphInto(rosterController_->getWindow());
@@ -298,12 +286,11 @@ void MainController::handleConnected() {
 		discoResponder_->setDiscoInfo(discoInfo);
 		discoResponder_->setDiscoInfo(capsInfo_->getNode() + "#" + capsInfo_->getVersion(), discoInfo);
 		discoResponder_->start();
-		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 
 		mucSearchController_ = new MUCSearchController(jid_, uiEventStream_, mucSearchWindowFactory_, client_->getIQRouter());
 	}
 	
-	xmppRosterController_->requestRoster();
+	client_->requestRoster();
 
 	GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(), client_->getIQRouter());
 	discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2));
@@ -410,16 +397,19 @@ void MainController::performLoginFromCachedCredentials() {
 	}
 	if (!client_) {
 		client_ = new Swift::Client(jid_, password_);
+		client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1));
+		client_->onDataWritten.connect(boost::bind(&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1));
+		client_->onError.connect(boost::bind(&MainController::handleError, this, _1));
+		client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
 
 		client_->setSoftwareVersion(CLIENT_NAME, buildVersion);
 
 		presenceSender_ = new PresenceSender(client_->getStanzaChannel());
 		presenceOracle_ = new PresenceOracle(client_->getStanzaChannel());
 		mucRegistry_ = new MUCRegistry();
-		xmppRoster_ = new XMPPRoster();
 		vcardManager_ = new VCardManager(jid_, client_->getIQRouter(), getVCardStorageForProfile(jid_));
 		vcardManager_->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2));
-		nickResolver_ = new NickResolver(this->jid_.toBare(), xmppRoster_, vcardManager_, mucRegistry_);
+		nickResolver_ = new NickResolver(this->jid_.toBare(), client_->getRoster(), vcardManager_, mucRegistry_);
 		avatarManager_ = new AvatarManagerImpl(vcardManager_, client_->getStanzaChannel(), avatarStorage_, mucRegistry_);
 		capsManager_ = new CapsManager(capsStorage_, client_->getStanzaChannel(), client_->getIQRouter());
 		entityCapsManager_ = new EntityCapsManager(capsManager_, client_->getStanzaChannel());
@@ -427,15 +417,9 @@ void MainController::performLoginFromCachedCredentials() {
 		presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1));
 		eventNotifier_ = new EventNotifier(eventController_, notifier_, avatarManager_, nickResolver_);
 		eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1));
-		client_->onDataRead.connect(boost::bind(
-				&XMLConsoleController::handleDataRead, xmlConsoleController_, _1));
-		client_->onDataWritten.connect(boost::bind(
-				&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1));
 		if (!certificateFile_.isEmpty()) {
 			client_->setCertificate(certificateFile_);
 		}
-		client_->onError.connect(boost::bind(&MainController::handleError, this, _1));
-		client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
 		boost::shared_ptr<Presence> presence(new Presence());
 		presence->setShow(static_cast<StatusShow::Type>(profileSettings_->getIntSetting("lastShow", StatusShow::Online)));
 		presence->setStatus(profileSettings_->getStringSetting("lastStatus"));
@@ -543,7 +527,6 @@ void MainController::setManagersOnline(bool enabled) {
 
 void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, const boost::optional<ErrorPayload>& error) {
 	if (!error) {
-		serverDiscoInfo_ = info;
 		chatsManager_->setServerDiscoInfo(info);
 	}
 }
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index fb26a9d..7139ce9 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -25,7 +25,6 @@
 #include "Swift/Controllers/ProfileSettingsProvider.h"
 #include "Swiften/Elements/CapsInfo.h"
 #include "Swift/Controllers/XMPPEvents/ErrorEvent.h"
-#include "Swiften/Roster/XMPPRoster.h"
 #include "Swift/Controllers/UIEvents/UIEvent.h"
 
 namespace Swift {
@@ -44,7 +43,6 @@ namespace Swift {
 	class MainWindow;
 	class NickResolver;
 	class RosterController;
-	class XMPPRosterController;
 	class PresenceSender;
 	class DiscoInfoResponder;
 	class AvatarManager;
@@ -143,7 +141,6 @@ namespace Swift {
 			Notifier* notifier_;
 			PresenceNotifier* presenceNotifier_;
 			EventNotifier* eventNotifier_;
-			XMPPRosterController* xmppRosterController_;
 			RosterController* rosterController_;
 			EventController* eventController_;
 			EventWindowController* eventWindowController_;
@@ -154,8 +151,6 @@ namespace Swift {
 			XMLConsoleController* xmlConsoleController_;
 			ChatsManager* chatsManager_;
 			boost::shared_ptr<CapsInfo> capsInfo_;
-			boost::shared_ptr<DiscoInfo> serverDiscoInfo_;
-			XMPPRoster* xmppRoster_;;
 			JID jid_;
 			JID boundJID_;
 			PresenceOracle* presenceOracle_;
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 5c64506..e3e8a45 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -7,15 +7,23 @@
 #include "Swiften/Client/Client.h"
 
 #include "Swiften/Queries/Responders/SoftwareVersionResponder.h"
+#include "Swiften/Roster/XMPPRoster.h"
+#include "Swiften/Roster/XMPPRosterController.h"
 
 namespace Swift {
 
 Client::Client(const JID& jid, const String& password) : CoreClient(jid, password) {
 	softwareVersionResponder = new SoftwareVersionResponder(getIQRouter());
 	softwareVersionResponder->start();
+
+	roster = new XMPPRoster();
+	rosterController = new XMPPRosterController(getIQRouter(), roster);
 }
 
 Client::~Client() {
+	delete rosterController;
+	delete roster;
+
 	softwareVersionResponder->stop();
 	delete softwareVersionResponder;
 }
@@ -24,4 +32,9 @@ void Client::setSoftwareVersion(const String& name, const String& version) {
 	softwareVersionResponder->setVersion(name, version);
 }
 
+void Client::requestRoster() {
+	rosterController->requestRoster();
+}
+
+
 }
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 54d6e56..9f3e935 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -10,6 +10,8 @@
 
 namespace Swift {
 	class SoftwareVersionResponder;
+	class XMPPRoster;
+	class XMPPRosterController;
 
 	/**
 	 * Provides the core functionality for writing XMPP client software.
@@ -30,8 +32,33 @@ namespace Swift {
 			 */
 			void setSoftwareVersion(const String& name, const String& version);
 
+			/**
+			 * Returns a representation of the roster.
+			 *
+			 * The roster is initially empty. To populate it, call requestRoster(), which
+			 * will request the roster from the server. When the roster has been requested,
+			 * it will also be kept up to date when it is updated on the server side.
+			 *
+			 * This pointer remains the same across the lifetime of Client. All changes
+			 * to the roster (e.g. after the initial roster request, or after subsequent
+			 * roster updates) are notified through the XMPPRoster's signals.
+			 *
+			 * \see requestRoster()
+			 */
+			XMPPRoster* getRoster() const {
+				return roster;
+			}
+
+			/**
+			 * Requests the roster from the server.
+			 *
+			 * \see getRoster()
+			 */
+			void requestRoster();
+
 		private:
 			SoftwareVersionResponder* softwareVersionResponder;
-
+			XMPPRoster* roster;
+			XMPPRosterController* rosterController;
 	};
 }
-- 
cgit v0.10.2-6-g49f6