diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-12-17 13:21:14 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-01-30 15:10:02 (GMT) |
commit | b897bac235a95f9c4654b31d101779bd0cc8f72f (patch) | |
tree | 8d00b3ab58ec200adf670e01671eed91876b485d /Swift/Controllers | |
parent | 869c52b244c2d03313e9eda83fac05bf0fc3a619 (diff) | |
download | swift-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.cpp | 10 | ||||
-rw-r--r-- | Swift/Controllers/MainController.h | 2 | ||||
-rw-r--r-- | Swift/Controllers/ProfileController.cpp | 90 | ||||
-rw-r--r-- | Swift/Controllers/ProfileController.h | 44 | ||||
-rw-r--r-- | Swift/Controllers/RosterController.cpp | 11 | ||||
-rw-r--r-- | Swift/Controllers/RosterController.h | 3 | ||||
-rw-r--r-- | Swift/Controllers/SConscript | 1 | ||||
-rw-r--r-- | Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h | 16 | ||||
-rw-r--r-- | Swift/Controllers/UIEvents/UIEvent.h | 4 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/MainWindow.h | 1 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ProfileWindow.h | 30 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ProfileWindowFactory.h | 18 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/UIFactory.h | 4 |
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() {} }; |