summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'SwifTools/Notifier/NotificationCenterNotifier.mm')
-rw-r--r--SwifTools/Notifier/NotificationCenterNotifier.mm87
1 files changed, 87 insertions, 0 deletions
diff --git a/SwifTools/Notifier/NotificationCenterNotifier.mm b/SwifTools/Notifier/NotificationCenterNotifier.mm
new file mode 100644
index 0000000..df092ff
--- /dev/null
+++ b/SwifTools/Notifier/NotificationCenterNotifier.mm
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) 2015 Isode Limited.
3 * All rights reserved.
4 * See the COPYING file for more information.
5 */
6
7#include <SwifTools/Notifier/NotificationCenterNotifier.h>
8
9#include <map>
10#include <string>
11
12#include <boost/smart_ptr/make_shared.hpp>
13
14#include <Swiften/Base/Log.h>
15
16#import <Cocoa/Cocoa.h>
17
18#include <SwifTools/Notifier/NotificationCenterNotifierDelegate.h>
19#include <SwifTools/Cocoa/CocoaUtil.h>
20
21namespace {
22 struct Context {
23 Context(const boost::function<void()>& callback) : callback(new boost::function<void()>(callback)) {
24 }
25
26 ~Context() {
27 delete callback;
28 }
29
30 boost::function<void()>* callback;
31 };
32}
33
34namespace Swift {
35
36class NotificationCenterNotifier::Private {
37 public:
38 std::map<std::string, boost::shared_ptr<Context> > callbacksForNotifications;
39 boost::intrusive_ptr<NotificationCenterNotifierDelegate> delegate;
40};
41
42NotificationCenterNotifier::NotificationCenterNotifier() {
43 p = boost::make_shared<Private>();
44 p->delegate = boost::intrusive_ptr<NotificationCenterNotifierDelegate>([[NotificationCenterNotifierDelegate alloc] init], false);
45 [p->delegate.get() setNotifier: this];
46
47 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate: p->delegate.get()];
48}
49
50NotificationCenterNotifier::~NotificationCenterNotifier() {
51 [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate: nil];
52 p->callbacksForNotifications.clear();
53}
54
55void NotificationCenterNotifier::showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void ()> callback) {
56 NSUserNotification* notification = [[NSUserNotification alloc] init];
57 notification.title = STD2NSSTRING(typeToString(type));
58 notification.subtitle = STD2NSSTRING(subject);
59 notification.informativeText = STD2NSSTRING(description);
60 notification.contentImage = [[NSImage alloc] initWithContentsOfFile: STD2NSSTRING(picture.string())];
61
62 // The OS X Notification Center API does not allow to attach custom data, like a pointer to a callback function,
63 // to the NSUserNotification object. Therefore we maintain a mapping from a NSUserNotification instance's identification
64 // to their respective callbacks.
65 notification.identifier = [[NSUUID UUID] UUIDString];
66
67 /// \todo Currently the elements are only removed on application exit. Ideally the notifications not required anymore
68 /// are removed from the map; e.g. when visiting a chat view, all notifications from that view can be removed from
69 /// the map and the NSUserNotificationCenter.
70 p->callbacksForNotifications[NS2STDSTRING(notification.identifier)] = boost::make_shared<Context>(callback);
71 [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
72}
73
74void NotificationCenterNotifier::purgeCallbacks() {
75 p->callbacksForNotifications.clear();
76}
77
78void NotificationCenterNotifier::handleUserNotificationActivated(const std::string& identifier) {
79 if (p->callbacksForNotifications.find(identifier) != p->callbacksForNotifications.end()) {
80 (*p->callbacksForNotifications[identifier]->callback)();
81 }
82 else {
83 SWIFT_LOG(warning) << "Missing callback entry for activated notification. The activate notification may come from another instance." << std::endl;
84 }
85}
86
87}