From 96be62f4a700e3bd50f4b6f177f02e5820a09106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 23 Oct 2010 10:22:10 +0200 Subject: Don't lose notification enabledness when the user changes status. Resolves: #651 Release-Notes: The notification toggle on Linux will now be respected. diff --git a/SwifTools/Notifier/GrowlNotifier.cpp b/SwifTools/Notifier/GrowlNotifier.cpp index 066c4d0..3eb580a 100644 --- a/SwifTools/Notifier/GrowlNotifier.cpp +++ b/SwifTools/Notifier/GrowlNotifier.cpp @@ -70,7 +70,7 @@ GrowlNotifier::GrowlNotifier(const String& name) { Growl_SetDelegate(&delegate_); } -void GrowlNotifier::doShowMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picturePath, boost::function<void()> callback) { +void GrowlNotifier::showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picturePath, boost::function<void()> callback) { ByteArray picture; picture.readFromFile(picturePath.string()); diff --git a/SwifTools/Notifier/GrowlNotifier.h b/SwifTools/Notifier/GrowlNotifier.h index 379181d..5d618e6 100644 --- a/SwifTools/Notifier/GrowlNotifier.h +++ b/SwifTools/Notifier/GrowlNotifier.h @@ -24,7 +24,7 @@ namespace Swift { public: GrowlNotifier(const String& name); - virtual void doShowMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback); + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback); private: Growl_Delegate delegate_; diff --git a/SwifTools/Notifier/LoggingNotifier.h b/SwifTools/Notifier/LoggingNotifier.h index 138d1c5..eea07ef 100644 --- a/SwifTools/Notifier/LoggingNotifier.h +++ b/SwifTools/Notifier/LoggingNotifier.h @@ -12,7 +12,7 @@ namespace Swift { class LoggingNotifier : public Notifier { public: - virtual void doShowMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { notifications.push_back(Notification(type, subject, description, picture, callback)); } diff --git a/SwifTools/Notifier/Notifier.cpp b/SwifTools/Notifier/Notifier.cpp index c03970b..2c2660e 100644 --- a/SwifTools/Notifier/Notifier.cpp +++ b/SwifTools/Notifier/Notifier.cpp @@ -11,18 +11,9 @@ namespace Swift { const int Notifier::DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS = 3; const int Notifier::DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS = 5; -Notifier::Notifier() : enabled(true) { -} - Notifier::~Notifier() { } -void Notifier::showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { - if (enabled) { - doShowMessage(type, subject, description, picture, callback); - } -} - String Notifier::typeToString(Type type) { switch (type) { case ContactAvailable: return "Contact Becomes Available"; diff --git a/SwifTools/Notifier/Notifier.h b/SwifTools/Notifier/Notifier.h index e609867..b7c705e 100644 --- a/SwifTools/Notifier/Notifier.h +++ b/SwifTools/Notifier/Notifier.h @@ -14,7 +14,6 @@ namespace Swift { class Notifier { public: - Notifier(); virtual ~Notifier(); enum Type { ContactAvailable, ContactUnavailable, ContactStatusChange, IncomingMessage, SystemMessage }; @@ -27,20 +26,6 @@ namespace Swift { const String& subject, const String& description, const boost::filesystem::path& picture, - boost::function<void()> callback); - - void setEnabled(bool b) { - enabled = b; - } - - bool getEnabled() const {return enabled;} - - private: - virtual void doShowMessage( - Type type, - const String& subject, - const String& description, - const boost::filesystem::path& picture, boost::function<void()> callback) = 0; protected: @@ -50,8 +35,5 @@ namespace Swift { static const int DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS; static const int DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS; - - private: - bool enabled; }; } diff --git a/SwifTools/Notifier/NullNotifier.h b/SwifTools/Notifier/NullNotifier.h index 0b0b3df..e97329b 100644 --- a/SwifTools/Notifier/NullNotifier.h +++ b/SwifTools/Notifier/NullNotifier.h @@ -11,7 +11,7 @@ namespace Swift { class NullNotifier : public Notifier { public: - virtual void doShowMessage(Type, const String&, const String&, const boost::filesystem::path&, boost::function<void()>) { + virtual void showMessage(Type, const String&, const String&, const boost::filesystem::path&, boost::function<void()>) { } }; } diff --git a/SwifTools/Notifier/SnarlNotifier.h b/SwifTools/Notifier/SnarlNotifier.h index 83d4715..2350e29 100644 --- a/SwifTools/Notifier/SnarlNotifier.h +++ b/SwifTools/Notifier/SnarlNotifier.h @@ -19,7 +19,7 @@ namespace Swift { SnarlNotifier(const String& name, Win32NotifierWindow* window, const boost::filesystem::path& icon); ~SnarlNotifier(); - virtual void doShowMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback); + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback); private: void handleMessageReceived(MSG* message); diff --git a/SwifTools/Notifier/TogglableNotifier.h b/SwifTools/Notifier/TogglableNotifier.h new file mode 100644 index 0000000..1e87807 --- /dev/null +++ b/SwifTools/Notifier/TogglableNotifier.h @@ -0,0 +1,54 @@ +/* + * 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 "SwifTools/Notifier/Notifier.h" + +namespace Swift { + class TogglableNotifier : public Notifier { + public: + TogglableNotifier(Notifier* notifier) : notifier(notifier), persistentEnabled(true), temporarilyDisabled(false) { + } + + /** + * Set a long-term (usually user-set) enabled. + * This may be temporarily overriden by the application, e.g. if the + * user is marked DND. + */ + void setPersistentEnabled(bool b) { + persistentEnabled = b; + } + + /** + * Set a temporary override to stop notifications without changing the + * long-term state. e.g. if the user goes DND, but the persistent + * enabled shouldn't be lost when they become available again. + */ + void setTemporarilyDisabled(bool b) { + temporarilyDisabled = b; + } + + /** + * Get the result of applying the temporary override to the persistent + * enabledness. + */ + bool getCurrentlyEnabled() const { + return persistentEnabled && !temporarilyDisabled; + } + + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { + if (getCurrentlyEnabled()) { + notifier->showMessage(type, subject, description, picture, callback); + } + } + + private: + Notifier* notifier; + bool persistentEnabled; + bool temporarilyDisabled; + }; +} diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 7cf68a1..fcd161b 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -39,6 +39,7 @@ #include "Swift/Controllers/PresenceNotifier.h" #include "Swift/Controllers/EventNotifier.h" #include "SwifTools/Dock/Dock.h" +#include "SwifTools/Notifier/TogglableNotifier.h" #include "Swiften/Base/foreach.h" #include "Swiften/Base/String.h" #include "Swiften/Client/Client.h" @@ -69,6 +70,7 @@ static const String CLIENT_NAME = "Swift"; static const String CLIENT_VERSION = "1.0-devel"; static const String CLIENT_NODE = "http://swift.im"; +static const String SHOW_NOTIFICATIONS = "showNotifications"; MainController::MainController( ChatWindowFactory* chatWindowFactory, @@ -119,12 +121,12 @@ MainController::MainController( mucSearchWindowFactory_ = mucSearchWindowFactory; eventWindowFactory_ = eventWindowFactory; dock_ = dock; - notifier_ = notifier; chatListWindowFactory_ = chatListWindowFactory; uiEventStream_ = new UIEventStream(); avatarStorage_ = avatarStorage; capsStorage_ = capsStorage; + notifier_ = new TogglableNotifier(notifier); eventController_ = new EventController(); eventController_->onEventQueueLengthChange.connect(boost::bind(&MainController::handleEventQueueLengthChange, this, _1)); @@ -158,10 +160,10 @@ MainController::MainController( xmlConsoleController_ = new XMLConsoleController(uiEventStream_, xmlConsoleWidgetFactory); - bool enabled = settings_->getBoolSetting("showNotifications", true); - notifier_->setEnabled(enabled); - uiEventStream_->send(boost::shared_ptr<ToggleNotificationsUIEvent>(new ToggleNotificationsUIEvent(enabled))); uiEventStream_->onUIEvent.connect(boost::bind(&MainController::handleUIEvent, this, _1)); + bool enabled = settings_->getBoolSetting(SHOW_NOTIFICATIONS, true); + uiEventStream_->send(boost::shared_ptr<ToggleNotificationsUIEvent>(new ToggleNotificationsUIEvent(enabled))); + if (loginAutomatically) { profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_); @@ -179,6 +181,7 @@ MainController::~MainController() { delete uiEventStream_; resetClient(); delete eventController_; + delete notifier_; for(VCardStorageMap::iterator i = vcardStorages_.begin(); i != vcardStorages_.end(); ++i) { delete i->second; } @@ -230,10 +233,8 @@ void MainController::handleUIEvent(boost::shared_ptr<UIEvent> event) { boost::shared_ptr<ToggleNotificationsUIEvent> notificationsEvent = boost::dynamic_pointer_cast<ToggleNotificationsUIEvent>(event); if (notificationsEvent) { bool enabled = notificationsEvent->getEnabled(); - if (enabled != notifier_->getEnabled()) { - notifier_->setEnabled(enabled); - settings_->storeBool("showNotifications", enabled); - } + notifier_->setPersistentEnabled(enabled); + settings_->storeBool(SHOW_NOTIFICATIONS, enabled); } } @@ -339,7 +340,7 @@ void MainController::sendPresence(boost::shared_ptr<Presence> presence) { rosterController_->getWindow()->setMyStatusType(presence->getShow()); rosterController_->getWindow()->setMyStatusText(presence->getStatus()); systemTrayController_->setMyStatusType(presence->getShow()); - notifier_->setEnabled(presence->getShow() != StatusShow::DND); + notifier_->setTemporarilyDisabled(presence->getShow() == StatusShow::DND); // Add information and send if (!vCardPhotoHash_.isEmpty()) { diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index e7b4bfd..2f01fd2 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -53,6 +53,7 @@ namespace Swift { class LoginWindowFactory; class MUCController; class Notifier; + class TogglableNotifier; class PresenceNotifier; class EventNotifier; class SystemTray; @@ -137,7 +138,7 @@ namespace Swift { VCardStorageFactory* vcardStorageFactory_; VCardManager* vcardManager_; Dock* dock_; - Notifier* notifier_; + TogglableNotifier* notifier_; PresenceNotifier* presenceNotifier_; EventNotifier* eventNotifier_; RosterController* rosterController_; -- cgit v0.10.2-6-g49f6