summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2012-03-15 19:21:46 (GMT)
committerRemko Tronçon <git@el-tramo.be>2012-03-15 19:21:46 (GMT)
commit138223ab9ca917420d107d95a113e7628c27bac5 (patch)
treeb7d71cc491af5723b72eec205695ac51cb2edf74
parent68d037d25824bcddfbb1316a221cd7a15ed109c2 (diff)
downloadswift-contrib-138223ab9ca917420d107d95a113e7628c27bac5.zip
swift-contrib-138223ab9ca917420d107d95a113e7628c27bac5.tar.bz2
Added purge to Growl.
-rw-r--r--SwifTools/Notifier/GrowlNotifier.h8
-rw-r--r--SwifTools/Notifier/GrowlNotifier.mm16
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();
+}
+
}