From 42b9cb3130a23524487bb3fa2e818da8b82880c7 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Thu, 28 Apr 2011 09:28:26 +0100
Subject: Recent chats are now persisted.

Release-Notes: A list of recent chats is now kept in the 'Chats' tab of the main window.

Resolves: #181

diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index 4ac814b..566d075 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index bd917e7..b60f9a3 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -7,6 +7,7 @@
 #include "Swift/Controllers/Chat/ChatsManager.h"
 
 #include <boost/bind.hpp>
+#include <boost/algorithm/string.hpp>
 
 #include <Swiften/Base/foreach.h>
 #include "Swift/Controllers/Chat/ChatController.h"
@@ -27,12 +28,15 @@
 #include "Swiften/MUC/MUCManager.h"
 #include "Swiften/Elements/ChatState.h"
 #include "Swiften/MUC/MUCBookmarkManager.h"
+#include <Swift/Controllers/ProfileSettingsProvider.h>
 
 namespace Swift {
 
 typedef std::pair<JID, ChatController*> JIDChatControllerPair;
 typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
 
+#define RECENT_CHATS "recent_chats"
+
 ChatsManager::ChatsManager(
 		JID jid, StanzaChannel* stanzaChannel, 
 		IQRouter* iqRouter, 
@@ -50,7 +54,7 @@ ChatsManager::ChatsManager(
 		EntityCapsProvider* entityCapsProvider, 
 		MUCManager* mucManager,
 		MUCSearchWindowFactory* mucSearchWindowFactory,
-		SettingsProvider* settings) : 
+		ProfileSettingsProvider* settings) :
 			jid_(jid), 
 			joinMUCWindowFactory_(joinMUCWindowFactory), 
 			useDelayForLatency_(useDelayForLatency), 
@@ -69,6 +73,7 @@ ChatsManager::ChatsManager(
 	presenceSender_ = presenceSender;
 	uiEventStream_ = uiEventStream;
 	mucBookmarkManager_ = NULL;
+	profileSettings_ = settings;
 	presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1));
 	uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1));
 	chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_);
@@ -76,6 +81,7 @@ ChatsManager::ChatsManager(
 	mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, settings);
 	mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1));
 	setupBookmarks();
+	loadRecents();
 }
 
 ChatsManager::~ChatsManager() {
@@ -90,6 +96,44 @@ ChatsManager::~ChatsManager() {
 	delete mucSearchController_;
 }
 
+void ChatsManager::saveRecents() {
+	std::string recents;
+	foreach (ChatListWindow::Chat chat, recentChats_) {
+		std::vector<std::string> activity;
+		boost::split(activity, chat.activity, boost::is_any_of("\t\n"));
+		std::string recent = chat.jid.toString() + "\t" + activity[0] + "\t" + (chat.isMUC ? "true" : "false") +  "\t" + chat.nick;
+		recents += recent + "\n";
+	}
+	profileSettings_->storeString(RECENT_CHATS, recents);
+}
+
+void ChatsManager::loadRecents() {
+	std::string recentsString(profileSettings_->getStringSetting(RECENT_CHATS));
+	std::vector<std::string> recents;
+	boost::split(recents, recentsString, boost::is_any_of("\n"));
+	int i = 0;
+	foreach (std::string recentString, recents) {
+		if (i++ > 30) {
+			break;
+		}
+		std::vector<std::string> recent;
+		boost::split(recent, recentString, boost::is_any_of("\t"));
+		if (recent.size() < 4) {
+			continue;
+		}
+		JID jid(recent[0]);
+		if (!jid.isValid()) {
+			continue;
+		}
+		std::string activity(recent[1]);
+		bool isMUC = recent[2] == "true";
+		std::string nick(recent[3]);
+		ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, isMUC, nick);
+		recentChats_.push_back(chat);
+		chatListWindow_->setRecents(recentChats_);
+	}
+}
+
 void ChatsManager::setupBookmarks() {
 	if (!mucBookmarkManager_) {
 		mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_);
@@ -130,6 +174,7 @@ void ChatsManager::handleChatActivity(const JID& jid, const std::string& activit
 	recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end());
 	recentChats_.push_front(chat);
 	chatListWindow_->setRecents(recentChats_);
+	saveRecents();
 }
 
 void ChatsManager::handleUserLeftMUC(MUCController* mucController) {
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 617f0c1..f489034 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -40,12 +40,12 @@ namespace Swift {
 	class EntityCapsProvider;
 	class DirectedPresenceSender;
 	class MUCSearchWindowFactory;
-	class SettingsProvider;
+	class ProfileSettingsProvider;
 	class MUCSearchController;
 
 	class ChatsManager {
 		public:
-			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, SettingsProvider* settings);
+			ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* settings);
 			virtual ~ChatsManager();
 			void setAvatarManager(AvatarManager* avatarManager);
 			void setOnline(bool enabled);
@@ -97,5 +97,6 @@ namespace Swift {
 			MUCManager* mucManager;
 			MUCSearchController* mucSearchController_;
 			std::list<ChatListWindow::Chat> recentChats_;
+			ProfileSettingsProvider* profileSettings_;
 	};
 }
