diff options
| author | Richard Maudsley <richard.maudsley@isode.com> | 2014-06-27 16:06:49 (GMT) | 
|---|---|---|
| committer | Richard Maudsley <richard.maudsley@isode.com> | 2014-07-07 10:49:04 (GMT) | 
| commit | 14fd8e4363241e04b20da85dfc61e5f315e9b28d (patch) | |
| tree | b7a5450f73e98dd64c0367702575bb3f52e44ab4 /Swift/Controllers/Roster | |
| parent | 9179b54ac93ddc88765c3cd984916d7ffd130d20 (diff) | |
| download | swift-contrib-14fd8e4363241e04b20da85dfc61e5f315e9b28d.zip swift-contrib-14fd8e4363241e04b20da85dfc61e5f315e9b28d.tar.bz2  | |
Show own tooltip when hovering over roster header.
Test-Information:
Made combinations of presence/vcard/avatar changes and verified that the information in the tooltip was synchronized. Connect two clients and verify that the tooltip presence text reflects the local client presence only.
Change-Id: I92af0f58f7045f3a15f2fae2f9cbc6e24a066923
Diffstat (limited to 'Swift/Controllers/Roster')
| -rw-r--r-- | Swift/Controllers/Roster/RosterController.cpp | 30 | ||||
| -rw-r--r-- | Swift/Controllers/Roster/RosterController.h | 5 | 
2 files changed, 30 insertions, 5 deletions
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp index d2d024c..6bb5119 100644 --- a/Swift/Controllers/Roster/RosterController.cpp +++ b/Swift/Controllers/Roster/RosterController.cpp @@ -26,103 +26,109 @@  #include <Swiften/Roster/GetRosterRequest.h>  #include <Swiften/Roster/SetRosterRequest.h>  #include <Swiften/Roster/XMPPRoster.h>  #include <Swiften/Roster/XMPPRosterItem.h>  #include <Swift/Controllers/Intl.h>  #include <Swift/Controllers/Roster/GroupRosterItem.h>  #include <Swift/Controllers/Roster/OfflineRosterFilter.h>  #include <Swift/Controllers/Roster/Roster.h>  #include <Swift/Controllers/Roster/RosterVCardProvider.h>  #include <Swift/Controllers/Roster/ItemOperations/AppearOffline.h>  #include <Swift/Controllers/Roster/ItemOperations/SetAvatar.h>  #include <Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h>  #include <Swift/Controllers/Roster/ItemOperations/SetBlockingState.h>  #include <Swift/Controllers/Roster/ItemOperations/SetName.h>  #include <Swift/Controllers/Roster/ItemOperations/SetPresence.h>  #include <Swift/Controllers/Roster/ItemOperations/SetVCard.h>  #include <Swift/Controllers/SettingConstants.h>  #include <Swift/Controllers/UIEvents/AddContactUIEvent.h>  #include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h>  #include <Swift/Controllers/UIEvents/RenameGroupUIEvent.h>  #include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h>  #include <Swift/Controllers/UIEvents/SendFileUIEvent.h>  #include <Swift/Controllers/UIInterfaces/MainWindow.h>  #include <Swift/Controllers/UIInterfaces/MainWindowFactory.h>  #include <Swift/Controllers/XMPPEvents/ErrorEvent.h>  #include <Swift/Controllers/XMPPEvents/EventController.h>  #include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>  namespace Swift {  /**   * 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, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager) -	: myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), nickManager_(nickManager), nickResolver_(nickResolver), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), clientBlockListManager_(clientBlockListManager) { +	: myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), vcardManager_(vcardManager), avatarManager_(avatarManager), nickManager_(nickManager), nickResolver_(nickResolver), presenceOracle_(presenceOracle), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), clientBlockListManager_(clientBlockListManager) {  	assert(fileTransferOverview);  	iqRouter_ = iqRouter; -	presenceOracle_ = presenceOracle;  	subscriptionManager_ = subscriptionManager;  	eventController_ = eventController;  	settings_ = settings;  	expandiness_ = new RosterGroupExpandinessPersister(roster_, settings);  	mainWindow_->setRosterModel(roster_);  	rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithoutResource);  	changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));  	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));  	xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1));  	xmppRoster_->onRosterCleared.connect(boost::bind(&RosterController::handleRosterCleared, this));  	subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&RosterController::handleSubscriptionRequest, this, _1, _2));  	presenceOracle_->onPresenceChange.connect(boost::bind(&RosterController::handleIncomingPresence, this, _1));  	uiEventConnection_ = uiEventStream->onUIEvent.connect(boost::bind(&RosterController::handleUIEvent, this, _1)); -	avatarManager_ = avatarManager; + +	vcardManager_->onOwnVCardChanged.connect(boost::bind(&RosterController::handleOwnVCardChanged, this, _1));  	avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1)); -	mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_))); +	presenceOracle_->onPresenceChange.connect(boost::bind(&RosterController::handlePresenceChanged, this, _1)); +	mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare())));  	nickManager_->onOwnNickChanged.connect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1));  	mainWindow_->setMyJID(jid);  	mainWindow_->setMyNick(nickManager_->getOwnNick());  	entityCapsManager_->onCapsChanged.connect(boost::bind(&RosterController::handleOnCapsChanged, this, _1));  	settings_->onSettingChanged.connect(boost::bind(&RosterController::handleSettingChanged, this, _1));  	handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); + +	ownContact_ = boost::make_shared<ContactRosterItem>(myJID_.toBare(), myJID_.toBare(), nickManager_->getOwnNick(), (GroupRosterItem*)0); +	ownContact_->setVCard(vcardManager_->getVCard(myJID_.toBare())); +	ownContact_->setAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare()))); +	mainWindow_->setMyContactRosterItem(ownContact_);  }  RosterController::~RosterController() {	  	settings_->onSettingChanged.disconnect(boost::bind(&RosterController::handleSettingChanged, this, _1));  	nickManager_->onOwnNickChanged.disconnect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1));  	delete offlineFilter_;  	delete expandiness_;  	mainWindow_->setRosterModel(NULL);  	if (mainWindow_->canDelete()) {  		delete mainWindow_;  	}  	delete rosterVCardProvider_;  	delete roster_;	  }  void RosterController::setEnabled(bool enabled) {  	if (!enabled) {  		roster_->applyOnItems(AppearOffline());  	}  }  void RosterController::handleShowOfflineToggled(bool state) {  	if (state) {  		roster_->removeFilter(offlineFilter_);  	} else {  		roster_->addFilter(offlineFilter_);  	}  }  void RosterController::handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText) {  	onChangeStatusRequest(show, statusText);  } @@ -304,66 +310,80 @@ void RosterController::handleRosterSetError(ErrorPayload::ref error, boost::shar  	}  	boost::shared_ptr<ErrorEvent> errorEvent(new ErrorEvent(JID(myJID_.getDomain()), text));  	eventController_->handleIncomingEvent(errorEvent);  }  void RosterController::handleIncomingPresence(Presence::ref newPresence) {  	if (newPresence->getType() == Presence::Error) {  		return;  	}  	roster_->applyOnItems(SetPresence(newPresence));  }  void RosterController::handleSubscriptionRequest(const JID& jid, const std::string& message) {  	if (xmppRoster_->containsJID(jid) && (xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::To || xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::Both)) {  		subscriptionManager_->confirmSubscription(jid);  		return;  	}  	SubscriptionRequestEvent* eventPointer = new SubscriptionRequestEvent(jid, message);  	eventPointer->onAccept.connect(boost::bind(&RosterController::handleSubscriptionRequestAccepted, this, eventPointer));  	eventPointer->onDecline.connect(boost::bind(&RosterController::handleSubscriptionRequestDeclined, this, eventPointer));  	boost::shared_ptr<StanzaEvent> event(eventPointer);  	eventController_->handleIncomingEvent(event);  }  void RosterController::handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event) {  	subscriptionManager_->confirmSubscription(event->getJID());  	if (!xmppRoster_->containsJID(event->getJID()) || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::None || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::From) {  		subscriptionManager_->requestSubscription(event->getJID());  	}  }  void RosterController::handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event) {  	subscriptionManager_->cancelSubscription(event->getJID());  } +void RosterController::handleOwnVCardChanged(VCard::ref vcard) { +	ownContact_->setVCard(vcard); +	mainWindow_->setMyContactRosterItem(ownContact_); +} +  void RosterController::handleAvatarChanged(const JID& jid) {  	boost::filesystem::path path = avatarManager_->getAvatarPath(jid);  	roster_->applyOnItems(SetAvatar(jid, path)); -	if (jid.equals(myJID_, JID::WithoutResource)) { +	if (jid.equals(myJID_, JID::WithResource)) {  		mainWindow_->setMyAvatarPath(pathToString(path));  	} +	ownContact_->setAvatarPath(pathToString(path)); +	mainWindow_->setMyContactRosterItem(ownContact_); +} + +void RosterController::handlePresenceChanged(Presence::ref presence) { +	if (presence->getFrom().equals(myJID_, JID::WithResource)) { +		ownContact_->applyPresence(std::string(), presence); +		mainWindow_->setMyContactRosterItem(ownContact_); +	}  }  boost::optional<XMPPRosterItem> RosterController::getItem(const JID& jid) const {  	return xmppRoster_->getItem(jid);  }  std::set<std::string> RosterController::getGroups() const {  	return xmppRoster_->getGroups();  }  void RosterController::handleOnCapsChanged(const JID& jid) {  	DiscoInfo::ref info = entityCapsManager_->getCaps(jid);  	if (info) {  		std::set<ContactRosterItem::Feature> features;  		if (FileTransferManager::isSupportedBy(info)) {  			features.insert(ContactRosterItem::FileTransferFeature);  		}  		if (info->hasFeature(DiscoInfo::WhiteboardFeature)) {  			features.insert(ContactRosterItem::WhiteboardFeature);  		}  		roster_->applyOnItems(SetAvailableFeatures(jid, features));  	}  }  } diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h index 5b26fc7..d0c7024 100644 --- a/Swift/Controllers/Roster/RosterController.h +++ b/Swift/Controllers/Roster/RosterController.h @@ -18,101 +18,106 @@  #include <Swiften/Elements/RosterPayload.h>  #include <Swiften/Avatars/AvatarManager.h>  #include <Swiften/VCards/VCardManager.h>  #include <Swift/Controllers/UIEvents/UIEvent.h>  #include <Swift/Controllers/FileTransfer/FileTransferOverview.h>  #include <Swift/Controllers/Roster/RosterGroupExpandinessPersister.h>  namespace Swift {  	class IQRouter;  	class Roster;  	class XMPPRoster;  	class XMPPRosterItem;  	class MainWindow;  	class MainWindowFactory;  	class OfflineRosterFilter;  	class NickResolver;  	class PresenceOracle;  	class SubscriptionManager;  	class EventController;  	class SubscriptionRequestEvent;  	class UIEventStream;  	class IQRouter;  	class SettingsProvider;  	class NickManager;  	class EntityCapsProvider;  	class FileTransferManager;  	class ClientBlockListManager;  	class RosterVCardProvider;  	class RosterController {  		public:  			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, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager);  			~RosterController();  			void showRosterWindow(); +			void setJID(const JID& jid) { myJID_ = jid; }  			MainWindow* getWindow() {return mainWindow_;}  			boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;  			boost::signal<void ()> onSignOutRequest; +			void handleOwnVCardChanged(VCard::ref vcard);  			void handleAvatarChanged(const JID& jid); +			void handlePresenceChanged(Presence::ref presence);  			void setEnabled(bool enabled);  			boost::optional<XMPPRosterItem> getItem(const JID&) const;  			std::set<std::string> getGroups() const;  			void setContactGroups(const JID& jid, const std::vector<std::string>& groups);  			void updateItem(const XMPPRosterItem&);  			void initBlockingCommand();  		private:  			void handleOnJIDAdded(const JID &jid);  			void handleRosterCleared();  			void handleOnJIDRemoved(const JID &jid);  			void handleOnJIDUpdated(const JID &jid, const std::string& oldName, const std::vector<std::string>& oldGroups);  			void handleStartChatRequest(const JID& contact);  			void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText);  			void handleShowOfflineToggled(bool state);  			void handleIncomingPresence(boost::shared_ptr<Presence> newPresence);  			void handleSubscriptionRequest(const JID& jid, const std::string& message);  			void handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event);  			void handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event);  			void handleUIEvent(boost::shared_ptr<UIEvent> event);  			void handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload);  			void applyAllPresenceTo(const JID& jid);  			void handleEditProfileRequest();  			void handleOnCapsChanged(const JID& jid);  			void handleSettingChanged(const std::string& settingPath);  			void handleBlockingStateChanged();  			void handleBlockingItemAdded(const JID& jid);  			void handleBlockingItemRemoved(const JID& jid);  			JID myJID_;  			XMPPRoster* xmppRoster_;  			MainWindowFactory* mainWindowFactory_;  			MainWindow* mainWindow_;  			Roster* roster_;  			OfflineRosterFilter* offlineFilter_; +			VCardManager* vcardManager_;  			AvatarManager* avatarManager_;  			NickManager* nickManager_;  			NickResolver* nickResolver_;  			PresenceOracle* presenceOracle_;  			SubscriptionManager* subscriptionManager_;  			EventController* eventController_;  			RosterGroupExpandinessPersister* expandiness_;  			IQRouter* iqRouter_;  			SettingsProvider* settings_;  			UIEventStream* uiEventStream_;  			EntityCapsProvider* entityCapsManager_;  			FileTransferOverview* ftOverview_;  			ClientBlockListManager* clientBlockListManager_;  			RosterVCardProvider* rosterVCardProvider_; +			boost::shared_ptr<ContactRosterItem> ownContact_;  			boost::bsignals::scoped_connection blockingOnStateChangedConnection_;  			boost::bsignals::scoped_connection blockingOnItemAddedConnection_;  			boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;  			boost::bsignals::scoped_connection changeStatusConnection_;  			boost::bsignals::scoped_connection signOutConnection_;  			boost::bsignals::scoped_connection uiEventConnection_;  	};  }  | 
 Swift