From c5b8d80800af29bcab6ba2263033fa0d7dc797ef Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Fri, 20 Aug 2010 14:42:05 +0100
Subject: Restart with previous (per-accoun) status.

Resolves: #390

diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 5502640..b267dd2 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -28,7 +28,6 @@
 #include "Swift/Controllers/UIInterfaces/MainWindow.h"
 #include "Swift/Controllers/Chat/MUCController.h"
 #include "Swift/Controllers/NickResolver.h"
-#include "Swift/Controllers/ProfileSettingsProvider.h"
 #include "Swift/Controllers/RosterController.h"
 #include "Swift/Controllers/SoundEventController.h"
 #include "Swift/Controllers/SoundPlayer.h"
@@ -122,8 +121,8 @@ MainController::MainController(ChatWindowFactory* chatWindowFactory, MainWindowF
 	idleDetector_.onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
 
 	xmlConsoleController_ = new XMLConsoleController(uiEventStream_, xmlConsoleWidgetFactory);
-
 	if (loginAutomatically) {
+		profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_);
 		handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, true, true);
 	}
 }
@@ -169,6 +168,8 @@ void MainController::resetClient() {
 	mucSearchController_ = NULL;
 	delete statusTracker_;
 	statusTracker_ = NULL;
+	delete profileSettings_;
+	profileSettings_ = NULL;
 }
 
 void MainController::resetPendingReconnects() {
@@ -231,7 +232,6 @@ void MainController::handleConnected() {
 		serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
 
 		mucSearchController_ = new MUCSearchController(jid_, uiEventStream_, mucSearchWindowFactory_, client_);
-		statusTracker_  = new StatusTracker();
 	}
 	
 	boost::shared_ptr<GetDiscoInfoRequest> discoInfoRequest(new GetDiscoInfoRequest(JID(), client_));
@@ -271,6 +271,10 @@ void MainController::handleChangeStatusRequest(StatusShow::Type show, const Stri
 	}
 	presence->setStatus(statusText);
 	statusTracker_->setRequestedPresence(presence);
+	if (presence->getType() != Presence::Unavailable) {
+		profileSettings_->storeInt("lastShow", presence->getShow());
+		profileSettings_->storeString("lastStatus", presence->getStatus());
+	}
 	if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) {
 		performLoginFromCachedCredentials();
 	} else {
@@ -317,14 +321,13 @@ void MainController::handleInputIdleChanged(bool idle) {
 void MainController::handleLoginRequest(const String &username, const String &password, const String& certificateFile, bool remember, bool loginAutomatically) {
 	loginWindow_->setMessage("");
 	loginWindow_->setIsLoggingIn(true);
-	ProfileSettingsProvider* profileSettings = new ProfileSettingsProvider(username, settings_);
-	profileSettings->storeString("jid", username);
-	profileSettings->storeString("certificate", certificateFile);
-	profileSettings->storeString("pass", (remember || loginAutomatically) ? password : "");
+	profileSettings_ = new ProfileSettingsProvider(username, settings_);
+	profileSettings_->storeString("jid", username);
+	profileSettings_->storeString("certificate", certificateFile);
+	profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
 	settings_->storeString("lastLoginJID", username);
 	settings_->storeBool("loginAutomatically", loginAutomatically);
-	loginWindow_->addAvailableAccount(profileSettings->getStringSetting("jid"), profileSettings->getStringSetting("pass"), profileSettings->getStringSetting("certificate"));
-	delete profileSettings;
+	loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"));
 	jid_ = JID(username);
 	password_ = password;
 	certificateFile_ = certificateFile;
@@ -332,6 +335,9 @@ void MainController::handleLoginRequest(const String &username, const String &pa
 }
 
 void MainController::performLoginFromCachedCredentials() {
+	if (!statusTracker_) {
+		statusTracker_  = new StatusTracker();
+	}
 	if (!client_) {
 		client_ = new Swift::Client(jid_, password_);
 		presenceSender_ = new PresenceSender(client_);
@@ -344,6 +350,10 @@ void MainController::performLoginFromCachedCredentials() {
 		}
 		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"));
+		statusTracker_->setRequestedPresence(presence);
 	} else {
 		/* In case we're in the middle of another login, make sure they don't overlap */
 		client_->disconnect();
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 36fe59d..e220211 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -22,6 +22,7 @@
 #include "Swiften/Elements/ErrorPayload.h"
 #include "Swiften/Elements/Presence.h"
 #include "Swiften/Settings/SettingsProvider.h"
+#include "Swift/Controllers/ProfileSettingsProvider.h"
 #include "Swiften/Elements/CapsInfo.h"
 #include "Swiften/Events/ErrorEvent.h"
 #include "Swiften/Roster/XMPPRoster.h"
@@ -102,6 +103,7 @@ namespace Swift {
 			LoginWindowFactory* loginWindowFactory_;
 			EventWindowFactory* eventWindowFactory_;
 			SettingsProvider *settings_;
+			ProfileSettingsProvider* profileSettings_;
 			AvatarStorage* avatarStorage_;
 			ApplicationMessageDisplay* applicationMessageDisplay_;
 			ChatController* chatController_;
diff --git a/Swift/Controllers/ProfileSettingsProvider.h b/Swift/Controllers/ProfileSettingsProvider.h
index 62878df..76d20e6 100644
--- a/Swift/Controllers/ProfileSettingsProvider.h
+++ b/Swift/Controllers/ProfileSettingsProvider.h
@@ -27,6 +27,8 @@ class ProfileSettingsProvider {
 		virtual ~ProfileSettingsProvider() {};
 		virtual String getStringSetting(const String &settingPath) {return provider_->getStringSetting(profileSettingPath(settingPath));};
 		virtual void storeString(const String &settingPath, const String &settingValue) {provider_->storeString(profileSettingPath(settingPath), settingValue);};
+		virtual int getIntSetting(const String& settingPath, int defaultValue) {return provider_->getIntSetting(settingPath, defaultValue);}
+		virtual void storeInt(const String& settingPath, int settingValue) {provider_->storeInt(settingPath, settingValue);}
 		
 	private:
 		String profileSettingPath(const String &settingPath) {return profile_ + ":" + settingPath;};
diff --git a/Swift/QtUI/QtSettingsProvider.cpp b/Swift/QtUI/QtSettingsProvider.cpp
index 4100c7d..ea0013a 100644
--- a/Swift/QtUI/QtSettingsProvider.cpp
+++ b/Swift/QtUI/QtSettingsProvider.cpp
@@ -36,6 +36,15 @@ void QtSettingsProvider::storeBool(const String &settingPath, bool settingValue)
 	settings_.setValue(P2QSTRING(settingPath), settingValue);
 }
 
+int QtSettingsProvider::getIntSetting(const String &settingPath, int defaultValue) {
+	QVariant setting = settings_.value(P2QSTRING(settingPath));
+	return setting.isNull() ? defaultValue : setting.toInt();
+}
+
+void QtSettingsProvider::storeInt(const String &settingPath, int settingValue) {
+	settings_.setValue(P2QSTRING(settingPath), settingValue);
+}
+
 std::vector<String> QtSettingsProvider::getAvailableProfiles() {
 	std::vector<String> profiles;
 	QVariant profilesVariant = settings_.value("profileList");
diff --git a/Swift/QtUI/QtSettingsProvider.h b/Swift/QtUI/QtSettingsProvider.h
index 75c5678..93f9ec1 100644
--- a/Swift/QtUI/QtSettingsProvider.h
+++ b/Swift/QtUI/QtSettingsProvider.h
@@ -21,6 +21,8 @@ class QtSettingsProvider : public SettingsProvider {
 		virtual void storeString(const String &settingPath, const String &settingValue);
 		virtual bool getBoolSetting(const String &settingPath, bool defaultValue);
 		virtual void storeBool(const String &settingPath, bool settingValue);
+		virtual int getIntSetting(const String &settingPath, int defaultValue);
+		virtual void storeInt(const String &settingPath, int settingValue);
 		virtual std::vector<String> getAvailableProfiles();
 		virtual void createProfile(const String& profile);
 		QSettings* getQSettings();
diff --git a/Swiften/Settings/SettingsProvider.h b/Swiften/Settings/SettingsProvider.h
index 0a604ec..7ddf789 100644
--- a/Swiften/Settings/SettingsProvider.h
+++ b/Swiften/Settings/SettingsProvider.h
@@ -20,6 +20,8 @@ class SettingsProvider {
 		virtual void storeString(const String &settingPath, const String &settingValue) = 0;
 		virtual bool getBoolSetting(const String &settingPath, bool defaultValue) = 0;
 		virtual void storeBool(const String &settingPath, bool settingValue) = 0;
+		virtual int getIntSetting(const String &settingPath, int defaultValue) = 0;
+		virtual void storeInt(const String &settingPath, int settingValue) = 0;
 		virtual std::vector<String> getAvailableProfiles() = 0;
 		virtual void createProfile(const String& profile) = 0;
 };
-- 
cgit v0.10.2-6-g49f6