diff --git a/Swift/Controllers/Chat/MUCSearchController.cpp b/Swift/Controllers/Chat/MUCSearchController.cpp
index 2d5c7e7..2cb89b4 100644
--- a/Swift/Controllers/Chat/MUCSearchController.cpp
+++ b/Swift/Controllers/Chat/MUCSearchController.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -24,7 +24,7 @@ namespace Swift {
 
 static const std::string SEARCHED_SERVICES = "searchedServices";
 
-MUCSearchController::MUCSearchController(const JID& jid, MUCSearchWindowFactory* factory, IQRouter* iqRouter, SettingsProvider* settings) : jid_(jid), factory_(factory), iqRouter_(iqRouter), settings_(settings), window_(NULL), walker_(NULL) {
+MUCSearchController::MUCSearchController(const JID& jid, MUCSearchWindowFactory* factory, IQRouter* iqRouter, ProfileSettingsProvider* settings) : jid_(jid), factory_(factory), iqRouter_(iqRouter), settings_(settings), window_(NULL), walker_(NULL) {
 	itemsInProgress_ = 0;
 	loadSavedServices();
 }
diff --git a/Swift/Controllers/Chat/MUCSearchController.h b/Swift/Controllers/Chat/MUCSearchController.h
index c8040ed..f90e4a7 100644
--- a/Swift/Controllers/Chat/MUCSearchController.h
+++ b/Swift/Controllers/Chat/MUCSearchController.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -16,7 +16,7 @@
 #include "Swiften/JID/JID.h"
 
 #include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swift/Controllers/Settings/SettingsProvider.h"
+#include "Swift/Controllers/ProfileSettingsProvider.h"
 #include "Swiften/Elements/DiscoInfo.h"
 #include "Swiften/Elements/DiscoItems.h"
 #include "Swiften/Elements/ErrorPayload.h"
@@ -87,7 +87,7 @@ namespace Swift {
 
 	class MUCSearchController {
 		public:
-			MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, SettingsProvider* settings);
+			MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, ProfileSettingsProvider* settings);
 			~MUCSearchController();
 
 			void openSearchWindow();
@@ -112,7 +112,7 @@ namespace Swift {
 			JID jid_;
 			MUCSearchWindowFactory* factory_;
 			IQRouter* iqRouter_;
-			SettingsProvider* settings_;
+			ProfileSettingsProvider* settings_;
 			MUCSearchWindow* window_;
 			DiscoServiceWalker* walker_;
 			std::list<JID> services_;
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index c266134..f8fda9a 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -39,6 +39,7 @@
 #include "Swift/Controllers/UIEvents/RequestChatUIEvent.h"
 #include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
 #include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include <Swift/Controllers/ProfileSettingsProvider.h>
 
 
 using namespace Swift;
@@ -83,9 +84,10 @@ public:
 		chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
 		mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>();
 		settings_ = new DummySettingsProvider();
+		profileSettings_ = new ProfileSettingsProvider("a", settings_);
 		chatListWindow_ = new MockChatListWindow();
 		mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_);
-		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, settings_);
+		manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_);
 
 		avatarManager_ = new NullAvatarManager();
 		manager_->setAvatarManager(avatarManager_);
