+///////////////////////////////////////////////////////////////////////////////
+// Name: src/gtk/notifmsg.cpp
+// Purpose: wxNotificationMessage for wxGTK using libnotify.
+// Author: Vadim Zeitlin
+// Created: 2012-07-25
+// RCS-ID: $Id$
+// Copyright: (c) 2012 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_NOTIFICATION_MESSAGE
+
+#ifndef WX_PRECOMP
+#endif // WX_PRECOMP
+
+#include "wx/notifmsg.h"
+
+#include <libnotify/notify.h>
+
+#include "wx/module.h"
+
+// General note about error handling: as notifications are meant to be
+// non-intrusive, we use wxLogDebug() and not wxLogError() if anything goes
+// wrong here to avoid spamming the user with message boxes. As all methods
+// return boolean indicating success or failure, the caller could show the
+// notification in some other way or notify about the error itself if needed.
+#include "wx/gtk/private/error.h"
+
+// ----------------------------------------------------------------------------
+// A module for cleaning up libnotify on exit.
+// ----------------------------------------------------------------------------
+
+class wxLibnotifyModule : public wxModule
+{
+public:
+ virtual bool OnInit()
+ {
+ // We're initialized on demand.
+ return true;
+ }
+
+ virtual void OnExit()
+ {
+ if ( notify_is_initted() )
+ notify_uninit();
+ }
+
+ // Do initialize the library.
+ static bool Initialize()
+ {
+ if ( !notify_is_initted() )
+ {
+ if ( !notify_init(wxTheApp->GetAppName().utf8_str()) )
+ return false;
+ }
+
+ return true;
+ }
+
+private:
+ wxDECLARE_DYNAMIC_CLASS(wxLibnotifyModule);
+};
+
+wxIMPLEMENT_DYNAMIC_CLASS(wxLibnotifyModule, wxModule);
+
+// ============================================================================
+// wxNotificationMessage implementation
+// ============================================================================
+
+bool wxNotificationMessage::Show(int timeout)
+{
+ if ( !wxLibnotifyModule::Initialize() )
+ return false;
+
+ // Determine the GTK+ icon to use from flags and also set the urgency
+ // appropriately.
+ const char* icon;
+ NotifyUrgency urgency;
+ switch ( GetFlags() )
+ {
+ case wxICON_INFORMATION:
+ icon = "dialog-information";
+ urgency = NOTIFY_URGENCY_LOW;
+ break;
+
+ case wxICON_WARNING:
+ icon = "dialog-warning";
+ urgency = NOTIFY_URGENCY_NORMAL;
+ break;
+
+ case wxICON_ERROR:
+ icon = "dialog-error";
+ urgency = NOTIFY_URGENCY_CRITICAL;
+ break;
+
+ default:
+ wxFAIL_MSG( "Unknown notification message flags." );
+ return false;
+ }
+
+ // Create the notification or update an existing one if we had already been
+ // shown before.
+ if ( !m_notification )
+ {
+ m_notification = notify_notification_new
+ (
+ GetTitle().utf8_str(),
+ GetMessage().utf8_str(),
+ icon
+ );
+ if ( !m_notification )
+ {
+ wxLogDebug("Failed to creation notification.");
+
+ return false;
+ }
+ }
+ else
+ {
+ if ( !notify_notification_update
+ (
+ m_notification,
+ GetTitle().utf8_str(),
+ GetMessage().utf8_str(),
+ icon
+ ) )
+ {
+ wxLogDebug(wxS("notify_notification_update() unexpectedly failed."));
+ }
+ }
+
+
+ // Set the notification parameters not specified during creation.
+ notify_notification_set_timeout
+ (
+ m_notification,
+ timeout == Timeout_Auto ? NOTIFY_EXPIRES_DEFAULT
+ : timeout == Timeout_Never ? NOTIFY_EXPIRES_NEVER
+ : 1000*timeout
+ );
+
+ notify_notification_set_urgency(m_notification, urgency);
+
+
+ // Finally do show the notification.
+ wxGtkError error;
+ if ( !notify_notification_show(m_notification, error.Out()) )
+ {
+ wxLogDebug("Failed to shown notification: %s", error.GetMessage());
+
+ return false;
+ }
+
+ return true;
+}
+
+bool wxNotificationMessage::Close()
+{
+ wxCHECK_MSG( m_notification, false,
+ wxS("Can't close not shown notification.") );
+
+ wxGtkError error;
+ if ( !notify_notification_close(m_notification, error.Out()) )
+ {
+ wxLogDebug("Failed to hide notification: %s", error.GetMessage());
+
+ return false;
+ }
+
+ return true;
+}
+
+wxNotificationMessage::~wxNotificationMessage()
+{
+ if ( m_notification )
+ g_object_unref(m_notification);
+}
+
+#endif // wxUSE_NOTIFICATION_MESSAGE