From 9e35dfd2f3a1fbc88bb800c8bf167035b0bd0582 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Wed, 22 Dec 2010 10:14:15 +0100
Subject: Use a default balloons notifier on Windows.


diff --git a/SwifTools/Notifier/SnarlNotifier.cpp b/SwifTools/Notifier/SnarlNotifier.cpp
index 709128b..8d7407a 100644
--- a/SwifTools/Notifier/SnarlNotifier.cpp
+++ b/SwifTools/Notifier/SnarlNotifier.cpp
@@ -17,9 +17,9 @@
 
 namespace Swift {
 
-SnarlNotifier::SnarlNotifier(const String& name, Win32NotifierWindow* window, const boost::filesystem::path& icon) : window(window) {
+SnarlNotifier::SnarlNotifier(const String& name, Win32NotifierWindow* window, const boost::filesystem::path& icon) : window(window), available(false) {
 	window->onMessageReceived.connect(boost::bind(&SnarlNotifier::handleMessageReceived, this, _1));
-	snarl.RegisterApp(name.getUTF8Data(), name.getUTF8Data(), icon.string().c_str(), window->getID(), SWIFT_SNARLNOTIFIER_MESSAGE_ID);
+	available = snarl.RegisterApp(name.getUTF8Data(), name.getUTF8Data(), icon.string().c_str(), window->getID(), SWIFT_SNARLNOTIFIER_MESSAGE_ID);
 	foreach(Notifier::Type type, getAllTypes()) {
 		snarl.AddClass(typeToString(type).getUTF8Data(), typeToString(type).getUTF8Data());
 	}
@@ -34,7 +34,7 @@ SnarlNotifier::~SnarlNotifier() {
 }
 
 bool SnarlNotifier::isAvailable() const {
-	return false;
+	return available;
 }
 
 
diff --git a/SwifTools/Notifier/SnarlNotifier.h b/SwifTools/Notifier/SnarlNotifier.h
index d03882a..9aa75f6 100644
--- a/SwifTools/Notifier/SnarlNotifier.h
+++ b/SwifTools/Notifier/SnarlNotifier.h
@@ -28,6 +28,7 @@ namespace Swift {
 		private:
 			Snarl::V41::SnarlInterface snarl;
 			Win32NotifierWindow* window;
+			bool available;
 			typedef std::map<int, boost::function<void()> > NotificationsMap;
 			NotificationsMap notifications;
 	};
diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp
index cb348fc..37ac755 100644
--- a/Swift/QtUI/QtLoginWindow.cpp
+++ b/Swift/QtUI/QtLoginWindow.cpp
@@ -169,7 +169,7 @@ QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream) : QMainWindow() {
 	toggleNotificationsAction_->setCheckable(true);
 	toggleNotificationsAction_->setChecked(true);
 	connect(toggleNotificationsAction_, SIGNAL(toggled(bool)), SLOT(handleToggleNotifications(bool)));
-#ifdef SWIFTEN_PLATFORM_LINUX
+#if defined(SWIFTEN_PLATFORM_LINUX) || defined(SWIFTEN_PLATFORM_WINDOWS)
 	generalMenu_->addAction(toggleNotificationsAction_);
 #endif
 
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index ef87aab..2c1f2bf 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -32,11 +32,11 @@
 #include "Swift/Controllers/BuildVersion.h"
 #include "SwifTools/AutoUpdater/AutoUpdater.h"
 #include "SwifTools/AutoUpdater/PlatformAutoUpdaterFactory.h"
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+#include "WindowsNotifier.h"
+#endif
 #if defined(HAVE_GROWL)
 #include "SwifTools/Notifier/GrowlNotifier.h"
-#elif defined(HAVE_SNARL)
-#include "QtWin32NotifierWindow.h"
-#include "SwifTools/Notifier/SnarlNotifier.h"
 #elif defined(SWIFTEN_PLATFORM_LINUX)
 #include "FreeDesktopNotifier.h"
 #else
@@ -44,11 +44,8 @@
 #endif
 #if defined(SWIFTEN_PLATFORM_MACOSX)
 #include "SwifTools/Dock/MacOSXDock.h"
-#elif defined(SWIFTEN_PLATFORM_WINDOWS)
-#include "SwifTools/Dock/WindowsDock.h"
-#else
-#include "SwifTools/Dock/NullDock.h"
 #endif
+#include "SwifTools/Dock/NullDock.h"
 
 namespace Swift{
 
@@ -104,26 +101,24 @@ QtSwift::QtSwift(po::variables_map options) : networkFactories_(&clientMainThrea
 	certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory());
 	chatWindowFactory_ = new QtChatWindowFactory(splitter_, settings_, tabs_, "");
 	soundPlayer_ = new QtSoundPlayer(applicationPathProvider_);
+
+	// Ugly, because the dock depends on the tray, but the temporary
+	// multi-account hack creates one tray per account.
+	QtSystemTray* systemTray = new QtSystemTray();
+	systemTrays_.push_back(systemTray);
+
 #if defined(HAVE_GROWL)
 	notifier_ = new GrowlNotifier(SWIFT_APPLICATION_NAME);
-#elif defined(HAVE_SNARL)
-	notifierWindow_ = new QtWin32NotifierWindow();
-	notifier_ = new SnarlNotifier(SWIFT_APPLICATION_NAME, notifierWindow_, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"));
+#elif defined(SWIFTEN_PLATFORM_WINDOWS)
+	notifier_ = new WindowsNotifier(SWIFT_APPLICATION_NAME, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"), systemTray->getQSystemTrayIcon());
 #elif defined(SWIFTEN_PLATFORM_LINUX)
 	notifier_ = new FreeDesktopNotifier(SWIFT_APPLICATION_NAME);
 #else
 	notifier_ = new NullNotifier();
 #endif
 
-	// Ugly, because the dock depends on the tray, but the temporary
-	// multi-account hack creates one tray per account.
-	QtSystemTray* systemTray = new QtSystemTray();
-	systemTrays_.push_back(systemTray);
-
 #if defined(SWIFTEN_PLATFORM_MACOSX)
 	dock_ = new MacOSXDock(&cocoaApplication_);
-#elif defined(SWIFTEN_PLATFORM_WINDOWS)
-	dock_ = new WindowsDock(systemTray->getQSystemTrayIcon(), notifier_);
 #else
 	dock_ = new NullDock();
 #endif
@@ -164,9 +159,6 @@ QtSwift::QtSwift(po::variables_map options) : networkFactories_(&clientMainThrea
 
 QtSwift::~QtSwift() {
 	delete notifier_;
-#if defined(HAVE_SNARL)
-	delete notifierWindow_;
-#endif
 	delete autoUpdater_;
 	foreach (QtUIFactory* factory, uiFactories_) {
 		delete factory;
diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h
index b674802..32e261c 100644
--- a/Swift/QtUI/QtSwift.h
+++ b/Swift/QtUI/QtSwift.h
@@ -18,8 +18,8 @@
 #if defined(SWIFTEN_PLATFORM_MACOSX)
 #include "SwifTools/Application/CocoaApplication.h"
 #endif
-#if defined(HAVE_SNARL)
-#include "SwifTools/Notifier/Win32NotifierWindow.h"
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+#include "WindowsNotifier.h"
 #endif
 
 namespace po = boost::program_options;
@@ -71,8 +71,5 @@ namespace Swift {
 #if defined(SWIFTEN_PLATFORM_MACOSX)
 			CocoaApplication cocoaApplication_;
 #endif
-#if defined(HAVE_SNARL)
-			Win32NotifierWindow* notifierWindow_;
-#endif
 	};
 }
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 377b949..d9080bb 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -92,6 +92,7 @@ sources = [
     "SystemMessageSnippet.cpp",
     "QtElidingLabel.cpp",
     "QtLineEdit.cpp",
+    "WindowsNotifier.cpp",
     "Roster/RosterModel.cpp",
     "Roster/QtTreeWidget.cpp",
 #    "Roster/QtTreeWidgetItem.cpp",
diff --git a/Swift/QtUI/WindowsNotifier.cpp b/Swift/QtUI/WindowsNotifier.cpp
new file mode 100644
index 0000000..8c113c5
--- /dev/null
+++ b/Swift/QtUI/WindowsNotifier.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "WindowsNotifier.h"
+
+#include <QSystemTrayIcon>
+#include <cassert>
+#include <iostream>
+#include <boost/bind.hpp>
+
+#include "QtWin32NotifierWindow.h"
+
+namespace Swift {
+
+WindowsNotifier::WindowsNotifier(const String& name, const boost::filesystem::path& icon, QSystemTrayIcon* tray) : tray(tray) {
+	notifierWindow = new QtWin32NotifierWindow();
+	snarlNotifier = new SnarlNotifier(name, notifierWindow, icon);
+	connect(tray, SIGNAL(messageClicked()), SLOT(handleMessageClicked()));
+}
+
+WindowsNotifier::~WindowsNotifier() {
+	delete snarlNotifier;
+	delete notifierWindow;
+}
+
+void WindowsNotifier::showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback) {
+	if (snarlNotifier->isAvailable()) {
+		snarlNotifier->showMessage(type, subject, description, picture, callback);
+		return;
+	}
+	std::vector<Notifier::Type> defaultTypes = getDefaultTypes();
+	if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) {
+		return;
+	}
+	lastCallback = callback;
+	int timeout = (type == IncomingMessage || type == SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS;
+	tray->showMessage(subject.getUTF8Data(), description.getUTF8Data(), type == SystemMessage ? QSystemTrayIcon::Information : QSystemTrayIcon::NoIcon, timeout * 1000);
+}
+
+void WindowsNotifier::handleMessageClicked() {
+	lastCallback();
+}
+
+}
diff --git a/Swift/QtUI/WindowsNotifier.h b/Swift/QtUI/WindowsNotifier.h
new file mode 100644
index 0000000..dbf86a2
--- /dev/null
+++ b/Swift/QtUI/WindowsNotifier.h
@@ -0,0 +1,36 @@
+/*
+ * 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 <QObject>
+#include <SwifTools/Notifier/Notifier.h>
+#include <SwifTools/Notifier/SnarlNotifier.h>
+
+class QSystemTrayIcon;
+
+namespace Swift {
+	class WindowsNotifier : public QObject, public Notifier {
+			Q_OBJECT
+
+		public:
+			WindowsNotifier(const String& name, const boost::filesystem::path& icon, QSystemTrayIcon* tray);
+			~WindowsNotifier();
+
+			virtual void showMessage(Type type, const String& subject, const String& description, const boost::filesystem::path& picture, boost::function<void()> callback);
+		
+		private slots:
+			void handleMessageClicked();
+
+		private:
+			QSystemTrayIcon* tray;
+			Win32NotifierWindow* notifierWindow;
+			SnarlNotifier* snarlNotifier;
+			boost::function<void()> lastCallback;
+	};
+}
-- 
cgit v0.10.2-6-g49f6