summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2010-10-02 08:53:43 (GMT)
committerKevin Smith <git@kismith.co.uk>2010-10-02 09:02:15 (GMT)
commit087bc243ffb53e3273580bce5ce66305841a3bff (patch)
treea09a7fd1d564f0e7164198c501d95c949f20b8dd
parent2fb3d3266bd22d84604688dc9ee18b17b211b91d (diff)
downloadswift-087bc243ffb53e3273580bce5ce66305841a3bff.zip
swift-087bc243ffb53e3273580bce5ce66305841a3bff.tar.bz2
Persist roster group expandiness.
Release-Notes: Whether roster groups are expanded or collapsed is now persisted between sessions. Resolves: #399
-rw-r--r--Swift/Controllers/MainController.cpp2
-rw-r--r--Swift/Controllers/RosterController.cpp5
-rw-r--r--Swift/Controllers/RosterController.h5
-rw-r--r--Swift/Controllers/RosterGroupExpandinessPersister.cpp60
-rw-r--r--Swift/Controllers/RosterGroupExpandinessPersister.h27
-rw-r--r--Swift/Controllers/SConscript1
-rw-r--r--Swift/Controllers/UnitTest/RosterControllerTest.cpp6
-rw-r--r--Swiften/Roster/GroupRosterItem.cpp4
-rw-r--r--Swiften/Roster/GroupRosterItem.h1
-rw-r--r--Swiften/Settings/DummySettingsProvider.h29
10 files changed, 135 insertions, 5 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 7ff3ed0..9915da9 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -255,7 +255,7 @@ void MainController::handleConnected() {
if (freshLogin) {
serverDiscoInfo_ = boost::shared_ptr<DiscoInfo>(new DiscoInfo());
- rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, eventController_, uiEventStream_, client_->getIQRouter());
+ rosterController_ = new RosterController(jid_, xmppRoster_, 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));
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index 79cf3b8..5288df1 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -37,12 +37,13 @@ namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter)
+RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings)
: myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()) {
iqRouter_ = iqRouter;
presenceOracle_ = presenceOracle;
presenceSender_ = presenceSender;
eventController_ = eventController;
+ expandiness_ = new RosterGroupExpandinessPersister(roster_, settings);
roster_->addFilter(offlineFilter_);
mainWindow_->setRosterModel(roster_);
@@ -65,7 +66,7 @@ RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, Avata
RosterController::~RosterController() {
delete offlineFilter_;
-
+ delete expandiness_;
}
void RosterController::setNickResolver(NickResolver* nickResolver) {
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index 80e7e3e..3cb3812 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -14,6 +14,7 @@
#include "Swiften/Elements/RosterPayload.h"
#include "Swiften/Avatars/AvatarManager.h"
#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include "Swift/Controllers/RosterGroupExpandinessPersister.h"
#include "Swiften/Base/boost_bsignals.h"
#include <boost/shared_ptr.hpp>
@@ -32,10 +33,11 @@ namespace Swift {
class SubscriptionRequestEvent;
class UIEventStream;
class IQRouter;
+ class SettingsProvider;
class RosterController {
public:
- RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_);
+ RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings);
~RosterController();
void showRosterWindow();
MainWindow* getWindow() {return mainWindow_;};
@@ -70,6 +72,7 @@ namespace Swift {
PresenceOracle* presenceOracle_;
PresenceSender* presenceSender_;
EventController* eventController_;
+ RosterGroupExpandinessPersister* expandiness_;
IQRouter* iqRouter_;
boost::bsignals::scoped_connection changeStatusConnection_;
boost::bsignals::scoped_connection showOfflineConnection_;
diff --git a/Swift/Controllers/RosterGroupExpandinessPersister.cpp b/Swift/Controllers/RosterGroupExpandinessPersister.cpp
new file mode 100644
index 0000000..a6a998a
--- /dev/null
+++ b/Swift/Controllers/RosterGroupExpandinessPersister.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Swift/Controllers/RosterGroupExpandinessPersister.h"
+
+#include <boost/bind.hpp>
+#include <vector>
+
+#include "Swiften/Roster/GroupRosterItem.h"
+
+namespace Swift {
+
+RosterGroupExpandinessPersister::RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings) : roster_(roster), settings_(settings) {
+ load();
+ roster_->onGroupAdded.connect(boost::bind(&RosterGroupExpandinessPersister::handleGroupAdded, this, _1));
+}
+
+void RosterGroupExpandinessPersister::handleGroupAdded(GroupRosterItem* group) {
+ if (collapsed_.find(group->getDisplayName()) != collapsed_.end()) {
+ group->setExpanded(false);
+ } else {
+ group->setExpanded(true);
+ }
+ group->onExpandedChanged.connect(boost::bind(&RosterGroupExpandinessPersister::handleExpandedChanged, this, group, _1));
+}
+
+void RosterGroupExpandinessPersister::handleExpandedChanged(GroupRosterItem* group, bool expanded) {
+ if (expanded) {
+ collapsed_.erase(collapsed_.find(group->getDisplayName()));
+ } else {
+ collapsed_.insert(group->getDisplayName());
+ }
+ save();
+}
+
+void RosterGroupExpandinessPersister::save() {
+ String setting;
+ foreach (const String& group, collapsed_) {
+ if (setting.isEmpty()) {
+ setting += "\n";
+ }
+ setting += group;
+ }
+ settings_->storeString(SettingPath, setting);
+}
+
+void RosterGroupExpandinessPersister::load() {
+ String saved = settings_->getStringSetting(SettingPath);
+ std::vector<String> collapsed = saved.split('\n');
+ foreach (const String& group, collapsed) {
+ collapsed_.insert(group);
+ }
+}
+
+const String RosterGroupExpandinessPersister::SettingPath = "GroupExpandiness";
+
+}
diff --git a/Swift/Controllers/RosterGroupExpandinessPersister.h b/Swift/Controllers/RosterGroupExpandinessPersister.h
new file mode 100644
index 0000000..545c9d0
--- /dev/null
+++ b/Swift/Controllers/RosterGroupExpandinessPersister.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <set>
+#include "Swiften/Roster/Roster.h"
+#include "Swiften/Settings/SettingsProvider.h"
+
+namespace Swift {
+ class RosterGroupExpandinessPersister {
+ public:
+ RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings);
+ private:
+ void handleExpandedChanged(GroupRosterItem* group, bool expanded);
+ void handleGroupAdded(GroupRosterItem* group);
+ void load();
+ void save();
+ std::set<String> collapsed_;
+ Roster* roster_;
+ SettingsProvider* settings_;
+ static const String SettingPath;
+ };
+}
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index d37b370..dead16a 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -29,6 +29,7 @@ if env["SCONS_STAGE"] == "build" :
"MainController.cpp",
"NickResolver.cpp",
"RosterController.cpp",
+ "RosterGroupExpandinessPersister.cpp",
"EventWindowController.cpp",
"SoundEventController.cpp",
"SystemTrayController.cpp",
diff --git a/Swift/Controllers/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
index 4ecc4c8..dde48ed 100644
--- a/Swift/Controllers/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/UnitTest/RosterControllerTest.cpp
@@ -20,6 +20,7 @@
#include "Swiften/Roster/Roster.h"
#include "Swiften/Roster/GroupRosterItem.h"
#include "Swiften/Roster/ContactRosterItem.h"
+#include "Swiften/Settings/DummySettingsProvider.h"
#include "Swiften/Avatars/NullAvatarManager.h"
#include "Swift/Controllers/XMPPEvents/EventController.h"
#include "Swiften/Presence/PresenceOracle.h"
@@ -61,7 +62,8 @@ class RosterControllerTest : public CppUnit::TestFixture
presenceSender_ = new PresenceSender(stanzaChannel_);
eventController_ = new EventController();
uiEventStream_ = new UIEventStream();
- rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, eventController_, uiEventStream_, router_);
+ settings_ = new DummySettingsProvider();
+ rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickResolver_, presenceOracle_, presenceSender_, eventController_, uiEventStream_, router_, settings_);
mainWindow_ = mainWindowFactory_->last;
};
@@ -78,6 +80,7 @@ class RosterControllerTest : public CppUnit::TestFixture
delete presenceOracle_;
delete stanzaChannel_;
delete uiEventStream_;
+ delete settings_;
};
GroupRosterItem* groupChild(size_t i) {
@@ -206,6 +209,7 @@ class RosterControllerTest : public CppUnit::TestFixture
EventController* eventController_;
UIEventStream* uiEventStream_;
MockMainWindow* mainWindow_;
+ DummySettingsProvider* settings_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(RosterControllerTest);
diff --git a/Swiften/Roster/GroupRosterItem.cpp b/Swiften/Roster/GroupRosterItem.cpp
index aa9fdd4..325c890 100644
--- a/Swiften/Roster/GroupRosterItem.cpp
+++ b/Swiften/Roster/GroupRosterItem.cpp
@@ -31,7 +31,11 @@ bool GroupRosterItem::isExpanded() const {
to avoid a loop in this case.
*/
void GroupRosterItem::setExpanded(bool expanded) {
+ bool old = expanded_;
expanded_ = expanded;
+ if (expanded != old) {
+ onExpandedChanged(expanded);
+ }
}
const std::vector<RosterItem*>& GroupRosterItem::getChildren() const {
diff --git a/Swiften/Roster/GroupRosterItem.h b/Swiften/Roster/GroupRosterItem.h
index 67ced97..b306b59 100644
--- a/Swiften/Roster/GroupRosterItem.h
+++ b/Swiften/Roster/GroupRosterItem.h
@@ -29,6 +29,7 @@ class GroupRosterItem : public RosterItem {
static bool itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right);
void setExpanded(bool expanded);
bool isExpanded() const;
+ boost::signal<void (bool)> onExpandedChanged;
private:
void handleChildrenChanged(GroupRosterItem* group);
void handleDataChanged(RosterItem* item);
diff --git a/Swiften/Settings/DummySettingsProvider.h b/Swiften/Settings/DummySettingsProvider.h
new file mode 100644
index 0000000..33f02b7
--- /dev/null
+++ b/Swiften/Settings/DummySettingsProvider.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swiften/Settings/SettingsProvider.h"
+
+namespace Swift {
+
+class DummySettingsProvider : public SettingsProvider {
+ public:
+ virtual ~DummySettingsProvider() {}
+ virtual String getStringSetting(const String&) {return "";}
+ virtual void storeString(const String &, const String &) {}
+ virtual bool getBoolSetting(const String &, bool ) {return true;}
+ virtual void storeBool(const String &, bool ) {}
+ virtual int getIntSetting(const String &, int ) {return 0;}
+ virtual void storeInt(const String &, int ) {}
+ virtual std::vector<String> getAvailableProfiles() {return std::vector<String>();}
+ virtual void createProfile(const String& ) {}
+};
+
+}
+
+
+