From 759dfaf9283ed07696a060a5ca92bef2699b1b65 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Fri, 12 Nov 2010 23:43:20 +0000
Subject: Persist toggle show offline.

Resolves: #689
Release-Notes: The toggle state for showing offline contacts will now persist between restarts.

diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index 4df8d13..ed311d9 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -31,9 +31,12 @@
 #include "Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h"
 #include "Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h"
 #include "Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h"
+#include "Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h"
 
 namespace Swift {
-	
+
+static const String SHOW_OFFLINE = "showOffline";
+
 /**
  * The controller does not gain ownership of these parameters.
  */
@@ -43,12 +46,12 @@ RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, Avata
 	presenceOracle_ = presenceOracle;
 	subscriptionManager_ = subscriptionManager;
 	eventController_ = eventController;
+	settings_ = settings;
 	expandiness_ = new RosterGroupExpandinessPersister(roster_, settings);
 	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)));
 	xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1));
 	xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3));
@@ -61,7 +64,9 @@ RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, Avata
 	avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1));
 	mainWindow_->setMyAvatarPath(avatarManager_->getAvatarPath(myJID_).string());
 	setNickResolver(nickResolver);
-	
+	if (settings->getBoolSetting(SHOW_OFFLINE, false)) {
+		uiEventStream->onUIEvent(boost::shared_ptr<UIEvent>(new ToggleShowOfflineUIEvent(true)));
+	}
 }
 
 RosterController::~RosterController() {
@@ -93,6 +98,9 @@ void RosterController::setEnabled(bool enabled) {
 }
 
 void RosterController::handleShowOfflineToggled(bool state) {
+	if (state != settings_->getBoolSetting(SHOW_OFFLINE, false)) {
+		settings_->storeBool(SHOW_OFFLINE, state);
+	}
 	if (state) {
 		roster_->removeFilter(offlineFilter_);
 	} else {
@@ -161,6 +169,10 @@ void RosterController::handleOnJIDUpdated(const JID& jid, const String& oldName,
 }
 
 void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
+	boost::shared_ptr<ToggleShowOfflineUIEvent> showOfflineEvent = boost::dynamic_pointer_cast<ToggleShowOfflineUIEvent>(event);
+	if (showOfflineEvent) {
+		handleShowOfflineToggled(showOfflineEvent->getShow());
+	}
 	boost::shared_ptr<AddContactUIEvent> addContactEvent = boost::dynamic_pointer_cast<AddContactUIEvent>(event);
 	if (addContactEvent) {
 		RosterItemPayload item;
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index 70f1288..be9e407 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -74,8 +74,8 @@ namespace Swift {
 			EventController* eventController_;
 			RosterGroupExpandinessPersister* expandiness_;
 			IQRouter* iqRouter_;
+			SettingsProvider* settings_;
 			boost::bsignals::scoped_connection changeStatusConnection_;
-			boost::bsignals::scoped_connection showOfflineConnection_;
 			boost::bsignals::scoped_connection signOutConnection_;
 			boost::bsignals::scoped_connection uiEventConnection_;
 	};
diff --git a/Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h b/Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h
new file mode 100644
index 0000000..b45eb83
--- /dev/null
+++ b/Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swift/Controllers/UIEvents/UIEvent.h"
+
+namespace Swift {
+	class ToggleShowOfflineUIEvent : public UIEvent {
+		public:
+			ToggleShowOfflineUIEvent(bool show) : show_(show) {};
+			bool getShow() {return show_;};
+		private:
+			bool show_;
+	};
+}
diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h
index 26b4ae8..3f37fc8 100644
--- a/Swift/Controllers/UIInterfaces/MainWindow.h
+++ b/Swift/Controllers/UIInterfaces/MainWindow.h
@@ -33,7 +33,6 @@ namespace Swift {
 			virtual void setConnecting() = 0;
 			
 			boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest;
-			boost::signal<void (bool)> onShowOfflineToggled;
 			boost::signal<void ()> onSignOutRequest;
 
 		private:
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index f737e30..710ef61 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -7,6 +7,7 @@
 #include "QtMainWindow.h"
 
 #include <boost/optional.hpp>
+#include <boost/bind.hpp>
 
 #include <QBoxLayout>
 #include <QComboBox>
@@ -26,6 +27,7 @@
 #include "Swift/Controllers/UIEvents/AddContactUIEvent.h"
 #include "Swift/Controllers/UIEvents/RequestMUCSearchUIEvent.h"
 #include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
+#include "Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h"
 
 namespace Swift {
 
@@ -71,11 +73,11 @@ QtMainWindow::QtMainWindow(UIEventStream* uiEventStream) : QWidget(), MainWindow
 	
 	QMenu* viewMenu = new QMenu(tr("View"), this);
 	menus_.push_back(viewMenu);
-	QAction* showOfflineAction = new QAction("Show offline contacts", this);
-	showOfflineAction->setCheckable(true);
-	showOfflineAction->setChecked(false);
-	connect(showOfflineAction, SIGNAL(toggled(bool)), SLOT(handleShowOfflineToggled(bool)));
-	viewMenu->addAction(showOfflineAction);
+	showOfflineAction_ = new QAction("Show offline contacts", this);
+	showOfflineAction_->setCheckable(true);
+	showOfflineAction_->setChecked(false);
+	connect(showOfflineAction_, SIGNAL(toggled(bool)), SLOT(handleShowOfflineToggled(bool)));
+	viewMenu->addAction(showOfflineAction_);
 
 	QMenu* actionsMenu = new QMenu(tr("Actions"), this);
 	menus_.push_back(actionsMenu);
@@ -88,9 +90,13 @@ QtMainWindow::QtMainWindow(UIEventStream* uiEventStream) : QWidget(), MainWindow
 	QAction* signOutAction = new QAction("Sign Out", this);
 	connect(signOutAction, SIGNAL(triggered()), SLOT(handleSignOutAction()));
 	actionsMenu->addAction(signOutAction);
+
+	lastOfflineState_ = false;
+	uiEventStream_->onUIEvent.connect(boost::bind(&QtMainWindow::handleUIEvent, this, _1));
 }
 
 QtMainWindow::~QtMainWindow() {
+	uiEventStream_->onUIEvent.disconnect(boost::bind(&QtMainWindow::handleUIEvent, this, _1));
 	delete contextMenu_;
 }
 
@@ -141,8 +147,19 @@ void QtMainWindow::handleStatusChanged(StatusShow::Type showType, const QString
 	onChangeStatusRequest(showType, Q2PSTRING(statusMessage));
 }
 
+void QtMainWindow::handleUIEvent(boost::shared_ptr<UIEvent> event) {
+	boost::shared_ptr<ToggleShowOfflineUIEvent> toggleEvent = boost::dynamic_pointer_cast<ToggleShowOfflineUIEvent>(event);
+	if (toggleEvent) {
+		handleShowOfflineToggled(toggleEvent->getShow());
+	}
+}
+
 void QtMainWindow::handleShowOfflineToggled(bool state) {
-	onShowOfflineToggled(state);
+	if (state != lastOfflineState_) {
+		lastOfflineState_ = state;
+		showOfflineAction_->setChecked(state);
+		uiEventStream_->onUIEvent(boost::shared_ptr<UIEvent>(new ToggleShowOfflineUIEvent(state)));
+	}
 }
 
 void QtMainWindow::setMyName(const String& name) {
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index c92c62a..9e200b1 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -48,6 +48,7 @@ namespace Swift {
 			void setRosterModel(Roster* roster);
 		private slots:
 			void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage);
+			void handleUIEvent(boost::shared_ptr<UIEvent> event);
 			void handleShowOfflineToggled(bool);
 			void handleJoinMUCAction();
 			void handleSignOutAction();
@@ -59,6 +60,7 @@ namespace Swift {
 			QtTreeWidget* treeWidget_;
 			QtRosterHeader* meView_;
 			QAction* addAction_;
+			QAction* showOfflineAction_;
 			QtTabWidget* tabs_;
 			QWidget* contactsTabWidget_;
 			QWidget* eventsTabWidget_;
@@ -66,6 +68,7 @@ namespace Swift {
 			QtChatListWindow* chatListWindow_;
 			UIEventStream* uiEventStream_;
 			QtRosterContextMenu* contextMenu_;
+			bool lastOfflineState_;
 	};
 }
 
-- 
cgit v0.10.2-6-g49f6