diff options
Diffstat (limited to 'SwifTools')
| -rw-r--r-- | SwifTools/Notifier/GrowlNotifier.h | 1 | ||||
| -rw-r--r-- | SwifTools/Notifier/GrowlNotifier.mm | 12 | ||||
| -rw-r--r-- | SwifTools/Notifier/Notifier.h | 4 | ||||
| -rw-r--r-- | SwifTools/Notifier/TogglableNotifier.h | 6 |
4 files changed, 19 insertions, 4 deletions
diff --git a/SwifTools/Notifier/GrowlNotifier.h b/SwifTools/Notifier/GrowlNotifier.h index ffd717a..cb0d089 100644 --- a/SwifTools/Notifier/GrowlNotifier.h +++ b/SwifTools/Notifier/GrowlNotifier.h @@ -1,34 +1,35 @@ /* * Copyright (c) 2010-2011 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #pragma once #include <boost/filesystem/fstream.hpp> #include <SwifTools/Notifier/Notifier.h> namespace Swift { /** * Preconditions for using growlnotifier: * - Must be part a bundle. * - The Carbon/Cocoa application loop must be running (e.g. through QApplication) * such that notifications are coming through. */ class GrowlNotifier : public Notifier { public: GrowlNotifier(const std::string& name); virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback); + virtual bool isExternallyConfigured() const; // Called by the delegate. Don't call. void handleNotificationClicked(void* data); void handleNotificationTimedOut(void* data); private: class Private; boost::shared_ptr<Private> p; }; } diff --git a/SwifTools/Notifier/GrowlNotifier.mm b/SwifTools/Notifier/GrowlNotifier.mm index 108259a..cb4790e 100644 --- a/SwifTools/Notifier/GrowlNotifier.mm +++ b/SwifTools/Notifier/GrowlNotifier.mm @@ -16,69 +16,75 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" namespace { struct Context { Context(const boost::function<void()>& callback) : callback(new boost::function<void()>(callback)) {} boost::function<void()>* callback; }; } namespace Swift { class GrowlNotifier::Private { public: boost::intrusive_ptr<GrowlNotifierDelegate> delegate; }; GrowlNotifier::GrowlNotifier(const std::string& name) { p = boost::make_shared<Private>(); p->delegate = boost::intrusive_ptr<GrowlNotifierDelegate>([[GrowlNotifierDelegate alloc] init], false); p->delegate.get().name = STD2NSSTRING(name); NSMutableArray* allNotifications = [[NSMutableArray alloc] init]; foreach(Type type, getAllTypes()) { [allNotifications addObject: STD2NSSTRING(typeToString(type))]; } NSMutableArray* defaultNotifications = [[NSMutableArray alloc] init]; foreach(Type type, getDefaultTypes()) { [defaultNotifications addObject: STD2NSSTRING(typeToString(type))]; } p->delegate.get().registrationDictionary = [[[NSDictionary alloc] initWithObjects: [NSArray arrayWithObjects: allNotifications, defaultNotifications, nil] forKeys: [NSArray arrayWithObjects: GROWL_NOTIFICATIONS_ALL, GROWL_NOTIFICATIONS_DEFAULT, nil]] autorelease]; + + [allNotifications release]; + [defaultNotifications release]; [GrowlApplicationBridge setGrowlDelegate: p->delegate.get()]; } void GrowlNotifier::showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picturePath, boost::function<void()> callback) { ByteArray picture; readByteArrayFromFile(picture, picturePath.string()); - Context* contextPtr = new Context(callback); - NSData* context = [NSData dataWithBytes: &contextPtr length: sizeof(contextPtr)]; + Context* context = new Context(callback); [GrowlApplicationBridge notifyWithTitle: STD2NSSTRING(subject) description: STD2NSSTRING(description) notificationName: STD2NSSTRING(typeToString(type)) iconData: [NSData dataWithBytes: vecptr(picture) length: picture.size()] priority: 0 isSticky: NO - clickContext: context]; + clickContext: [NSData dataWithBytes: &context length: sizeof(context)]]; } void GrowlNotifier::handleNotificationClicked(void* rawData) { Context* context = *(Context**) [((NSData*) rawData) bytes]; if (!context->callback->empty()) { (*context->callback)(); } delete context; } void GrowlNotifier::handleNotificationTimedOut(void* rawData) { delete *(Context**) [((NSData*) rawData) bytes]; } +bool GrowlNotifier::isExternallyConfigured() const { + return ![GrowlApplicationBridge isMistEnabled]; +} + } diff --git a/SwifTools/Notifier/Notifier.h b/SwifTools/Notifier/Notifier.h index d6bd878..1bcd58d 100644 --- a/SwifTools/Notifier/Notifier.h +++ b/SwifTools/Notifier/Notifier.h @@ -1,43 +1,47 @@ /* * 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 <boost/function.hpp> #include <boost/filesystem/path.hpp> #include <string> #include <vector> namespace Swift { class Notifier { public: virtual ~Notifier(); enum Type { ContactAvailable, ContactUnavailable, ContactStatusChange, IncomingMessage, SystemMessage }; /** * Picture is a PNG image. */ virtual void showMessage( Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback) = 0; virtual bool isAvailable() const { return true; } + virtual bool isExternallyConfigured() const { + return false; + } + protected: std::string typeToString(Type type); static std::vector<Type> getAllTypes(); static std::vector<Type> getDefaultTypes(); static const int DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS; static const int DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS; }; } diff --git a/SwifTools/Notifier/TogglableNotifier.h b/SwifTools/Notifier/TogglableNotifier.h index e8de5de..7abfd42 100644 --- a/SwifTools/Notifier/TogglableNotifier.h +++ b/SwifTools/Notifier/TogglableNotifier.h @@ -9,46 +9,50 @@ #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 std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback) { - if (getCurrentlyEnabled()) { + if (getCurrentlyEnabled() || notifier->isExternallyConfigured()) { notifier->showMessage(type, subject, description, picture, callback); } } + virtual bool isExternallyConfigured() const { + return notifier->isExternallyConfigured(); + } + private: Notifier* notifier; bool persistentEnabled; bool temporarilyDisabled; }; } |
Swift