summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-12-17 13:21:14 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-01-30 15:10:02 (GMT)
commitb897bac235a95f9c4654b31d101779bd0cc8f72f (patch)
tree8d00b3ab58ec200adf670e01671eed91876b485d /Swift/Controllers
parent869c52b244c2d03313e9eda83fac05bf0fc3a619 (diff)
downloadswift-contrib-b897bac235a95f9c4654b31d101779bd0cc8f72f.zip
swift-contrib-b897bac235a95f9c4654b31d101779bd0cc8f72f.tar.bz2
Added profile edit dialog.
Resolves: #141, #587.
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/MainController.cpp10
-rw-r--r--Swift/Controllers/MainController.h2
-rw-r--r--Swift/Controllers/ProfileController.cpp90
-rw-r--r--Swift/Controllers/ProfileController.h44
-rw-r--r--Swift/Controllers/RosterController.cpp11
-rw-r--r--Swift/Controllers/RosterController.h3
-rw-r--r--Swift/Controllers/SConscript1
-rw-r--r--Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h16
-rw-r--r--Swift/Controllers/UIEvents/UIEvent.h4
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindow.h1
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindow.h30
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindowFactory.h18
-rw-r--r--Swift/Controllers/UIInterfaces/UIFactory.h4
13 files changed, 232 insertions, 2 deletions
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index f07a964..d7e1941 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -61,6 +61,7 @@
#include "Swift/Controllers/CertificateStorageFactory.h"
#include "Swift/Controllers/CertificateStorageTrustChecker.h"
#include "Swiften/Network/NetworkFactories.h"
+#include <Swift/Controllers/ProfileController.h>
namespace Swift {
@@ -98,6 +99,7 @@ MainController::MainController(
rosterController_ = NULL;
chatsManager_ = NULL;
eventWindowController_ = NULL;
+ profileController_ = NULL;
userSearchControllerChat_ = NULL;
userSearchControllerAdd_ = NULL;
quitRequested_ = false;
@@ -170,6 +172,8 @@ MainController::~MainController() {
void MainController::resetClient() {
resetCurrentError();
resetPendingReconnects();
+ delete profileController_;
+ profileController_ = NULL;
delete eventWindowController_;
eventWindowController_ = NULL;
delete chatsManager_;
@@ -228,6 +232,8 @@ void MainController::handleConnected() {
bool freshLogin = rosterController_ == NULL;
myStatusLooksOnline_ = true;
if (freshLogin) {
+ profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
+
rosterController_ = new RosterController(jid_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_);
rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
@@ -261,6 +267,7 @@ void MainController::handleConnected() {
client_->getVCardManager()->requestOwnVCard();
rosterController_->setEnabled(true);
+ profileController_->setAvailable(true);
/* Send presence later to catch all the incoming presences. */
sendPresence(statusTracker_->getNextPresence());
/* Enable chats last of all, so rejoining MUCs has the right sent presence */
@@ -522,6 +529,9 @@ void MainController::setManagersOffline() {
if (rosterController_) {
rosterController_->setEnabled(false);
}
+ if (profileController_) {
+ profileController_->setAvailable(false);
+ }
}
void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error) {
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index a933a5a..d6e54ef 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -42,6 +42,7 @@ namespace Swift {
class EventLoop;
class MUCController;
class Notifier;
+ class ProfileController;
class TogglableNotifier;
class PresenceNotifier;
class EventNotifier;
@@ -130,6 +131,7 @@ namespace Swift {
UIEventStream* uiEventStream_;
XMLConsoleController* xmlConsoleController_;
ChatsManager* chatsManager_;
+ ProfileController* profileController_;
JID jid_;
JID boundJID_;
SystemTrayController* systemTrayController_;
diff --git a/Swift/Controllers/ProfileController.cpp b/Swift/Controllers/ProfileController.cpp
new file mode 100644
index 0000000..9667d89
--- /dev/null
+++ b/Swift/Controllers/ProfileController.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/ProfileController.h>
+
+#include <boost/bind.hpp>
+
+#include <Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIInterfaces/ProfileWindowFactory.h>
+#include <Swiften/VCards/VCardManager.h>
+
+
+namespace Swift {
+
+ProfileController::ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream), available(true), profileWindow(NULL), gettingVCard(false) {
+ uiEventStream->onUIEvent.connect(boost::bind(&ProfileController::handleUIEvent, this, _1));
+}
+
+ProfileController::~ProfileController() {
+ if (profileWindow) {
+ vcardManager->onOwnVCardChanged.disconnect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
+ profileWindow->onVCardChangeRequest.disconnect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
+ delete profileWindow;
+ }
+ uiEventStream->onUIEvent.disconnect(boost::bind(&ProfileController::handleUIEvent, this, _1));
+}
+
+void ProfileController::handleUIEvent(UIEvent::ref event) {
+ if (!boost::dynamic_pointer_cast<RequestProfileEditorUIEvent>(event)) {
+ return;
+ }
+
+ if (!profileWindow) {
+ profileWindow = profileWindowFactory->createProfileWindow();
+ profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
+ vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
+ }
+ gettingVCard = true;
+ updateDialogStatus();
+ vcardManager->requestOwnVCard();
+ profileWindow->show();
+}
+
+void ProfileController::handleVCardChangeRequest(VCard::ref vcard) {
+ assert(!pendingSetVCardRequest);
+ profileWindow->setError("");
+ pendingSetVCardRequest = vcardManager->createSetVCardRequest(vcard);
+ pendingSetVCardRequest->onResponse.connect(boost::bind(&ProfileController::handleSetVCardResponse, this, _2));
+ pendingSetVCardRequest->send();
+ updateDialogStatus();
+}
+
+void ProfileController::handleSetVCardResponse(ErrorPayload::ref error) {
+ pendingSetVCardRequest.reset();
+ updateDialogStatus();
+ if (error) {
+ profileWindow->setError("There was an error publishing your profile data");
+ }
+ else {
+ profileWindow->setError("");
+ profileWindow->hide();
+ }
+}
+
+void ProfileController::handleOwnVCardChanged(VCard::ref vcard) {
+ if (profileWindow) {
+ profileWindow->setVCard(vcard);
+ gettingVCard = false;
+ updateDialogStatus();
+ }
+}
+
+void ProfileController::setAvailable(bool b) {
+ available = b;
+ updateDialogStatus();
+}
+
+
+void ProfileController::updateDialogStatus() {
+ if (profileWindow) {
+ profileWindow->setEnabled(available && !gettingVCard && !pendingSetVCardRequest);
+ profileWindow->setProcessing(gettingVCard || pendingSetVCardRequest);
+ }
+}
+
+}
diff --git a/Swift/Controllers/ProfileController.h b/Swift/Controllers/ProfileController.h
new file mode 100644
index 0000000..c1afcf9
--- /dev/null
+++ b/Swift/Controllers/ProfileController.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+#include <Swiften/Elements/VCard.h>
+#include <Swiften/Elements/ErrorPayload.h>
+#include <Swiften/VCards/SetVCardRequest.h>
+
+namespace Swift {
+ class UIEventStream;
+ class ProfileWindowFactory;
+ class ProfileWindow;
+ class VCardManager;
+
+ class ProfileController {
+ public:
+ ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
+ ~ProfileController();
+
+ void setAvailable(bool b);
+
+ private:
+ void handleUIEvent(UIEvent::ref event);
+ void handleVCardChangeRequest(VCard::ref vcard);
+ void handleSetVCardResponse(ErrorPayload::ref);
+ void handleOwnVCardChanged(VCard::ref vcard);
+ void updateDialogStatus();
+
+ private:
+ VCardManager* vcardManager;
+ ProfileWindowFactory* profileWindowFactory;
+ UIEventStream* uiEventStream;
+ bool available;
+ SetVCardRequest::ref pendingSetVCardRequest;
+ ProfileWindow* profileWindow;
+ bool gettingVCard;
+ };
+}
+
diff --git a/Swift/Controllers/RosterController.cpp b/Swift/Controllers/RosterController.cpp
index 282f041..0f149f6 100644
--- a/Swift/Controllers/RosterController.cpp
+++ b/Swift/Controllers/RosterController.cpp
@@ -7,6 +7,7 @@
#include "Swift/Controllers/RosterController.h"
#include <boost/bind.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
#include "Swiften/Base/foreach.h"
#include "Swift/Controllers/UIInterfaces/MainWindow.h"
@@ -32,6 +33,7 @@
#include "Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h"
#include "Swift/Controllers/UIEvents/RegroupRosterItemUIEvent.h"
#include "Swift/Controllers/UIEvents/ToggleShowOfflineUIEvent.h"
+#include "Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h"
#include <Swiften/Client/NickManager.h>
namespace Swift {
@@ -42,7 +44,7 @@ static const String SHOW_OFFLINE = "showOffline";
* The controller does not gain ownership of these parameters.
*/
RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings)
- : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver) {
+ : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream) {
iqRouter_ = iqRouter;
presenceOracle_ = presenceOracle;
subscriptionManager_ = subscriptionManager;
@@ -54,6 +56,7 @@ RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, Avata
changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));
signOutConnection_ = mainWindow_->onSignOutRequest.connect(boost::bind(boost::ref(onSignOutRequest)));
+ mainWindow_->onEditProfileRequest.connect(boost::bind(&RosterController::handleEditProfileRequest, this));
xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1));
xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3));
xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1));
@@ -79,6 +82,8 @@ RosterController::~RosterController() {
delete offlineFilter_;
delete expandiness_;
+
+ mainWindow_->onEditProfileRequest.disconnect(boost::bind(&RosterController::handleEditProfileRequest, this));
mainWindow_->setRosterModel(NULL);
if (mainWindow_->canDelete()) {
delete mainWindow_;
@@ -280,4 +285,8 @@ void RosterController::handleAvatarChanged(const JID& jid) {
}
}
+void RosterController::handleEditProfileRequest() {
+ uiEventStream_->onUIEvent(boost::make_shared<RequestProfileEditorUIEvent>());
+}
+
}
diff --git a/Swift/Controllers/RosterController.h b/Swift/Controllers/RosterController.h
index 79c14b9..9e22686 100644
--- a/Swift/Controllers/RosterController.h
+++ b/Swift/Controllers/RosterController.h
@@ -60,6 +60,8 @@ namespace Swift {
void handleUIEvent(boost::shared_ptr<UIEvent> event);
void handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload);
void applyAllPresenceTo(const JID& jid);
+ void handleEditProfileRequest();
+
JID myJID_;
XMPPRoster* xmppRoster_;
MainWindowFactory* mainWindowFactory_;
@@ -75,6 +77,7 @@ namespace Swift {
RosterGroupExpandinessPersister* expandiness_;
IQRouter* iqRouter_;
SettingsProvider* settings_;
+ UIEventStream* uiEventStream_;
boost::bsignals::scoped_connection changeStatusConnection_;
boost::bsignals::scoped_connection signOutConnection_;
boost::bsignals::scoped_connection uiEventConnection_;
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 96674bd..b149cd2 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -29,6 +29,7 @@ if env["SCONS_STAGE"] == "build" :
"Chat/UserSearchController.cpp",
"DiscoServiceWalker.cpp",
"MainController.cpp",
+ "ProfileController.cpp",
"RosterController.cpp",
"RosterGroupExpandinessPersister.cpp",
"EventWindowController.cpp",
diff --git a/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h
new file mode 100644
index 0000000..107e2e8
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * 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 RequestProfileEditorUIEvent : public UIEvent {
+ public:
+ RequestProfileEditorUIEvent() {}
+ };
+}
diff --git a/Swift/Controllers/UIEvents/UIEvent.h b/Swift/Controllers/UIEvents/UIEvent.h
index ab57634..e79a4f1 100644
--- a/Swift/Controllers/UIEvents/UIEvent.h
+++ b/Swift/Controllers/UIEvents/UIEvent.h
@@ -6,9 +6,13 @@
#pragma once
+#include <boost/shared_ptr.hpp>
+
namespace Swift {
class UIEvent {
public:
+ typedef boost::shared_ptr<UIEvent> ref;
+
virtual ~UIEvent();
};
}
diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h
index 125aae5..55087fe 100644
--- a/Swift/Controllers/UIInterfaces/MainWindow.h
+++ b/Swift/Controllers/UIInterfaces/MainWindow.h
@@ -36,6 +36,7 @@ namespace Swift {
boost::signal<void (StatusShow::Type, const String&)> onChangeStatusRequest;
boost::signal<void ()> onSignOutRequest;
+ boost::signal<void ()> onEditProfileRequest;
private:
bool canDelete_;
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindow.h b/Swift/Controllers/UIInterfaces/ProfileWindow.h
new file mode 100644
index 0000000..e9c9a63
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/ProfileWindow.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <boost/shared_ptr.hpp>
+
+#include <Swiften/Elements/VCard.h>
+
+namespace Swift {
+ class ProfileWindow {
+ public:
+ virtual ~ProfileWindow() {};
+
+ virtual void setVCard(VCard::ref vcard) = 0;
+
+ virtual void setEnabled(bool b) = 0;
+ virtual void setProcessing(bool b) = 0;
+ virtual void setError(const String&) = 0;
+
+ virtual void show() = 0;
+ virtual void hide() = 0;
+
+ boost::signal<void (VCard::ref)> onVCardChangeRequest;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
new file mode 100644
index 0000000..022c3eb
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/UIInterfaces/ProfileWindow.h>
+
+namespace Swift {
+ class ProfileWindowFactory {
+ public:
+ virtual ~ProfileWindowFactory() {};
+
+ virtual ProfileWindow* createProfileWindow() = 0;
+ };
+}
diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h
index 4783dc8..11623d7 100644
--- a/Swift/Controllers/UIInterfaces/UIFactory.h
+++ b/Swift/Controllers/UIInterfaces/UIFactory.h
@@ -15,6 +15,7 @@
#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h>
+#include <Swift/Controllers/UIInterfaces/ProfileWindowFactory.h>
namespace Swift {
class UIFactory :
@@ -26,7 +27,8 @@ namespace Swift {
public MUCSearchWindowFactory,
public XMLConsoleWidgetFactory,
public UserSearchWindowFactory,
- public JoinMUCWindowFactory {
+ public JoinMUCWindowFactory,
+ public ProfileWindowFactory {
public:
virtual ~UIFactory() {}
};