From 13c1ef651158d8bdbd459ebea461c23c89699abd Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Tue, 15 Sep 2009 11:06:15 +0100
Subject: Completely untested. Rewiring the MainController for Client to be
 reconnectable (won't compile).


diff --git a/Swift/Controllers/ChatControllerBase.cpp b/Swift/Controllers/ChatControllerBase.cpp
index 519b019..7d11401 100644
--- a/Swift/Controllers/ChatControllerBase.cpp
+++ b/Swift/Controllers/ChatControllerBase.cpp
@@ -23,12 +23,11 @@ ChatControllerBase::~ChatControllerBase() {
 }
 
 void ChatControllerBase::setEnabled(bool enabled) {
-	//FIXME: implement
-	h
+	chatWindow_->setInputEnabled(enabled);
 }
 
 void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) {
-	if (info->hasFeature(DiscoInfo::SecurityLabels)) {
+	if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabels)) {
 		chatWindow_->setSecurityLabelsEnabled(true);
 		chatWindow_->setSecurityLabelsError();
 		boost::shared_ptr<GetSecurityLabelsCatalogRequest> request(new GetSecurityLabelsCatalogRequest(JID(toJID_.toBare()), iqRouter_));
@@ -50,7 +49,7 @@ void ChatControllerBase::handleAllMessagesRead() {
 }
 
 void ChatControllerBase::handleSendMessageRequest(const String &body) {
-	if (body.isEmpty()) {
+	if (!stanzaChannel_->isAvailable() || body.isEmpty()) {
 		return;
 	}
 	boost::shared_ptr<Message> message(new Message());
diff --git a/Swift/Controllers/ChatControllerBase.h b/Swift/Controllers/ChatControllerBase.h
index a977f8c..601e56b 100644
--- a/Swift/Controllers/ChatControllerBase.h
+++ b/Swift/Controllers/ChatControllerBase.h
@@ -14,6 +14,7 @@
 #include "Swiften/Elements/SecurityLabelsCatalog.h"
 #include "Swiften/Elements/Error.h"
 #include "Swiften/Presence/PresenceOracle.h"
+#include "Swiften/Queries/IQRouter.h"
 
 namespace Swift {
 	class IQRouter;
diff --git a/Swift/Controllers/ChatWindow.h b/Swift/Controllers/ChatWindow.h
index 816b843..db1e9e3 100644
--- a/Swift/Controllers/ChatWindow.h
+++ b/Swift/Controllers/ChatWindow.h
@@ -32,6 +32,7 @@ namespace Swift {
 			virtual TreeWidget *getTreeWidget() = 0;
 			virtual void setSecurityLabelsError() = 0;
 			virtual SecurityLabel getSelectedSecurityLabel() = 0;
+			virtual void setInputEnabled(bool enabled) = 0;
 
 			boost::signal<void ()> onClosed;
 			boost::signal<void ()> onAllMessagesRead;
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index cf85c18..a8fec70 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -61,8 +61,7 @@ typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
 
 MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowFactory *mainWindowFactory, LoginWindowFactory *loginWindowFactory, TreeWidgetFactory *treeWidgetFactory, SettingsProvider *settings, Application* application, SystemTray* systemTray, SoundPlayer* soundPlayer)
 		: client_(NULL), chatWindowFactory_(chatWindowFactory), mainWindowFactory_(mainWindowFactory), loginWindowFactory_(loginWindowFactory), treeWidgetFactory_(treeWidgetFactory), settings_(settings),
-		xmppRosterController_(NULL), rosterController_(NULL), loginWindow_(NULL), clientVersionResponder_(NULL), nickResolver_(NULL), discoResponder_(NULL), 
-		serverDiscoInfo_(new DiscoInfo()),  xmppRoster_(new XMPPRoster()) {
+		xmppRosterController_(NULL), rosterController_(NULL), loginWindow_(NULL), clientVersionResponder_(NULL), nickResolver_(NULL), discoResponder_(NULL) {
 	application_ = application;
 	presenceOracle_ = NULL;
 	avatarManager_ = NULL;
@@ -96,19 +95,16 @@ MainController::~MainController() {
 }
 
 void MainController::resetClient() {
-	// FIXME: Most of this should be moved closer to the point where the client is logged out.
+	serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>();
+	xmppRoster_ = boost::shared_ptr<XMPPRoster>();
 	delete presenceOracle_;
 	presenceOracle_ = NULL;
 	delete nickResolver_;
 	nickResolver_ = NULL;
 	delete avatarManager_;
 	avatarManager_ = NULL;
-	//delete rosterController_;
-	//rosterController_ = NULL;
-	if (rosterController_) {
-		rosterController_->setAvatarManager(NULL);
-		rosterController_->setNickResolver(NULL);
-	}
+	delete rosterController_;
+	rosterController_ = NULL;
 	delete xmppRosterController_;
 	xmppRosterController_ = NULL;
 	delete clientVersionResponder_;
@@ -117,49 +113,45 @@ void MainController::resetClient() {
 	discoResponder_ = NULL;
 	delete client_;
 	client_ = NULL;
+	
 }
 
 void MainController::handleConnected() {
 	//FIXME: this freshLogin thing is temporary so I can see what's what before I split into a seperate method.
 	bool freshLogin = rosterController_ == NULL;
-	
-	presenceOracle_ = new PresenceOracle(client_);
 	if (freshLogin) {
+		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
+		xmppRoster_ = boost::shared_ptr<XMPPRoster>(new XMPPRoster());
+		presenceOracle_ = new PresenceOracle(client_);
+
 		lastSentPresence_ = boost::shared_ptr<Presence>();
-	}
 
-	client_->onPresenceReceived.connect(boost::bind(&MainController::handleIncomingPresence, this, _1));
+		client_->onPresenceReceived.connect(boost::bind(&MainController::handleIncomingPresence, this, _1));
 
-	nickResolver_ = new NickResolver(xmppRoster_);
+		nickResolver_ = new NickResolver(xmppRoster_);
 
-	avatarManager_ = new AvatarManager(client_, client_, avatarStorage_, this);
-	if (freshLogin) {
+		avatarManager_ = new AvatarManager(client_, client_, avatarStorage_, this);
 		rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, treeWidgetFactory_, nickResolver_);
 		rosterController_->onStartChatRequest.connect(boost::bind(&MainController::handleChatRequest, this, _1));
 		rosterController_->onJoinMUCRequest.connect(boost::bind(&MainController::handleJoinMUCRequest, this, _1, _2));
 		rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
-	} else {
-		rosterController_->setAvatarManager(avatarManager_);
-		rosterController_->setNickResolver(nickResolver_);
-	}
 
-	xmppRosterController_ = new XMPPRosterController(client_, xmppRoster_);
-	xmppRosterController_->requestRoster();
+		xmppRosterController_ = new XMPPRosterController(client_, xmppRoster_);
+		xmppRosterController_->requestRoster();
 
-	clientVersionResponder_ = new SoftwareVersionResponder(CLIENT_NAME, CLIENT_VERSION, client_);
-	if (freshLogin) {
+		clientVersionResponder_ = new SoftwareVersionResponder(CLIENT_NAME, CLIENT_VERSION, client_);
 		loginWindow_->morphInto(rosterController_->getWindow());
-	}
-
-	DiscoInfo discoInfo;
-	discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
-	capsInfo_ = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator(CLIENT_NODE).generateCapsInfo(discoInfo)));
 
-	discoResponder_ = new DiscoInfoResponder(client_);
-	discoResponder_->setDiscoInfo(discoInfo);
-	discoResponder_->setDiscoInfo(capsInfo_->getNode() + "#" + capsInfo_->getVersion(), discoInfo);
+		DiscoInfo discoInfo;
+		discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
+		capsInfo_ = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator(CLIENT_NODE).generateCapsInfo(discoInfo)));
 
-	serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
+		discoResponder_ = new DiscoInfoResponder(client_);
+		discoResponder_->setDiscoInfo(discoInfo);
+		discoResponder_->setDiscoInfo(capsInfo_->getNode() + "#" + capsInfo_->getVersion(), discoInfo);
+		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
+	}
+	
 	boost::shared_ptr<GetDiscoInfoRequest> discoInfoRequest(new GetDiscoInfoRequest(JID(), client_));
 	discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2));
 	discoInfoRequest->send();
