diff options
author | Remko Tronçon <git@el-tramo.be> | 2012-03-15 19:21:46 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2012-03-15 19:21:46 (GMT) |
commit | 138223ab9ca917420d107d95a113e7628c27bac5 (patch) | |
tree | b7d71cc491af5723b72eec205695ac51cb2edf74 | |
parent | 68d037d25824bcddfbb1316a221cd7a15ed109c2 (diff) | |
download | swift-contrib-138223ab9ca917420d107d95a113e7628c27bac5.zip swift-contrib-138223ab9ca917420d107d95a113e7628c27bac5.tar.bz2 |
Added purge to Growl.
-rw-r--r-- | SwifTools/Notifier/GrowlNotifier.h | 8 | ||||
-rw-r--r-- | SwifTools/Notifier/GrowlNotifier.mm | 16 |
2 files changed, 17 insertions, 7 deletions
diff --git a/SwifTools/Notifier/GrowlNotifier.h b/SwifTools/Notifier/GrowlNotifier.h index f1fb8c6..73f1008 100644 --- a/SwifTools/Notifier/GrowlNotifier.h +++ b/SwifTools/Notifier/GrowlNotifier.h @@ -1,39 +1,41 @@ /* * 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); ~GrowlNotifier(); 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); - virtual void purgeCallbacks() { -#warning FIXME: Implement - } + virtual void purgeCallbacks(); + + private: + void clearPendingNotifications(); + private: class Private; boost::shared_ptr<Private> p; }; } diff --git a/SwifTools/Notifier/GrowlNotifier.mm b/SwifTools/Notifier/GrowlNotifier.mm index b0f26ce..c1996d9 100644 --- a/SwifTools/Notifier/GrowlNotifier.mm +++ b/SwifTools/Notifier/GrowlNotifier.mm @@ -28,82 +28,90 @@ namespace Swift { class GrowlNotifier::Private { public: std::set<Context*> pendingNotifications; 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().notifier = this; 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()]; } GrowlNotifier::~GrowlNotifier() { [GrowlApplicationBridge setGrowlDelegate: nil]; - foreach (Context* context, p->pendingNotifications) { - delete context; - } - p->pendingNotifications.clear(); + clearPendingNotifications(); } 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* context = new Context(callback); // Growl sometimes sends timeout notifications twice for the same message. We therefore need // to keep track of which ones have already been processed. p->pendingNotifications.insert(context); [GrowlApplicationBridge notifyWithTitle: STD2NSSTRING(subject) description: STD2NSSTRING(description) notificationName: STD2NSSTRING(typeToString(type)) iconData: [NSData dataWithBytes: vecptr(picture) length: picture.size()] priority: 0 isSticky: NO clickContext: [NSData dataWithBytes: &context length: sizeof(context)]]; } void GrowlNotifier::handleNotificationClicked(void* rawData) { Context* context = *(Context**) [((NSData*) rawData) bytes]; if (p->pendingNotifications.erase(context) > 0) { if (!context->callback->empty()) { (*context->callback)(); } delete context; } } void GrowlNotifier::handleNotificationTimedOut(void* rawData) { Context* context = *(Context**) [((NSData*) rawData) bytes]; if (p->pendingNotifications.erase(context) > 0) { delete context; } } bool GrowlNotifier::isExternallyConfigured() const { return ![GrowlApplicationBridge isMistEnabled]; } +void GrowlNotifier::purgeCallbacks() { + clearPendingNotifications(); +} + +void GrowlNotifier::clearPendingNotifications() { + foreach (Context* context, p->pendingNotifications) { + delete context; + } + p->pendingNotifications.clear(); +} + } |