summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'SwifTools/Notifier')
-rw-r--r--SwifTools/Notifier/GrowlNotifier.h1
-rw-r--r--SwifTools/Notifier/GrowlNotifier.mm12
-rw-r--r--SwifTools/Notifier/Notifier.h4
-rw-r--r--SwifTools/Notifier/TogglableNotifier.h6
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;
};
}