diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-09-15 16:40:20 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-09-15 16:41:16 (GMT) |
commit | c0ea59aed73b5425ad78e6bdb6f8f12e2b44567e (patch) | |
tree | bc111c071c92911d7e9745c86c8cdfac69cd64e7 /SwifTools/Notifier | |
parent | 3c45ed7c3b62609824c0ea50f1ce9c00bbe00849 (diff) | |
download | swift-contrib-c0ea59aed73b5425ad78e6bdb6f8f12e2b44567e.zip swift-contrib-c0ea59aed73b5425ad78e6bdb6f8f12e2b44567e.tar.bz2 |
Added Snarl notification support
Diffstat (limited to 'SwifTools/Notifier')
-rw-r--r-- | SwifTools/Notifier/GrowlNotifier.cpp | 17 | ||||
-rw-r--r-- | SwifTools/Notifier/GrowlNotifier.h | 6 | ||||
-rw-r--r-- | SwifTools/Notifier/LoggingNotifier.h | 6 | ||||
-rw-r--r-- | SwifTools/Notifier/Notifier.cpp | 30 | ||||
-rw-r--r-- | SwifTools/Notifier/Notifier.h | 8 | ||||
-rw-r--r-- | SwifTools/Notifier/SConscript | 11 | ||||
-rw-r--r-- | SwifTools/Notifier/SnarlNotifier.cpp | 62 | ||||
-rw-r--r-- | SwifTools/Notifier/SnarlNotifier.h | 34 | ||||
-rw-r--r-- | SwifTools/Notifier/Win32NotifierWindow.h | 22 |
9 files changed, 173 insertions, 23 deletions
diff --git a/SwifTools/Notifier/GrowlNotifier.cpp b/SwifTools/Notifier/GrowlNotifier.cpp index 0527ef8..0660910 100644 --- a/SwifTools/Notifier/GrowlNotifier.cpp +++ b/SwifTools/Notifier/GrowlNotifier.cpp @@ -71,7 +71,10 @@ GrowlNotifier::GrowlNotifier(const String& name) { Growl_SetDelegate(&delegate_); } -void GrowlNotifier::showMessage(Type type, const String& subject, const String& description, const ByteArray& picture, boost::function<void()> callback) { +void GrowlNotifier::showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picturePath, boost::function<void()> callback) { + ByteArray picture; + picture.readFromFile(picturePath.string()); + CFStringRef cfSubject = SWIFTEN_STRING_TO_CFSTRING(subject); CFStringRef cfDescription = SWIFTEN_STRING_TO_CFSTRING(description); CFStringRef cfName = SWIFTEN_STRING_TO_CFSTRING(typeToString(type)); @@ -92,16 +95,4 @@ void GrowlNotifier::showMessage(Type type, const String& subject, const String& CFRelease(cfSubject); } -String GrowlNotifier::typeToString(Type type) { - switch (type) { - case ContactAvailable: return "Contact Becomes Available"; - case ContactUnavailable: return "Contact Becomes Unavailable"; - case ContactStatusChange: return "Contact Changes Status"; - case IncomingMessage: return "Incoming Message"; - case SystemMessage: return "System Message"; - } - assert(false); - return ""; -} - } diff --git a/SwifTools/Notifier/GrowlNotifier.h b/SwifTools/Notifier/GrowlNotifier.h index fab3b5e..5d618e6 100644 --- a/SwifTools/Notifier/GrowlNotifier.h +++ b/SwifTools/Notifier/GrowlNotifier.h @@ -8,6 +8,7 @@ #include <CoreFoundation/CoreFoundation.h> #include <Growl/Growl.h> +#include <boost/filesystem/fstream.hpp> #include "SwifTools/Notifier/Notifier.h" @@ -23,12 +24,9 @@ namespace Swift { public: GrowlNotifier(const String& name); - virtual void showMessage(Type type, const String& subject, const String& description, const ByteArray& picture, boost::function<void()> callback); + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback); private: - String typeToString(Type type); - - private: Growl_Delegate delegate_; }; } diff --git a/SwifTools/Notifier/LoggingNotifier.h b/SwifTools/Notifier/LoggingNotifier.h index 93349d9..eea07ef 100644 --- a/SwifTools/Notifier/LoggingNotifier.h +++ b/SwifTools/Notifier/LoggingNotifier.h @@ -12,16 +12,16 @@ namespace Swift { class LoggingNotifier : public Notifier { public: - virtual void showMessage(Type type, const String& subject, const String& description, const ByteArray& picture, boost::function<void()> callback) { + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { notifications.push_back(Notification(type, subject, description, picture, callback)); } struct Notification { - Notification(Type type, const String& subject, const String& description, const ByteArray& picture, boost::function<void()> callback) : type(type), subject(subject), description(description), picture(picture), callback(callback) {} + Notification(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) : type(type), subject(subject), description(description), picture(picture), callback(callback) {} Type type; String subject; String description; - ByteArray picture; + boost::filesystem::path picture; boost::function<void()> callback; }; diff --git a/SwifTools/Notifier/Notifier.cpp b/SwifTools/Notifier/Notifier.cpp index 2c2cfe5..a976486 100644 --- a/SwifTools/Notifier/Notifier.cpp +++ b/SwifTools/Notifier/Notifier.cpp @@ -11,4 +11,34 @@ namespace Swift { Notifier::~Notifier() { } +String Notifier::typeToString(Type type) { + switch (type) { + case ContactAvailable: return "Contact Becomes Available"; + case ContactUnavailable: return "Contact Becomes Unavailable"; + case ContactStatusChange: return "Contact Changes Status"; + case IncomingMessage: return "Incoming Message"; + case SystemMessage: return "System Message"; + } + assert(false); + return ""; +} + +std::vector<Notifier::Type> Notifier::getAllTypes() { + std::vector<Type> result; + result.push_back(ContactAvailable); + result.push_back(ContactUnavailable); + result.push_back(ContactStatusChange); + result.push_back(IncomingMessage); + result.push_back(SystemMessage); + return result; +} + +std::vector<Notifier::Type> Notifier::getDefaultTypes() { + std::vector<Type> result; + result.push_back(ContactAvailable); + result.push_back(IncomingMessage); + result.push_back(SystemMessage); + return result; +} + } diff --git a/SwifTools/Notifier/Notifier.h b/SwifTools/Notifier/Notifier.h index 3e3da8a..f1a89ef 100644 --- a/SwifTools/Notifier/Notifier.h +++ b/SwifTools/Notifier/Notifier.h @@ -7,6 +7,7 @@ #pragma once #include <boost/function.hpp> +#include <boost/filesystem/path.hpp> #include "Swiften/Base/String.h" @@ -24,7 +25,12 @@ namespace Swift { Type type, const String& subject, const String& description, - const ByteArray& picture, + const boost::filesystem::path& picture, boost::function<void()> callback) = 0; + + protected: + String typeToString(Type type); + static std::vector<Type> getAllTypes(); + static std::vector<Type> getDefaultTypes(); }; } diff --git a/SwifTools/Notifier/SConscript b/SwifTools/Notifier/SConscript index 89fc31b..9ad2fd7 100644 --- a/SwifTools/Notifier/SConscript +++ b/SwifTools/Notifier/SConscript @@ -1,5 +1,7 @@ Import("swiftools_env") +myenv = swiftools_env.Clone() + sources = [ "Notifier.cpp", ] @@ -8,6 +10,11 @@ if swiftools_env.get("HAVE_GROWL", False) : sources += [ "GrowlNotifier.cpp", ] - -objects = swiftools_env.StaticObject(sources) +if swiftools_env.get("HAVE_SNARL", False) : + myenv.MergeFlags(myenv["SNARL_FLAGS"]) + sources += [ + "SnarlNotifier.cpp", + ] + +objects = myenv.StaticObject(sources) swiftools_env.Append(SWIFTOOLS_OBJECTS = objects) diff --git a/SwifTools/Notifier/SnarlNotifier.cpp b/SwifTools/Notifier/SnarlNotifier.cpp new file mode 100644 index 0000000..86069c9 --- /dev/null +++ b/SwifTools/Notifier/SnarlNotifier.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "SwifTools/Notifier/SnarlNotifier.h" + +#include <cassert> +#include <iostream> +#include <boost/bind.hpp> + +#include "Swiften/Base/foreach.h" +#include "SwifTools/Notifier/Win32NotifierWindow.h" + +#define SWIFT_SNARLNOTIFIER_MESSAGE_ID 0x4567 // Sounds sick to pick a number, but this is windows + +namespace Swift { + +SnarlNotifier::SnarlNotifier(const String& name, Win32NotifierWindow* window) : window(window) { + window->onMessageReceived.connect(boost::bind(&SnarlNotifier::handleMessageReceived, this, _1)); + snarl.RegisterConfig(window->getID(), name.getUTF8Data(), 0); + foreach(Notifier::Type type, getAllTypes()) { + snarl.RegisterAlert(name.getUTF8Data(), typeToString(type).getUTF8Data()); + } +} + +SnarlNotifier::~SnarlNotifier() { + snarl.RevokeConfig(window->getID()); + window->onMessageReceived.disconnect(boost::bind(&SnarlNotifier::handleMessageReceived, this, _1)); + if (!notifications.empty()) { + std::cerr << "Warning: " << notifications.size() << " Snarl notifications pending" << std::endl; + } +} + +void SnarlNotifier::showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) { + int notificationID = snarl.ShowMessageEx(typeToString(type).getUTF8Data(), subject.getUTF8Data(), description.getUTF8Data(), timeout, picture.string().c_str(), window->getID(), SWIFT_SNARLNOTIFIER_MESSAGE_ID); + if (notificationID > 0) { + notifications.insert(std::make_pair(notificationID, callback)); + } +} + +void SnarlNotifier::handleMessageReceived(MSG* message) { + if (message->message == SWIFT_SNARLNOTIFIER_MESSAGE_ID) { + int action = message->wParam; + if (action == Snarl::SNARL_NOTIFICATION_TIMED_OUT || action == Snarl::SNARL_NOTIFICATION_ACK || action == Snarl::SNARL_NOTIFICATION_CLOSED) { + int notificationID = message->lParam; + NotificationsMap::iterator i = notifications.find(notificationID); + if (i != notifications.end()) { + if (action == Snarl::SNARL_NOTIFICATION_ACK) { + i->second(); + } + notifications.erase(i); + } + else { + std::cerr << "Warning: Orphaned Snarl notification received"; + } + } + } +} + +} diff --git a/SwifTools/Notifier/SnarlNotifier.h b/SwifTools/Notifier/SnarlNotifier.h new file mode 100644 index 0000000..45408ec --- /dev/null +++ b/SwifTools/Notifier/SnarlNotifier.h @@ -0,0 +1,34 @@ +/* + * 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 <map> + +#include "SwifTools/Notifier/Notifier.h" +#include "SnarlInterface.h" + +namespace Swift { + class Win32NotifierWindow; + + class SnarlNotifier : public Notifier { + public: + SnarlNotifier(const String& name, Win32NotifierWindow* window); + ~SnarlNotifier(); + + virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback); + + private: + void handleMessageReceived(MSG* message); + + private: + static const int timeout = 3; + Snarl::SnarlInterface snarl; + Win32NotifierWindow* window; + typedef std::map<int, boost::function<void()> > NotificationsMap; + NotificationsMap notifications; + }; +} diff --git a/SwifTools/Notifier/Win32NotifierWindow.h b/SwifTools/Notifier/Win32NotifierWindow.h new file mode 100644 index 0000000..7ac149b --- /dev/null +++ b/SwifTools/Notifier/Win32NotifierWindow.h @@ -0,0 +1,22 @@ +/* + * 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 <windows.h> + +#include "Swiften/Base/boost_bsignals.h" + +namespace Swift { + class Win32NotifierWindow { + public: + virtual ~Win32NotifierWindow() {} + + virtual HWND getID() const = 0; + + boost::signal<void (MSG*)> onMessageReceived; + }; +} |