@@ -94,6 +96,7 @@ public:
 	void tearDown() {
 		//delete chatListWindowFactory_;
 		delete settings_;
+		delete profileSettings_;
 		delete mocks_;
 		delete avatarManager_;
 		delete manager_;
@@ -349,6 +352,7 @@ private:
 	CapsProvider* capsProvider_;
 	MUCManager* mucManager_;
 	DummySettingsProvider* settings_;
+	ProfileSettingsProvider* profileSettings_;
 	ChatListWindow* chatListWindow_;
 };
 
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 63cac11..737839f 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -253,7 +253,7 @@ void MainController::handleConnected() {
 
 		contactEditController_ = new ContactEditController(rosterController_, uiFactory_, uiEventStream_);
 
-		chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, settings_);
+		chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_);
 		client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
 		chatsManager_->setAvatarManager(client_->getAvatarManager());
 
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index ae69e70..757abb8 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
diff --git a/Swift/QtUI/ChatList/ChatListGroupItem.h b/Swift/QtUI/ChatList/ChatListGroupItem.h
index 2fb2284..a1e479f 100644
--- a/Swift/QtUI/ChatList/ChatListGroupItem.h
+++ b/Swift/QtUI/ChatList/ChatListGroupItem.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
diff --git a/Swift/QtUI/ChatList/ChatListModel.cpp b/Swift/QtUI/ChatList/ChatListModel.cpp
index dc60d65..681c1c2 100644
--- a/Swift/QtUI/ChatList/ChatListModel.cpp
+++ b/Swift/QtUI/ChatList/ChatListModel.cpp
@@ -12,11 +12,11 @@
 namespace Swift {
 
 ChatListModel::ChatListModel() {
-	root_ = new ChatListGroupItem("", NULL);
+	root_ = new ChatListGroupItem("", NULL, false);
 	mucBookmarks_ = new ChatListGroupItem(tr("Bookmarked Rooms"), root_);
 	recents_ = new ChatListGroupItem(tr("Recent Chats"), root_, false);
-	root_->addItem(mucBookmarks_);
 	root_->addItem(recents_);
+	root_->addItem(mucBookmarks_);
 }
 
 void ChatListModel::clearBookmarks() {
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp
index a3dbd78..d71563d 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.cpp
+++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp
@@ -70,18 +70,24 @@ void QtChatListWindow::setupContextMenus() {
 }
 
 void QtChatListWindow::handleItemActivated(const QModelIndex& index) {
-	if (!bookmarksEnabled_) {
-		return;
-	}
 	ChatListItem* item = model_->getItemForIndex(index);
 	ChatListMUCItem* mucItem = dynamic_cast<ChatListMUCItem*>(item);
-	if (mucItem) {
+	if (bookmarksEnabled_ && mucItem) {
 		boost::shared_ptr<UIEvent> event(new JoinMUCUIEvent(mucItem->getBookmark().getRoom(), mucItem->getBookmark().getNick()));
 		eventStream_->send(event);
 	}
 	ChatListRecentItem* recentItem = dynamic_cast<ChatListRecentItem*>(item);
 	if (recentItem) {
-		boost::shared_ptr<UIEvent> event(new RequestChatUIEvent(recentItem->getChat().jid));
+		boost::shared_ptr<UIEvent> event;
+		if (recentItem->getChat().isMUC) {
+			if (!bookmarksEnabled_) {
+				return;
+			}
+			return;
+		}
+		else {
+			event = boost::shared_ptr<UIEvent>(new RequestChatUIEvent(recentItem->getChat().jid));
+		}
 		eventStream_->send(event);
 	}
 }
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index f7dba58..a4606f9 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -21,21 +21,25 @@
 #include <QAction>
 #include <QTabWidget>
 
-#include "QtSwiftUtil.h"
-#include "QtTabWidget.h"
-#include "Roster/QtTreeWidget.h"
-#include "Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h"
-#include "Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h"
-#include "Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h"
-#include "Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h"
-#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
-#include "Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h"
-#include "Swift/Controllers/UIEvents/RequestAdHocUIEvent.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtTabWidget.h>
+#include <Swift/QtUI/QtSettingsProvider.h>
+#include <Roster/QtTreeWidget.h>
+#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h>
+#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestAdHocUIEvent.h>
 
 namespace Swift {
 
+#define CURRENT_ROSTER_TAB "current_roster_tab"
+
 QtMainWindow::QtMainWindow(QtSettingsProvider* settings, UIEventStream* uiEventStream) : QWidget(), MainWindow(false) {
 	uiEventStream_ = uiEventStream;
+	settings_ = settings;
 	setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
 	QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
 	mainLayout->setContentsMargins(0,0,0,0);
@@ -69,8 +73,12 @@ QtMainWindow::QtMainWindow(QtSettingsProvider* settings, UIEventStream* uiEventS
 
 	chatListWindow_ = new QtChatListWindow(uiEventStream_);
 
-	tabs_->addTab(eventWindow_, tr("&Notices"));
 	tabs_->addTab(chatListWindow_, tr("C&hats"));
+	tabs_->addTab(eventWindow_, tr("&Notices"));
+
+	tabs_->setCurrentIndex(settings_->getIntSetting(CURRENT_ROSTER_TAB, 0));
+
+	connect(tabs_, SIGNAL(currentChanged(int)), this, SLOT(handleTabChanged(int)));
 
 	this->setLayout(mainLayout);
 
@@ -123,6 +131,10 @@ QtMainWindow::~QtMainWindow() {
 	uiEventStream_->onUIEvent.disconnect(boost::bind(&QtMainWindow::handleUIEvent, this, _1));
 }
 
+void QtMainWindow::handleTabChanged(int index) {
+	settings_->storeInt(CURRENT_ROSTER_TAB, index);
+}
+
 QtEventWindow* QtMainWindow::getEventWindow() {
 	return eventWindow_;
 }
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index e20d773..5c29f6d 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2011 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -60,8 +60,10 @@ namespace Swift {
 			void handleAdHocActionTriggered(bool checked);
 			void handleEventCountUpdated(int count);
 			void handleEditProfileRequest();
+			void handleTabChanged(int index);
 
 		private:
+			QtSettingsProvider* settings_;
 			std::vector<QMenu*> menus_;
 			QtTreeWidget* treeWidget_;
 			QtRosterHeader* meView_;
-- 
cgit v0.10.2-6-g49f6