@@ -176,8 +168,8 @@ void MainController::handleConnected() {
 		initialPresence = boost::shared_ptr<Presence>(new Presence());
 	}
 	initialPresence->addPayload(capsInfo_);
-	sendPresence(initialPresence);
 	enableManagers();
+	sendPresence(initialPresence);
 }
 
 void MainController::handleEventQueueLengthChange(int count) {
@@ -234,17 +226,17 @@ void MainController::handleLoginRequest(const String &username, const String &pa
 }
 
 void MainController::performLoginFromCachedCredentials() {
-	resetClient();
-
-	client_ = new Swift::Client(jid_, password_);
-	//client_->onDataRead.connect(&printIncomingData);
-	//client_->onDataWritten.connect(&printOutgoingData);
-	if (!certificateFile_.isEmpty()) {
-		client_->setCertificate(certificateFile_);
+	if (!client_) {
+		client_ = new Swift::Client(jid_, password_);
+		//client_->onDataRead.connect(&printIncomingData);
+		//client_->onDataWritten.connect(&printOutgoingData);
+		if (!certificateFile_.isEmpty()) {
+			client_->setCertificate(certificateFile_);
+		}
+		client_->onError.connect(boost::bind(&MainController::handleError, this, _1));
+		client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
+		client_->onMessageReceived.connect(boost::bind(&MainController::handleIncomingMessage, this, _1));
 	}
-	client_->onError.connect(boost::bind(&MainController::handleError, this, _1));
-	client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
-	client_->onMessageReceived.connect(boost::bind(&MainController::handleIncomingMessage, this, _1));
 	client_->connect();
 }
 
@@ -280,15 +272,13 @@ void MainController::signout() {
 		delete controllerPair.second;
 	}
 	mucControllers_.clear();
+	delete rosterController_;
+	rosterController_ = NULL;
+	resetClient();
 }
 
 void MainController::logout() {
-	delete discoResponder_;
-	discoResponder_ = NULL;
-	delete clientVersionResponder_;
-	clientVersionResponder_ = NULL;
 	disableManagers();
-	resetClient();
 }
 
 void MainController::disableManagers() {
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index e27335b..6da5faf 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -10,6 +10,7 @@
 #include "Swiften/EventLoop/MainEventLoop.h"
 #include "Swiften/Roster/Roster.h"
 #include "Swiften/Roster/SetPresence.h"
+#include "Swiften/Roster/AppearOffline.h"
 #include "Swiften/Roster/SetAvatar.h"
 #include "Swiften/Roster/OfflineRosterFilter.h"
 #include "Swiften/Roster/OpenChatRosterAction.h"
@@ -63,8 +64,9 @@ void RosterController::setAvatarManager(AvatarManager* avatarManager) {
 }
 
 void RosterController::setEnabled(bool enabled) {
-	//FIXME: implement;
-	h
+	if (!enabled) {
+		roster_->applyOnItems(AppearOffline());
+	}
 }
 
 void RosterController::handleShowOfflineToggled(bool state) {
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 7e71b7f..3da0f8d 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -115,6 +115,10 @@ void QtChatWindow::qAppFocusChanged(QWidget *old, QWidget *now) {
 	
 }
 
+void QtChatWindow::setInputEnabled(bool enabled) {
+	input_->setEnabled(enabled);
+}
+
 void QtChatWindow::showEvent(QShowEvent* event) {
 	emit windowOpening();
 	QWidget::showEvent(event);
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index 80961f8..8a07de3 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -32,6 +32,7 @@ namespace Swift {
 			void setSecurityLabelsError();
 			SecurityLabel getSelectedSecurityLabel();
 			void setName(const String& name);
+			void setInputEnabled(bool enabled);
 
 		protected slots:
 			void qAppFocusChanged(QWidget* old, QWidget* now);
diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h
index 13e7ed4..37c58c7 100644
--- a/Swiften/Client/StanzaChannel.h
+++ b/Swiften/Client/StanzaChannel.h
@@ -13,6 +13,7 @@ namespace Swift {
 		public:
 			virtual void sendMessage(boost::shared_ptr<Message>) = 0;
 			virtual void sendPresence(boost::shared_ptr<Presence>) = 0;
+			virtual bool isAvailable() = 0;
 
 			boost::signal<void (boost::shared_ptr<Message>)> onMessageReceived;
 			boost::signal<void (boost::shared_ptr<Presence>) > onPresenceReceived;
diff --git a/Swiften/Queries/IQChannel.h b/Swiften/Queries/IQChannel.h
index 0dbb1be..1692afe 100644
--- a/Swiften/Queries/IQChannel.h
+++ b/Swiften/Queries/IQChannel.h
@@ -14,6 +14,8 @@ namespace Swift {
 
 			virtual void sendIQ(boost::shared_ptr<IQ>) = 0;
 			virtual String getNewIQID() = 0;
+			
+			virtual bool isAvailable() = 0;
 
 			boost::signal<void (boost::shared_ptr<IQ>)> onIQReceived;
 	};
diff --git a/Swiften/Queries/IQRouter.cpp b/Swiften/Queries/IQRouter.cpp
index b20d344..ffed5f7 100644
--- a/Swiften/Queries/IQRouter.cpp
+++ b/Swiften/Queries/IQRouter.cpp
@@ -19,6 +19,10 @@ IQRouter::IQRouter(IQChannel* channel) : channel_(channel), queueRemoves_(false)
 IQRouter::~IQRouter() {
 }
 
+bool IQRouter::isAvailable() {
+	return channel_->isAvailable();
+}
+
 void IQRouter::handleIQ(boost::shared_ptr<IQ> iq) {
 	queueRemoves_ = true;
 
diff --git a/Swiften/Queries/IQRouter.h b/Swiften/Queries/IQRouter.h
index 6de2ff9..717a845 100644
--- a/Swiften/Queries/IQRouter.h
+++ b/Swiften/Queries/IQRouter.h
@@ -23,6 +23,8 @@ namespace Swift {
 
 			void sendIQ(boost::shared_ptr<IQ> iq);
 			String getNewIQID();
+			
+			bool isAvailable();
 
 		private:
 			void handleIQ(boost::shared_ptr<IQ> iq);
diff --git a/Swiften/Roster/AppearOffline.h b/Swiften/Roster/AppearOffline.h
new file mode 100644
index 0000000..673e018
--- /dev/null
+++ b/Swiften/Roster/AppearOffline.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Swiften/Roster/RosterItemOperation.h"
+#include "Swiften/Roster/ContactRosterItem.h"
+
+namespace Swift {
+
+class RosterItem;
+
+class AppearOffline : public RosterItemOperation {
+	public:
+		AppearOffline() {
+		}
+
+		virtual void operator() (RosterItem* item) const {
+			ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+			if (contact) {
+				contact->setStatusShow(StatusShow::None);
+			}
+		}
+
+};
+
+}
+
+
-- 
cgit v0.10.2-6-g49f6