diff options
-rw-r--r-- | BuildTools/SCons/SConscript.boot | 1 | ||||
-rw-r--r-- | BuildTools/SCons/SConstruct | 5 | ||||
-rw-r--r-- | SwifTools/Notifier/NotificationCenterNotifier.h | 30 | ||||
-rw-r--r-- | SwifTools/Notifier/NotificationCenterNotifier.mm | 89 | ||||
-rw-r--r-- | SwifTools/Notifier/NotificationCenterNotifierDelegate.h | 21 | ||||
-rw-r--r-- | SwifTools/Notifier/NotificationCenterNotifierDelegate.mm | 23 | ||||
-rw-r--r-- | SwifTools/Notifier/SConscript | 5 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 11 | ||||
-rw-r--r-- | Swift/QtUI/QtWebView.cpp | 2 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 2 |
10 files changed, 187 insertions, 2 deletions
diff --git a/BuildTools/SCons/SConscript.boot b/BuildTools/SCons/SConscript.boot index b049f94..a741aab 100644 --- a/BuildTools/SCons/SConscript.boot +++ b/BuildTools/SCons/SConscript.boot @@ -36,6 +36,7 @@ if os.name == "nt" : if os.name == "nt" : vars.Add(PackageVariable("bonjour", "Bonjour SDK location", "yes")) vars.Add(PackageVariable("openssl", "OpenSSL location", "yes")) +vars.Add(PackageVariable("notification_center", "enable OS X Mountain Lion notification center", "no")) vars.Add(PathVariable("boost_includedir", "Boost headers location", None, PathVariable.PathAccept)) vars.Add(PathVariable("boost_libdir", "Boost library location", None, PathVariable.PathAccept)) vars.Add(PathVariable("expat_includedir", "Expat headers location", None, PathVariable.PathAccept)) diff --git a/BuildTools/SCons/SConstruct b/BuildTools/SCons/SConstruct index 3be4bd7..8a7e9ab 100644 --- a/BuildTools/SCons/SConstruct +++ b/BuildTools/SCons/SConstruct @@ -230,6 +230,11 @@ if env["PLATFORM"] == "darwin" : env["SPARKLE_FRAMEWORK"] = "/Library/Frameworks/Sparkle.framework" conf.Finish() +# Notification Center +env["HAVE_NOTIFICATION_CENTER"] = 0 +if env["PLATFORM"] == "darwin" : + env["HAVE_NOTIFICATION_CENTER"] = bool(env["notification_center"]) + # Growl env["HAVE_GROWL"] = 0 if env["PLATFORM"] == "darwin" : diff --git a/SwifTools/Notifier/NotificationCenterNotifier.h b/SwifTools/Notifier/NotificationCenterNotifier.h new file mode 100644 index 0000000..337f224 --- /dev/null +++ b/SwifTools/Notifier/NotificationCenterNotifier.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/filesystem/fstream.hpp> + +#include <SwifTools/Notifier/Notifier.h> + +namespace Swift { + class NotificationCenterNotifier : public Notifier { + public: + NotificationCenterNotifier(const std::string& name); + virtual ~NotificationCenterNotifier(); + + virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback); + + virtual void purgeCallbacks(); + + static bool isSupported(); + void handleNotificationClicked(void* notification); + + public: + class Private; + boost::shared_ptr<Private> p; + }; +} diff --git a/SwifTools/Notifier/NotificationCenterNotifier.mm b/SwifTools/Notifier/NotificationCenterNotifier.mm new file mode 100644 index 0000000..46bc7b1 --- /dev/null +++ b/SwifTools/Notifier/NotificationCenterNotifier.mm @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <SwifTools/Notifier/NotificationCenterNotifier.h> + +#include <SwifTools/Notifier/NotificationCenterNotifierDelegate.h> + +#import <Foundation/NSObjCRuntime.h> +#import <Foundation/NSUserNotification.h> +#import <Foundation/NSString.h> +#import <objc/runtime.h> + +#include <boost/smart_ptr/make_shared.hpp> +#include <SwifTools/Cocoa/CocoaUtil.h> + +#include <map> + +#include <Swiften/Base/Log.h> + +namespace Swift { + +class NotificationCenterNotifier::Private { + public: + void handleNotificationClicked(NSUserNotification* notification) { + unsigned long int id = [[[notification userInfo] objectForKey:@"id"] unsignedLongValue]; + if (callbacks.find(id) != callbacks.end()) { + callbacks[id](); + callbacks.erase(id); + } else { + SWIFT_LOG(debug) << "Callback missing! id:"<< id << std::endl; + } + } + + public: + unsigned long int lastID; + NSUserNotificationCenter* notificationCenter; + boost::intrusive_ptr<NotificationCenterNotifierDelegate> delegate; + std::map<unsigned long int, boost::function<void()> > callbacks; +}; + +NotificationCenterNotifier::NotificationCenterNotifier(const std::string& /*name*/) { + assert(isSupported()); + p = boost::make_shared<Private>(); + p->lastID = 0; + p->delegate = boost::intrusive_ptr<NotificationCenterNotifierDelegate>([[NotificationCenterNotifierDelegate alloc] init], false); + p->delegate.get().notifier = this; + p->notificationCenter = [NSUserNotificationCenter defaultUserNotificationCenter]; + [p->notificationCenter setDelegate:p->delegate.get()]; +} + +NotificationCenterNotifier::~NotificationCenterNotifier() { + +} + +void NotificationCenterNotifier::showMessage(Notifier::Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& /* picture */, boost::function<void()> callback) { + std::vector<Notifier::Type> defaultTypes = getDefaultTypes(); + if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) { + return; + } + + unsigned long int currentID = ++(p->lastID); + + NSUserNotification *notification = [[NSUserNotification alloc] init]; + [notification setTitle: [NSString stringWithUTF8String:subject.c_str()]]; + [notification setInformativeText: [NSString stringWithUTF8String:description.c_str()]]; + //[notification setActionButtonTitle:@"Accept Invitation"]; + //[notification setHasActionButton:TRUE]; + //[notification setSoundName:NSUserNotificationDefaultSoundName]; + [notification setUserInfo: [NSDictionary dictionaryWithObject: [NSNumber numberWithUnsignedLong:currentID] forKey:@"id"]]; + p->callbacks[currentID] = callback; + [p->notificationCenter scheduleNotification:notification]; +} + +void NotificationCenterNotifier::purgeCallbacks() { + p->callbacks.clear(); +} + +bool NotificationCenterNotifier::isSupported() { + return NSClassFromString(@"NSUserNotificationCenter") != nil; +} + +void NotificationCenterNotifier::handleNotificationClicked(void *notification) { + p->handleNotificationClicked(static_cast<NSUserNotification*>(notification)); +} + +} diff --git a/SwifTools/Notifier/NotificationCenterNotifierDelegate.h b/SwifTools/Notifier/NotificationCenterNotifierDelegate.h new file mode 100644 index 0000000..0db4370 --- /dev/null +++ b/SwifTools/Notifier/NotificationCenterNotifierDelegate.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#import <Foundation/NSUserNotification.h> + +namespace Swift { + class NotificationCenterNotifier; +} + +@interface NotificationCenterNotifierDelegate : NSObject<NSUserNotificationCenterDelegate> { + Swift::NotificationCenterNotifier* notifier; +} + +@property (nonatomic) Swift::NotificationCenterNotifier* notifier; + +- (void) userNotificationCenter:(NSUserNotificationCenter *) center didActivateNotification:(NSUserNotification *) notification; + +@end diff --git a/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm b/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm new file mode 100644 index 0000000..271d953 --- /dev/null +++ b/SwifTools/Notifier/NotificationCenterNotifierDelegate.mm @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#import "NotificationCenterNotifierDelegate.h" + +#include <SwifTools/Notifier/NotificationCenterNotifier.h> + +@implementation NotificationCenterNotifierDelegate; + +@synthesize notifier; + +using namespace Swift; + +- (void) userNotificationCenter:(NSUserNotificationCenter *) center didActivateNotification:(NSUserNotification *) notification { + notifier->handleNotificationClicked(notification); + //Remove the notification + [center removeDeliveredNotification:notification]; +} + +@end diff --git a/SwifTools/Notifier/SConscript b/SwifTools/Notifier/SConscript index 98b5400..53bb38e 100644 --- a/SwifTools/Notifier/SConscript +++ b/SwifTools/Notifier/SConscript @@ -16,6 +16,11 @@ if swiftools_env.get("HAVE_SNARL", False) : sources += [ "SnarlNotifier.cpp", ] +if swiftools_env.get("HAVE_NOTIFICATION_CENTER", False) : + sources += [ + "NotificationCenterNotifier.mm", + "NotificationCenterNotifierDelegate.mm", + ] objects = myenv.StaticObject(sources) swiftools_env.Append(SWIFTOOLS_OBJECTS = objects) diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index 13b2175..c07c485 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -43,6 +43,9 @@ #include "WindowsNotifier.h" #elif defined(HAVE_GROWL) #include "SwifTools/Notifier/GrowlNotifier.h" +#if defined(HAVE_NOTIFICATION_CENTER) +#include "SwifTools/Notifier/NotificationCenterNotifier.h" +#endif #elif defined(SWIFTEN_PLATFORM_LINUX) #include "FreeDesktopNotifier.h" #else @@ -163,7 +166,13 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa QtSystemTray* systemTray = new QtSystemTray(); systemTrays_.push_back(systemTray); -#if defined(HAVE_GROWL) +#if defined(HAVE_NOTIFICATION_CENTER) && defined(HAVE_GROWL) + if (NotificationCenterNotifier::isSupported()) { + notifier_ = new NotificationCenterNotifier(SWIFT_APPLICATION_NAME); + } else { + notifier_ = new GrowlNotifier(SWIFT_APPLICATION_NAME); + } +#elif defined(HAVE_GROWL) notifier_ = new GrowlNotifier(SWIFT_APPLICATION_NAME); #elif defined(SWIFTEN_PLATFORM_WINDOWS) notifier_ = new WindowsNotifier(SWIFT_APPLICATION_NAME, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"), systemTray->getQSystemTrayIcon()); diff --git a/Swift/QtUI/QtWebView.cpp b/Swift/QtUI/QtWebView.cpp index 388f06a..38ed345 100644 --- a/Swift/QtUI/QtWebView.cpp +++ b/Swift/QtUI/QtWebView.cpp @@ -58,7 +58,7 @@ void QtWebView::contextMenuEvent(QContextMenuEvent* ev) { } } if (removeAction) { - menu->removeAction(action); + //menu->removeAction(action); } } diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 5ab9c9e..4cd7865 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -40,6 +40,8 @@ if myenv["swift_mobile"] : if myenv.get("HAVE_SNARL", False) : myenv.UseFlags(myenv["SNARL_FLAGS"]) myenv.Append(CPPDEFINES = ["HAVE_SNARL"]) +if myenv.get("HAVE_NOTIFICATION_CENTER", False) : + myenv.Append(CPPDEFINES = ["HAVE_NOTIFICATION_CENTER"]) if env["PLATFORM"] == "win32" : myenv.Append(LIBS = ["cryptui"]) myenv.UseFlags(myenv["PLATFORM_FLAGS"]) |