debian/0000755000000000000000000000000012156613374007176 5ustar debian/copyright0000644000000000000000000000425311201357465011131 0ustar This package was debianized by Varun Hiremath on Sat, 18 Nov 2006 00:46:10 +0530. It was downloaded from Upstream Author: Duarte Henriques Copyright: © 2005-2006 Duarte Henriques Copyright Translations: © 2005 Ezequiel Prez © 2005 Ersplus © 2006 Marco Cabizza © 2006 Raymond Jelierse © 2006 Krzysztof Rosiski © 2006 Everson Araujo © 2005-2006 Duarte Henriques License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. On Debian systems, you can find the GPL license in: /usr/share/common-licenses/GPL ------- The files in intl/* are copyright: © 1995-2001 Free Software Foundation, Inc. Some of the files are contributed by: Ulrich Drepper , 1995. The files are licensed as follows: This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. On Debian systems, you can find the Library GPL license in: /usr/share/common-licenses/LGPL-2 The Debian packaging is © 2006, Varun Hiremath and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. debian/changelog0000644000000000000000000001363012156613364011052 0ustar pidgin-libnotify (0.14-9ubuntu2) saucy; urgency=low * debian/patches/messaging_menu.patch: - Use purple_buddy_get_name() instead of sender in unique id if possible (LP: #1175537) - Associate a buddy name with a conversation if possible, otherwise fall back to the name of the conversation. -- Jason Conti Mon, 20 May 2013 18:20:04 -0400 pidgin-libnotify (0.14-9ubuntu1) raring; urgency=low * libmessaging-menu support (LP: #1040259) * debian/control: - drop indicate build-dep - add libmessaging-menu-dev * debian/patches/ubuntu_notify_support.patch: - Split out notify changes from messaging-menu changes (was combined in indicate.patch) - Merged libnotify-0.7.patch * debian/patches/messaging_menu.patch: - messaging-menu support. -- Jason Conti Sun, 21 Oct 2012 15:17:58 -0400 pidgin-libnotify (0.14-9) unstable; urgency=low * Merge changes from Ubuntu - d/control: add Build-Depends: libindicate-dev, libindicate-gtk-dev - add patches: best_name.patch, libnotify_0_7.patch, force-load.patch, indicate.patch, update others - remove patches: fix-libnotify0.7-compatibility.diff, fix-notify-osd.diff, transient-hint-on-event-notifications.diff, fix-printf-warnings.diff, chat-nick-test-optional.diff * Update debian/rules based on Ubuntu changes -- Varun Hiremath Wed, 08 Aug 2012 16:01:15 -0400 pidgin-libnotify (0.14-8) unstable; urgency=low * debian/rules: include autoreconf.mk (Closes: #657920) * debian/control: Build-Depend on dh-autoreconf -- Varun Hiremath Thu, 22 Mar 2012 19:40:23 -0400 pidgin-libnotify (0.14-7) unstable; urgency=low * debian/patches: - replace-pidgin-action-requests.diff, use libnotify (Closes: #640728) - transient-hint-on-event-notifications.diff, use "transient" hint for event notifications (Closes: #640835) -- Varun Hiremath Tue, 24 Jan 2012 17:11:58 -0500 pidgin-libnotify (0.14-6) unstable; urgency=low * debian/patches - chat-nick-test-optional.diff, make nick presence optional (Closes: #638901) - fix-printf-warnings.diff , fix compiler warnings (Closes: #638899) - fix-notify-osd.diff, fix notify issues (Closes: #635614, #549265) - add-cs-translation.diff, add Czech translation (Closes: #638902) * Thanks to Jakub Adam for providing the above patches -- Varun Hiremath Fri, 26 Aug 2011 23:35:52 -0400 pidgin-libnotify (0.14-5) unstable; urgency=low * Add patches/fix-libnotify0.7-compatibility.diff to add compatibility with libnotify 0.7, thanks to Jérémy Bobbio (Closes: #630295) * Remove unneeded pidgin-libnotify.la file (Closes: #633288) * Bump Standards-Version to 3.9.2 -- Varun Hiremath Wed, 20 Jul 2011 20:34:48 -0400 pidgin-libnotify (0.14-4) unstable; urgency=low * Swicth to source format 3.0 * Bum Standards-Version to 3.8.3 * Add patch fix-notify-osd.diff to disable show button for working with notify-osd, thanks to Lubomír Sedlár * Add it_po.diff to update Italian translation, thanks to Milo Casagrande (Closes: #555789) -- Varun Hiremath Sun, 24 Jan 2010 13:25:57 -0500 pidgin-libnotify (0.14-3) unstable; urgency=low * Add de_po.diff patch to fix a German translation, thanks to Jürgen Göricke (Closes: #522952) -- Varun Hiremath Sat, 09 May 2009 15:39:47 -0400 pidgin-libnotify (0.14-2) unstable; urgency=low * upload to unstable -- Torsten Werner Sun, 15 Feb 2009 22:45:55 +0100 pidgin-libnotify (0.14-1) experimental; urgency=low * New upstream release * Bump up Standards-Version: 3.8.0. -- Torsten Werner Sun, 28 Dec 2008 17:52:00 +0100 pidgin-libnotify (0.13-2) unstable; urgency=low * Add patches/show_button_fix.diff to fix issues with the show button in the notification window (Closes: #456218) * debian/control: + Add quilt to Build-Depends + Update Standards-Version to 3.7.3 -- Varun Hiremath Mon, 17 Dec 2007 16:26:02 +0530 pidgin-libnotify (0.13-1) unstable; urgency=low [ Varun Hiremath ] * New upstream release * debian/control: + Add Homepage header and rename XS-Vcs to Vcs + Remove gaim-libnotify transition package * Fix watch file. * Remove old patches - no longer required. [ Torsten Werner ] * Do not run automake + autoconf and remove the Build-Depends. * Build with pidgin-dev 2.3.0. (Closes: #454170) -- Torsten Werner Tue, 04 Dec 2007 07:03:40 +0100 pidgin-libnotify (0.12-4) unstable; urgency=low * debian/rules: call dh_pidgin and remove duplicate-relation depends: pidgin (>= 2.0), pidgin (<< 3.0) from debian/control -- Varun Hiremath Thu, 09 Aug 2007 23:23:58 +0530 pidgin-libnotify (0.12-3) unstable; urgency=low * debian/control: Add Depends: pidgin (>= 2.0), pidgin (<< 3.0) to avoid breaking when upgraded to pidgin 3.0 (Closes: #433407) -- Varun Hiremath Tue, 17 Jul 2007 10:30:13 +0530 pidgin-libnotify (0.12-2) unstable; urgency=low * Switch to pidgin. (Closes: #424685) * Rename the package to pidgin-libnotify and add a dummy package to ease upgrades. * Add NEWS.Debian to explain the transition. * Implement get-orig-source as suggested by the Debian policy. -- Torsten Werner Sun, 20 May 2007 13:26:57 +0200 gaim-libnotify (0.12-1) unstable; urgency=low [ Varun Hiremath ] * Initial release (Closes: #359955) [ Torsten Werner ] * Disable static library creation because it cannot be used. * Add myself to Uploaders in debian/control. * Add XS-X-Vcs-Svn header in debian/control. -- Torsten Werner Mon, 20 Nov 2006 06:45:09 +0100 debian/rules0000755000000000000000000000062612010531327010244 0ustar #!/usr/bin/make -f include /usr/share/cdbs/1/rules/autoreconf.mk include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/gnome.mk DEB_CONFIGURE_EXTRA_FLAGS := --disable-static DEB_DH_MAKESHLIBS_ARGS := -Xpidgin-libnotify install/pidgin-libnotify:: find debian/pidgin-libnotify -name \*.la -delete dh_pidgin -ppidgin-libnotify get-orig-source: uscan --force-download --rename debian/source/0000755000000000000000000000000012010542642010462 5ustar debian/source/format0000644000000000000000000000001411327112627011676 0ustar 3.0 (quilt) debian/control0000644000000000000000000000151412051401733010566 0ustar Source: pidgin-libnotify Section: net Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Varun Hiremath Build-Depends: debhelper (>= 7), cdbs, intltool, pkg-config, libnotify-dev, libglib2.0-dev, libgtk2.0-dev, libtool, pidgin-dev, dh-autoreconf, libmessaging-menu-dev (>= 12.10.4) Standards-Version: 3.9.3 Homepage: http://gaim-libnotify.sourceforge.net Vcs-Svn: https://bollin.googlecode.com/svn/pidgin-libnotify/trunk/ Vcs-Browser: http://bollin.googlecode.com/svn/pidgin-libnotify/trunk/ Package: pidgin-libnotify Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: display notification bubbles in pidgin pidgin-libnotify is a Pidgin plugin which displays notification bubbles in Pidgin using libnotify and notification-daemon. debian/compat0000644000000000000000000000000211327112627010366 0ustar 7 debian/watch0000644000000000000000000000010710725050046010214 0ustar version=3 http://sf.net/gaim-libnotify/ pidgin-libnotify-(.*)\.tar\.gz debian/docs0000644000000000000000000000002110530036131010022 0ustar NEWS README TODO debian/patches/0000755000000000000000000000000012156613364010624 5ustar debian/patches/it_po.diff0000644000000000000000000000675511327112627012600 0ustar diff -urN pidgin-libnotify-0.14.orig/po/it.po pidgin-libnotify-0.14/po/it.po --- pidgin-libnotify-0.14.orig/po/it.po 2010-01-24 13:31:58.000000000 -0500 +++ pidgin-libnotify-0.14/po/it.po 2010-01-24 13:32:31.000000000 -0500 @@ -1,79 +1,76 @@ # Italian (it) translation of gaim-libnotify. -# Copyright (C) 2006, Marco Cabizza -# # This file is distributed under the same license as gaim-libnotify. +# Copyright (C) 2006, Marco Cabizza +# Copyright (C) 2009, The Free Software Foundation, Inc. +# Gruppo traduzione italiano di Ubuntu, +# Milo Casagrande # msgid "" msgstr "" "Project-Id-Version: gaim-libnotify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-06-30 19:58+0000\n" -"PO-Revision-Date: 2007-05-25 12:30-0300\n" -"Last-Translator: Marco Cabizza \n" +"POT-Creation-Date: 2009-09-29 16:23+0000\n" +"PO-Revision-Date: 2009-11-04 15:15+0000\n" +"Last-Translator: Milo Casagrande \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Launchpad-Export-Date: 2009-11-11 17:20+0000\n" +"X-Generator: Launchpad (build Unknown)\n" -#: src/pidgin-libnotify.c:57 -#, fuzzy +#: ../src/pidgin-libnotify.c:95 msgid "New messages" msgstr "Nuovi messaggi" -#: src/pidgin-libnotify.c:62 +#: ../src/pidgin-libnotify.c:100 msgid "Only new conversations" -msgstr "Solo le nuove finestre" +msgstr "Solo nuove conversazioni" -#: src/pidgin-libnotify.c:67 +#: ../src/pidgin-libnotify.c:105 msgid "Ignore events from blocked users" -msgstr "Ignora gli utenti bloccati" +msgstr "Ignora eventi da utenti bloccati" -#: src/pidgin-libnotify.c:72 -#, fuzzy +#: ../src/pidgin-libnotify.c:110 msgid "Buddy signs on" -msgstr "%s entra" +msgstr "Il conoscente si connette" -#: src/pidgin-libnotify.c:77 -#, fuzzy +#: ../src/pidgin-libnotify.c:115 msgid "Buddy signs off" -msgstr "%s entra" +msgstr "Il conoscente si disconnette" + +#: ../src/pidgin-libnotify.c:120 +msgid "Only when available" +msgstr "Solo quando disponibile" -#: src/pidgin-libnotify.c:315 +#: ../src/pidgin-libnotify.c:125 +msgid "Names to remove notifications for" +msgstr "Nomi per cui rimuovere le notifiche" + +#: ../src/pidgin-libnotify.c:505 msgid "Show" msgstr "Mostra" -#: src/pidgin-libnotify.c:347 -#, c-format -msgid "%s signed on" -msgstr "%s è entrato" - -#: src/pidgin-libnotify.c:379 -#, fuzzy, c-format -msgid "%s signed off" -msgstr "%s è entrato" - -#: src/pidgin-libnotify.c:406 -#, c-format -msgid "%s says:" -msgstr "%s dice:" +#: ../src/pidgin-libnotify.c:538 +msgid "is online" +msgstr "è in linea" + +#: ../src/pidgin-libnotify.c:567 +msgid "is offline" +msgstr "non è in linea" -#: src/pidgin-libnotify.c:572 +#: ../src/pidgin-libnotify.c:1399 msgid "Libnotify Popups" -msgstr "Popups di libnotify" +msgstr "Notifiche di libnotify" -#: src/pidgin-libnotify.c:573 +#: ../src/pidgin-libnotify.c:1400 msgid "Displays popups via libnotify." -msgstr "Mostra avvisi mediante libnotify." +msgstr "Visualizza le notifiche mediante libnotify." -#: src/pidgin-libnotify.c:574 -#, fuzzy +#: ../src/pidgin-libnotify.c:1401 msgid "" "Pidgin-libnotify:\n" "Displays popups via libnotify." msgstr "" -"Gaim-libnotify:\n" -"Mostra avvisi mediante libnotify." - -#~ msgid "Libnotify Interface" -#~ msgstr "Interfaccia libnotify" +"Pidgin-libnotify:\n" +"Visualizza le notifiche mediante libnotify." debian/patches/replace-pidgin-action-requests.diff0000644000000000000000000003277012051402055017461 0ustar From 9c39dfc1c415d017057f8a87d503b9a3f9f26603 Mon Sep 17 00:00:00 2001 From: Jakub Adam Date: Tue, 6 Sep 2011 22:58:23 +0200 Subject: [PATCH] replace-pidgin-action-requests.diff --- po/cs.po | 20 +++-- src/Makefile.am | 3 + src/common.c | 67 ++++++++++++++++++ src/common.h | 38 ++++++++++ src/pidgin-libnotify.c | 37 +++++----- src/request.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 320 insertions(+), 27 deletions(-) create mode 100644 src/common.c create mode 100644 src/common.h create mode 100644 src/request.c Index: pidgin-libnotify-0.14/po/cs.po =================================================================== --- pidgin-libnotify-0.14.orig/po/cs.po 2012-11-16 10:15:18.539589953 +0100 +++ pidgin-libnotify-0.14/po/cs.po 2012-11-16 10:15:19.187589931 +0100 @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: pidgin-libnotify\n" -"POT-Creation-Date: 2011-08-21 12:58+0200\n" +"POT-Creation-Date: 2011-09-06 22:17+0200\n" "PO-Revision-Date: 2011-08-21 00:00::00+GMT\n" "Last-Translator: Jakub Adam \n" "MIME-Version: 1.0\n" @@ -45,34 +45,38 @@ msgid "Only when available" msgstr "Jen, když jsem k dispozici" -#: ../src/pidgin-libnotify.c:342 +#: ../src/pidgin-libnotify.c:102 +msgid "Replace Pidgin request dialogs with libnotify popups" +msgstr "Nahradit dotazovací dialogy Pidginu" + +#: ../src/pidgin-libnotify.c:338 msgid "Show" msgstr "Ukaž" -#: ../src/pidgin-libnotify.c:375 +#: ../src/pidgin-libnotify.c:368 #, c-format msgid "%s signed on" msgstr "%s se přihlásil" -#: ../src/pidgin-libnotify.c:407 +#: ../src/pidgin-libnotify.c:400 #, c-format msgid "%s signed off" msgstr "%s se odhlásil" -#: ../src/pidgin-libnotify.c:434 +#: ../src/pidgin-libnotify.c:427 #, c-format msgid "%s says:" msgstr "%s napsal:" -#: ../src/pidgin-libnotify.c:610 +#: ../src/pidgin-libnotify.c:606 msgid "Libnotify Popups" msgstr "Vyskakovací okna libnotify" -#: ../src/pidgin-libnotify.c:611 +#: ../src/pidgin-libnotify.c:607 msgid "Displays popups via libnotify." msgstr "Zobrazuje vyskakovací okna pomocí libnotify" -#: ../src/pidgin-libnotify.c:612 +#: ../src/pidgin-libnotify.c:608 msgid "" "Pidgin-libnotify:\n" "Displays popups via libnotify." Index: pidgin-libnotify-0.14/src/Makefile.am =================================================================== --- pidgin-libnotify-0.14.orig/src/Makefile.am 2012-11-16 10:14:30.371591653 +0100 +++ pidgin-libnotify-0.14/src/Makefile.am 2012-11-16 10:15:19.187589931 +0100 @@ -8,6 +8,9 @@ pidgin_libnotify_la_SOURCES = \ pidgin-libnotify.c \ + common.h \ + common.c \ + request.c \ gln_intl.h pidgin_libnotify_la_LIBADD = $(LIBNOTIFY_LIBS) $(DBUS_LIBS) $(GTK_LIBS) Index: pidgin-libnotify-0.14/src/common.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ pidgin-libnotify-0.14/src/common.c 2012-11-16 10:15:19.191589930 +0100 @@ -0,0 +1,67 @@ +/* + * Pidgin-libnotify - Provides a libnotify interface for Pidgin + * Copyright (C) 2005-2007 Duarte Henriques + * Copyright (C) 2011 Jakub Adam + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "common.h" + +#include +#include + +gboolean +server_has_caps(const char *id) +{ + GList *caps = notify_get_server_caps(); + gboolean result; + result = (g_list_find_custom(caps, id, (GCompareFunc)g_strcmp0) != NULL); + g_list_free_full(caps, g_free); + return result; +} + +typedef struct { + int id; + PurpleRequestActionCb callback; +} ActionData; + +NotifyNotification * +notification_new(const gchar *title, const gchar *body) +{ + NotifyNotification *notification; + +/* libnotify 0.7.0 and later has no support for attaching to widgets */ +#if NOTIFY_CHECK_VERSION(0,7,0) + notification = notify_notification_new(title, body, NULL); +#else + notification = notify_notification_new(title, body, NULL, NULL); +#endif + purple_debug_info(PLUGIN_ID, "notification_new(), title: '%s', body: '%s'", + title, body); + + notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL); + + return notification; +} + +void +notification_show(NotifyNotification *notification) +{ + if (!notify_notification_show (notification, NULL)) { + purple_debug_error (PLUGIN_ID, "notification_show(), " + "failed to send notification\n"); + } +} Index: pidgin-libnotify-0.14/src/common.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ pidgin-libnotify-0.14/src/common.h 2012-11-16 10:15:19.191589930 +0100 @@ -0,0 +1,38 @@ +/* + * Pidgin-libnotify - Provides a libnotify interface for Pidgin + * Copyright (C) 2005-2007 Duarte Henriques + * Copyright (C) 2011 Jakub Adam + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PIDGIN_LIBNOTIFY_COMMON_H +#define PIDGIN_LIBNOTIFY_COMMON_H + +#include + +#define PLUGIN_ID "pidgin-libnotify" + +#ifndef NOTIFY_CHECK_VERSION +#define NOTIFY_CHECK_VERSION(x,y,z) 0 +#endif + +gboolean server_has_caps(const char *id); + +NotifyNotification * notification_new(const gchar *title, const gchar *body); + +void notification_show(NotifyNotification *notification); + +#endif // PIDGIN_LIBNOTIFY_COMMON_H Index: pidgin-libnotify-0.14/src/pidgin-libnotify.c =================================================================== --- pidgin-libnotify-0.14.orig/src/pidgin-libnotify.c 2012-11-16 10:15:16.971590010 +0100 +++ pidgin-libnotify-0.14/src/pidgin-libnotify.c 2012-11-16 10:15:19.191589930 +0100 @@ -21,6 +21,7 @@ #include #endif +#include "common.h" #include "gln_intl.h" #ifndef PURPLE_PLUGINS @@ -82,6 +83,11 @@ _("Only when available")); purple_plugin_pref_frame_add (frame, ppref); + ppref = purple_plugin_pref_new_with_name_and_label ( + "/plugins/gtk/libnotify/replace_requests", + _("Replace Pidgin request dialogs with libnotify popups")); + purple_plugin_pref_frame_add (frame, ppref); + return frame; } @@ -463,6 +469,9 @@ notify_msg_sent (account, sender, message); } +extern void attach_request_ui_ops (); +extern void detach_request_ui_ops (); + static gboolean plugin_load (PurplePlugin *plugin) { @@ -495,6 +504,8 @@ purple_signal_connect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle), NULL); + attach_request_ui_ops (); + return TRUE; } @@ -522,6 +533,8 @@ purple_signal_disconnect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle)); + detach_request_ui_ops (); + g_hash_table_destroy (buddy_hash); notify_uninit (); Index: pidgin-libnotify-0.14/src/request.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ pidgin-libnotify-0.14/src/request.c 2012-11-16 10:15:19.191589930 +0100 @@ -0,0 +1,182 @@ +/* + * Pidgin-libnotify - Provides a libnotify interface for Pidgin + * Copyright (C) 2011 Jakub Adam + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "common.h" + +typedef struct { + int id; + PurpleRequestActionCb callback; +} ActionData; + +static void +action_cb (NotifyNotification *notification, char *action, + ActionData *data) +{ + data->callback(g_object_get_data(G_OBJECT(notification), "user_data"), + data->id); +} + +GSList *req_notifications = NULL; + +static gboolean +closed_cb (NotifyNotification *notification) +{ + req_notifications = g_slist_remove(req_notifications, notification); + g_object_unref(G_OBJECT(notification)); + + return FALSE; +} + +static gchar * +remove_accelerators (const gchar *s) +{ + gchar **split = g_strsplit(s, "_", -1); + gchar *result = g_strjoinv("", split); + g_strfreev(split); + return result; +} + +static PurpleRequestUiOps ops; +static PurpleRequestUiOps *original_ops = NULL; + +static void * +notify_request_action_with_icon(const char *title, const char *primary, + const char *secondary, int default_action, + PurpleAccount *account, const char *who, + PurpleConversation *conv, + gconstpointer icon_data, gsize icon_size, + void *user_data, + size_t action_count, va_list actions) +{ + NotifyNotification *notification; + int i; + + if (!purple_prefs_get_bool("/plugins/gtk/libnotify/replace_requests") || + !server_has_caps("actions")) { + return original_ops->request_action_with_icon(title, primary, secondary, + default_action, account, + who, conv, icon_data, + icon_size, user_data, + action_count, actions); + } + + notification = notification_new(primary, secondary); + + if (icon_data) { + GdkPixbuf *pixbuf = pidgin_pixbuf_from_data(icon_data, icon_size); + if (pixbuf) { + notify_notification_set_icon_from_pixbuf(notification, pixbuf); + g_object_unref (pixbuf); + } else { + purple_debug_warning(PLUGIN_ID, "notify_request_action_with_icon(), " + "failed to parse request icon\n"); + } + } + + notify_notification_set_hint(notification, "resident", + g_variant_new_boolean(TRUE)); + notify_notification_set_timeout(notification, NOTIFY_EXPIRES_NEVER); + + g_signal_connect(notification, "closed", G_CALLBACK(closed_cb), NULL); + + for (i = 0; i != action_count; ++i) { + char *label = remove_accelerators(va_arg (actions, const char *)); + ActionData *data = g_new(ActionData, 1); + data->id = i; + data->callback = va_arg(actions, PurpleRequestActionCb); + + notify_notification_add_action(notification, + (default_action == i) ? "default" : label, + label, + (NotifyActionCallback) action_cb, + data, g_free); + g_free(label); + } + + g_object_set_data(G_OBJECT(notification), "user_data", user_data); + + req_notifications = g_slist_append(req_notifications, notification); + + notification_show(notification); + + return notification; +} + +static void * +notify_request_action(const char *title, const char *primary, + const char *secondary, int default_action, + PurpleAccount *account, const char *who, + PurpleConversation *conv, void *user_data, + size_t action_count, va_list actions) +{ + if (!purple_prefs_get_bool("/plugins/gtk/libnotify/replace_requests") || + !server_has_caps("actions")) { + return original_ops->request_action(title, primary, secondary, + default_action, account, who, conv, + user_data, action_count, actions); + } + + return notify_request_action_with_icon(title, primary, secondary, + default_action, account, who, conv, + NULL, 0, user_data, action_count, + actions); +} + +static void +notify_close_request(PurpleRequestType type, void *ui_handle) +{ + GSList *l = g_slist_find(req_notifications, ui_handle); + if (l) { + NotifyNotification *notification = l->data; + notify_notification_close(notification, NULL); + } else { + original_ops->close_request(type, ui_handle); + } +} + +void +attach_request_ui_ops() +{ + original_ops = purple_request_get_ui_ops(); + if (original_ops) { + memcpy(&ops, original_ops, sizeof (ops)); + ops.request_action = notify_request_action; + ops.request_action_with_icon = notify_request_action_with_icon; + ops.close_request = notify_close_request; + purple_request_set_ui_ops(&ops); + } +} + +void +detach_request_ui_ops() +{ + if (original_ops) { + purple_request_set_ui_ops(original_ops); + } +} debian/patches/messaging_menu.patch0000644000000000000000000004230512156613364014652 0ustar === modified file 'configure.ac' --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,15 @@ AC_SUBST(LIBNOTIFY_LIBS) # +# Check for libmessaging-menu +# + +PKG_CHECK_MODULES(LIBMESSAGINGMENU, messaging-menu >= 12.10.4) + +AC_SUBST(LIBMESSAGINGMENU_CFLAGS) +AC_SUBST(LIBMESSAGINGMENU_LIBS) + +# # Check for GTK+ # PKG_CHECK_MODULES(GTK, gtk+-2.0) --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ request.c \ gln_intl.h -pidgin_libnotify_la_LIBADD = $(LIBNOTIFY_LIBS) $(DBUS_LIBS) $(GTK_LIBS) +pidgin_libnotify_la_LIBADD = $(LIBMESSAGINGMENU_LIBS) $(LIBNOTIFY_LIBS) $(DBUS_LIBS) $(GTK_LIBS) endif @@ -27,6 +27,7 @@ $(PIDGIN_CFLAGS) \ $(LIBPURPLE_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ + $(LIBMESSAGINGMENU_CFLAGS) \ $(DBUS_CFLAGS) \ $(GTK_CFLAGS) --- a/src/pidgin-libnotify.c +++ b/src/pidgin-libnotify.c @@ -24,6 +24,8 @@ #include "common.h" #include "gln_intl.h" +#include + #ifndef PURPLE_PLUGINS #define PURPLE_PLUGINS #endif @@ -39,6 +41,7 @@ #include #include +#include #include @@ -49,7 +52,7 @@ #endif #define G_LOG_DOMAIN "pidgin-libnotify-plugin" -#define PIDGIN_DESKTOP_FILE "/usr/share/applications/pidgin.desktop" +#define PIDGIN_DESKTOP_FILE "pidgin.desktop" #define BLACKLIST_FILENAME "pidgin-libnotify" #define BLACKLIST_DIR "indicators/messages/applications-blacklist" @@ -59,6 +62,8 @@ /* Globals */ static GHashTable *buddy_hash; +static MessagingMenuApp *m_menu_app = NULL; + static gboolean notify_supports_actions = FALSE; static gboolean notify_supports_append = FALSE; static gboolean notify_supports_truncation = FALSE; @@ -844,10 +849,422 @@ extern void attach_request_ui_ops (); extern void detach_request_ui_ops (); +static gchar * +messaging_unique_id (const char *type, + PurpleAccount *account, + const char *name) +{ + g_return_val_if_fail (type != NULL, NULL); + g_return_val_if_fail (account != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + gchar *escaped_type = g_uri_escape_string (type, NULL, TRUE); + gchar *buddy_name = g_uri_escape_string (name, NULL, TRUE); + gchar *account_name = g_uri_escape_string (purple_account_get_username (account), NULL, TRUE); + gchar *protocol_id = g_uri_escape_string (purple_account_get_protocol_id (account), NULL, TRUE); + gchar *unique_id = g_strconcat (escaped_type, ":", protocol_id, ":", account_name, + ":", buddy_name, NULL); + + g_free (escaped_type); + g_free (buddy_name); + g_free (account_name); + g_free (protocol_id); + + return unique_id; +} + +static PurpleConversation * +messaging_conversation_for_unique_id (const gchar *unique_id) +{ + g_return_val_if_fail (unique_id != NULL, NULL); + + gchar **tokens = g_strsplit(unique_id, ":", 0); + guint n_tokens = g_strv_length(tokens); + + if (n_tokens != 4) { + purple_debug_warning (PLUGIN_ID, "Invalid unique_id '%s'\n", unique_id); + g_strfreev (tokens); + return NULL; + } + + gchar *type_id = g_uri_unescape_string(tokens[0], NULL); + gchar *protocol_id = g_uri_unescape_string(tokens[1], NULL); + gchar *account_name = g_uri_unescape_string(tokens[2], NULL); + gchar *buddy_name = g_uri_unescape_string(tokens[3], NULL); + + PurpleAccount *account = purple_accounts_find (account_name, protocol_id); + + if (account == NULL) { + g_free (type_id); + g_free (protocol_id); + g_free (account_name); + g_free (buddy_name); + g_strfreev (tokens); + return NULL; + } + + PurpleConversationType conv_type = PURPLE_CONV_TYPE_IM; + if (g_strcmp0 (type_id, "chat") == 0) + conv_type = PURPLE_CONV_TYPE_CHAT; + + PurpleConversation *conv = purple_find_conversation_with_account (conv_type, + buddy_name, account); + + g_free (type_id); + g_free (protocol_id); + g_free (account_name); + g_free (buddy_name); + g_strfreev (tokens); + + return conv; +} + +static const char * +messaging_type_from_conv_type (PurpleConversationType type) +{ + const char *messaging_type; + + switch (type) { + case PURPLE_CONV_TYPE_IM: + messaging_type = "im"; + break; + case PURPLE_CONV_TYPE_CHAT: + messaging_type = "chat"; + break; + default: + purple_debug_warning (PLUGIN_ID, "Unsupported conversation type\n"); + messaging_type = "unknown"; + break; + } + + return messaging_type; +} + +static const char * +messaging_conversation_get_name (PurpleConversation *conv, + PurpleAccount *account) +{ + PurpleBuddy *buddy = NULL; + + if (purple_conversation_get_type (conv) == PURPLE_CONV_TYPE_IM) + buddy = purple_find_buddy (account, purple_conversation_get_name (conv)); + if (buddy != NULL) + return purple_buddy_get_name (buddy); + return purple_conversation_get_name (conv); +} + +static void +messaging_conversation_updated_cb (PurpleConversation *conv, + PurpleConvUpdateType type, + gpointer user_data) +{ + g_return_if_fail (m_menu_app != NULL); + + const char *type_name; + const char *conv_type = messaging_type_from_conv_type (purple_conversation_get_type (conv)); + PurpleAccount *account; + gchar *buddy_id; + int unseen_count; + + switch (type) { + case PURPLE_CONV_UPDATE_ADD: + type_name = "ADD"; + break; + case PURPLE_CONV_UPDATE_REMOVE: + type_name = "REMOVE"; + break; + case PURPLE_CONV_UPDATE_ACCOUNT: + type_name = "ACCOUNT"; + break; + case PURPLE_CONV_UPDATE_TYPING: + type_name = "TYPING"; + break; + case PURPLE_CONV_UPDATE_UNSEEN: + type_name = "UNSEEN"; + break; + case PURPLE_CONV_UPDATE_LOGGING: + type_name = "LOGGING"; + break; + case PURPLE_CONV_UPDATE_TOPIC: + type_name = "TOPIC"; + break; + default: + type_name = "OTHER"; + } + purple_debug_info (PLUGIN_ID, "Conversation Updated (%s)\n", type_name); + + /* Remove the attention */ + if (type == PURPLE_CONV_UPDATE_UNSEEN) { + unseen_count = GPOINTER_TO_INT(purple_conversation_get_data (conv, "unseen-count")); + account = purple_conversation_get_account (conv); + buddy_id = messaging_unique_id (conv_type, account, + messaging_conversation_get_name (conv, account)); + + if (buddy_id != NULL) { + if (messaging_menu_app_has_source (m_menu_app, buddy_id)) { + if (unseen_count == 0) { + purple_debug_info (PLUGIN_ID, "REMOVING ATTENTION FOR (%s) (%d)\n", + buddy_id, unseen_count); + messaging_menu_app_remove_attention (m_menu_app, buddy_id); + } + else if (purple_conversation_get_type (conv) == PURPLE_CONV_TYPE_IM) { + messaging_menu_app_draw_attention (m_menu_app, buddy_id); + } + } + } + g_free (buddy_id); + } +} + +static void +messaging_conversation_deleted_cb (PurpleConversation *conv, + gpointer user_data) +{ + g_return_if_fail (conv != NULL); + + PurpleAccount *account; + const char *conv_type = messaging_type_from_conv_type (purple_conversation_get_type (conv)); + gchar *buddy_id; + + account = purple_conversation_get_account (conv); + buddy_id = messaging_unique_id (conv_type, account, + messaging_conversation_get_name (conv, account)); + + if (buddy_id != NULL) { + if (messaging_menu_app_has_source (m_menu_app, buddy_id)) { + purple_debug_info (PLUGIN_ID, "Removing source (%s)\n", buddy_id); + messaging_menu_app_remove_source (m_menu_app, buddy_id); + } + } + + g_free (buddy_id); +} + +static gboolean +pidgin_conversation_has_focus (PurpleConversation *conv) +{ + if (conv == NULL) + return FALSE; + + PidginConversation * pconv = PIDGIN_CONVERSATION(conv); + + if (pconv != NULL) { + if (pconv->entry != NULL && pconv->imhtml != NULL) { + if (GTK_WIDGET_HAS_FOCUS(pconv->entry) || GTK_WIDGET_HAS_FOCUS(pconv->imhtml)) { + return TRUE; + } + } + } + + return FALSE; +} + +static void +messaging_new_message_cb (PurpleAccount *account, + const gchar *sender, + const gchar *message, + int flags, + gpointer user_data) +{ + g_return_if_fail (m_menu_app != NULL); + + PurpleBuddy *buddy = NULL; + gchar *buddy_id; + const char *buddy_name = NULL; + + if (name_blacklisted(account, sender)) + return; + + if (g_list_find (just_signed_on_accounts, account)) + return; + + if (account == NULL || sender == NULL) + return; + + buddy = purple_find_buddy (account, sender); + + if (buddy != NULL) + buddy_name = purple_buddy_get_name (buddy); + + buddy_id = messaging_unique_id ("im", account, buddy_name != NULL ? buddy_name : sender); + + if (buddy_id != NULL) { + purple_debug_info (PLUGIN_ID, "Sender: (%s) ID (%s) \n", sender, buddy_id); + if (messaging_menu_app_has_source (m_menu_app, buddy_id)) { + messaging_menu_app_set_source_time (m_menu_app, buddy_id, g_get_real_time ()); + } + else { + messaging_menu_app_append_source (m_menu_app, buddy_id, NULL, + buddy != NULL ? best_name (buddy) : sender); + } + } + + g_free (buddy_id); +} + +static void +messaging_new_chat_cb (PurpleAccount *account, + const gchar *sender, + const gchar *message, + PurpleConversation *conv, + gpointer user_data) +{ + g_return_if_fail (m_menu_app != NULL); + + purple_debug_info (PLUGIN_ID, "Chat (%s) (%s)\n", sender, message); + + if (name_blacklisted(account, sender)) return; + + const char *nick = purple_conv_chat_get_nick (PURPLE_CONV_CHAT(conv)); + if (nick && !g_strcmp0 (sender, nick)) + return; + + if (!purple_utf8_has_word (message, nick)) + return; + + char *buddy_id = messaging_unique_id ("chat", account, purple_conversation_get_name (conv)); + + if (buddy_id != NULL) { + if (messaging_menu_app_has_source (m_menu_app, buddy_id)) { + messaging_menu_app_set_source_time (m_menu_app, buddy_id, g_get_real_time ()); + } + else { + messaging_menu_app_append_source (m_menu_app, buddy_id, NULL, + purple_conversation_get_title (conv)); + } + if (!pidgin_conversation_has_focus (conv)) + messaging_menu_app_draw_attention (m_menu_app, buddy_id); + } + + g_free (buddy_id); +} + +static MessagingMenuStatus +purple_status_to_messaging_status (PurpleStatusPrimitive status) +{ + MessagingMenuStatus messaging_status_value; + + switch (status) { + case PURPLE_STATUS_AVAILABLE: + messaging_status_value = MESSAGING_MENU_STATUS_AVAILABLE; + break; + case PURPLE_STATUS_AWAY: + messaging_status_value = MESSAGING_MENU_STATUS_AWAY; + break; + case PURPLE_STATUS_UNAVAILABLE: + messaging_status_value = MESSAGING_MENU_STATUS_BUSY; + break; + case PURPLE_STATUS_INVISIBLE: + messaging_status_value = MESSAGING_MENU_STATUS_INVISIBLE; + break; + case PURPLE_STATUS_OFFLINE: + messaging_status_value = MESSAGING_MENU_STATUS_OFFLINE; + break; + default: + messaging_status_value = MESSAGING_MENU_STATUS_AVAILABLE; + } + + return messaging_status_value; +} + +static void +messaging_set_status_from_savedstatus (PurpleSavedStatus *status) +{ + g_return_if_fail (m_menu_app != NULL); + + PurpleStatusPrimitive purple_status = purple_savedstatus_get_type (status); + const char *status_id = purple_primitive_get_id_from_type (purple_status); + MessagingMenuStatus messaging_status = purple_status_to_messaging_status (purple_status); + messaging_menu_app_set_status (m_menu_app, messaging_status); + purple_debug_info (PLUGIN_ID, "Updating status set from pidgin to '%s'\n", status_id); +} + +static void +messaging_savedstatus_changed_cb (PurpleSavedStatus *now, + PurpleSavedStatus *old, + gpointer user_data) +{ + messaging_set_status_from_savedstatus (now); +} + +static PurpleStatusPrimitive +messaging_status_to_purple_status (MessagingMenuStatus status) +{ + PurpleStatusPrimitive purple_status_value; + + switch (status) { + case MESSAGING_MENU_STATUS_AVAILABLE: + purple_status_value = PURPLE_STATUS_AVAILABLE; + break; + case MESSAGING_MENU_STATUS_AWAY: + purple_status_value = PURPLE_STATUS_AWAY; + break; + case MESSAGING_MENU_STATUS_BUSY: + purple_status_value = PURPLE_STATUS_UNAVAILABLE; + break; + case MESSAGING_MENU_STATUS_INVISIBLE: + purple_status_value = PURPLE_STATUS_INVISIBLE; + break; + case MESSAGING_MENU_STATUS_OFFLINE: + purple_status_value = PURPLE_STATUS_OFFLINE; + break; + default: + purple_status_value = PURPLE_STATUS_UNSET; + } + + return purple_status_value; +} + +static void +messaging_status_changed_cb (MessagingMenuApp *app, + MessagingMenuStatus status, + gpointer user_data) +{ + g_return_if_fail (app != NULL); + + PurpleStatusPrimitive status_type = messaging_status_to_purple_status (status); + const char *status_id = purple_primitive_get_id_from_type (status_type); + PurpleSavedStatus *saved_status; + + purple_debug_info (PLUGIN_ID, "Updating accounts to status '%s'\n", status_id); + + saved_status = purple_savedstatus_find_transient_by_type_and_message (status_type, NULL); + + if (saved_status == NULL) { + saved_status = purple_savedstatus_new (NULL, status_type); + purple_debug_info (PLUGIN_ID, "Status not found\n"); + } + purple_savedstatus_activate (saved_status); + messaging_menu_app_set_status (app, status); +} + +static void +messaging_source_activated_cb (MessagingMenuApp *app, + const gchar *source_id, + gpointer user_data) +{ + PurpleConversation *conv; + PidginConversation *gtkconv; + purple_debug_info (PLUGIN_ID, "SOURCE activated '%s'\n", source_id); + /* find conversation with given source id */ + conv = messaging_conversation_for_unique_id (source_id); + + if (conv) { + gtkconv = PIDGIN_CONVERSATION (conv); + if (gtkconv == NULL) { + purple_debug_warning (PLUGIN_ID, "NULL gtkconv '%s'\n", source_id); + return; + } + pidgin_conv_switch_active_conversation(conv); + pidgin_conv_window_switch_gtkconv(gtkconv->win, gtkconv); + gtk_window_present(GTK_WINDOW(gtkconv->win->window)); + } +} + static gboolean plugin_load (PurplePlugin *plugin) { - void *conv_handle, *blist_handle, *conn_handle; + void *conv_handle, *blist_handle, *conn_handle, *savedstatus_handle; if (!notify_is_initted () && !notify_init ("Pidgin")) { purple_debug_error (PLUGIN_ID, "libnotify not running!\n"); @@ -862,9 +1279,21 @@ notify_check_caps(); + if (m_menu_app == NULL) { + m_menu_app = messaging_menu_app_new (PIDGIN_DESKTOP_FILE); + messaging_menu_app_register (m_menu_app); + g_signal_connect(m_menu_app, "status-changed", + G_CALLBACK(messaging_status_changed_cb), NULL); + g_signal_connect(m_menu_app, "activate-source", + G_CALLBACK(messaging_source_activated_cb), NULL); + messaging_set_status_from_savedstatus (purple_savedstatus_get_current ()); + pidgin_blist_visibility_manager_add (); + } + conv_handle = purple_conversations_get_handle (); blist_handle = purple_blist_get_handle (); conn_handle = purple_connections_get_handle(); + savedstatus_handle = purple_savedstatuses_get_handle (); buddy_hash = g_hash_table_new (NULL, NULL); @@ -883,6 +1312,21 @@ purple_signal_connect (conv_handle, "deleting-conversation", plugin, PURPLE_CALLBACK(conv_delete_cb), NULL); + purple_signal_connect (conv_handle, "conversation-updated", plugin, + PURPLE_CALLBACK(messaging_conversation_updated_cb), NULL); + + purple_signal_connect (conv_handle, "deleting-conversation", plugin, + PURPLE_CALLBACK(messaging_conversation_deleted_cb), NULL); + + purple_signal_connect (conv_handle, "received-im-msg", plugin, + PURPLE_CALLBACK(messaging_new_message_cb), NULL); + + purple_signal_connect (conv_handle, "received-chat-msg", plugin, + PURPLE_CALLBACK(messaging_new_chat_cb), NULL); + + purple_signal_connect (savedstatus_handle, "savedstatus-changed", plugin, + PURPLE_CALLBACK(messaging_savedstatus_changed_cb), NULL); + /* used just to not display the flood of guifications we'd get */ purple_signal_connect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle), NULL); @@ -895,11 +1339,12 @@ static gboolean plugin_unload (PurplePlugin *plugin) { - void *conv_handle, *blist_handle, *conn_handle; + void *conv_handle, *blist_handle, *conn_handle, *savedstatus_handle; conv_handle = purple_conversations_get_handle (); blist_handle = purple_blist_get_handle (); conn_handle = purple_connections_get_handle(); + savedstatus_handle = purple_savedstatuses_get_handle (); purple_signal_disconnect (blist_handle, "buddy-signed-on", plugin, PURPLE_CALLBACK(notify_buddy_signon_cb)); @@ -916,6 +1361,21 @@ purple_signal_disconnect (conv_handle, "deleting-conversation", plugin, PURPLE_CALLBACK(conv_delete_cb)); + purple_signal_disconnect (conv_handle, "conversation-updated", plugin, + PURPLE_CALLBACK(messaging_conversation_updated_cb)); + + purple_signal_disconnect (conv_handle, "deleting-conversation", plugin, + PURPLE_CALLBACK(messaging_conversation_deleted_cb)); + + purple_signal_disconnect (conv_handle, "received-im-msg", plugin, + PURPLE_CALLBACK(messaging_new_message_cb)); + + purple_signal_disconnect (conv_handle, "received-chat-msg", plugin, + PURPLE_CALLBACK(messaging_new_chat_cb)); + + purple_signal_disconnect (savedstatus_handle, "savedstatus-changed", plugin, + PURPLE_CALLBACK(messaging_savedstatus_changed_cb)); + purple_signal_disconnect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle)); @@ -925,6 +1385,12 @@ notify_uninit (); + if (m_menu_app) { + g_object_unref (m_menu_app); + m_menu_app = NULL; + pidgin_blist_visibility_manager_remove (); + } + /* If this goes off, we were unloaded by the user and not by shutdown. Same thing as us never getting loaded at all. */ debian/patches/ubuntu_notify_support.patch0000644000000000000000000005635412051402060016347 0ustar Index: pidgin-libnotify-0.14/src/pidgin-libnotify.c =================================================================== --- pidgin-libnotify-0.14.orig/src/pidgin-libnotify.c 2012-11-16 10:15:19.191589930 +0100 +++ pidgin-libnotify-0.14/src/pidgin-libnotify.c 2012-11-16 10:15:27.039589654 +0100 @@ -36,6 +36,7 @@ /* for pidgin_create_prpl_icon */ #include +#include #include @@ -43,8 +44,29 @@ #define PLUGIN_ID "pidgin-libnotify" +#ifdef G_LOG_DOMAIN +#undef G_LOG_DOMAIN +#endif +#define G_LOG_DOMAIN "pidgin-libnotify-plugin" + +#define PIDGIN_DESKTOP_FILE "/usr/share/applications/pidgin.desktop" +#define BLACKLIST_FILENAME "pidgin-libnotify" +#define BLACKLIST_DIR "indicators/messages/applications-blacklist" + +/* Prototypes */ +static void notify_new_message_cb (PurpleAccount *account, const gchar *sender, const gchar *message, int flags, gpointer data); + +/* Globals */ static GHashTable *buddy_hash; +static gboolean notify_supports_actions = FALSE; +static gboolean notify_supports_append = FALSE; +static gboolean notify_supports_truncation = FALSE; + +static guint never_loaded = 0; + +static void conv_delete_cb (PurpleConversation * conv, void * data); + static PurplePluginPrefFrame * get_plugin_pref_frame (PurplePlugin *plugin) { @@ -88,6 +110,11 @@ _("Replace Pidgin request dialogs with libnotify popups")); purple_plugin_pref_frame_add (frame, ppref); + ppref = purple_plugin_pref_new_with_name_and_label ( + "/plugins/gtk/libnotify/blocked_nicks", + _("Names to remove notifications for")); + purple_plugin_pref_frame_add (frame, ppref); + return frame; } @@ -133,7 +160,9 @@ return; just_signed_on_accounts = g_list_prepend (just_signed_on_accounts, account); - g_timeout_add (5000, event_connection_throttle_cb, (gpointer)account); + g_timeout_add_seconds (15, event_connection_throttle_cb, (gpointer)account); + + return; } /* do NOT g_free() the string returned by this function */ @@ -154,7 +183,6 @@ data = purple_buddy_icon_get_data (buddy_icon, &len); loader = gdk_pixbuf_loader_new (); - gdk_pixbuf_loader_set_size (loader, 48, 48); gdk_pixbuf_loader_write (loader, data, len, NULL); gdk_pixbuf_loader_close (loader, NULL); @@ -169,6 +197,97 @@ return icon; } +/* + * This takes a pixbuf that we want to send to the notify server, and + * transforms it to the desired dimensions suitable for a notification. + * We scale the pixbuf down to size * size (square), but preserve the + * original aspect ratio and fill in the edges with transparent pixels + * if the original pixbuf was not square. + */ +static GdkPixbuf * +normalize_icon (GdkPixbuf *icon, gint size) +{ + gint w, h; + int dest_x, dest_y; + gdouble max_edge; + gint new_width, new_height; + GdkPixbuf *scaled_icon; + GdkPixbuf *new_icon; + + w = gdk_pixbuf_get_width (icon); + h = gdk_pixbuf_get_height (icon); + + dest_x = dest_y = 0; + + max_edge = MAX (w, h); + + new_width = size * (w / max_edge); + new_height = size * (h / max_edge); + + /* Scale the image down, preserving the aspect ratio */ + scaled_icon = gdk_pixbuf_scale_simple (icon, + new_width, + new_height, + GDK_INTERP_HYPER); + + g_object_unref (icon); + + /* Create a square pixbuf with an alpha channel, dimensions size * size */ + new_icon = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (scaled_icon), + TRUE, + gdk_pixbuf_get_bits_per_sample (scaled_icon), + size, size); + + /* Clear the pixbuf so it is transparent */ + gdk_pixbuf_fill (new_icon, 0x00000000); + + /* Center the aspect ratio preseved pixbuf in the square pixbuf */ + if (new_width > new_height) { + dest_y = (new_width - new_height) / 2; + } else if (new_height > new_width) { + dest_x = (new_height - new_width) / 2; + } + + /* Copy from the aspect ratio-preserved scaled pixbuf into the + * new pixbuf, at a centered position. */ + gdk_pixbuf_copy_area (scaled_icon, + 0, 0, + gdk_pixbuf_get_width (scaled_icon), + gdk_pixbuf_get_height (scaled_icon), + new_icon, + dest_x, dest_y); + + g_object_unref (scaled_icon); + + return new_icon; +} + +/* Check the name against the static list of black listed + names that we're looking out for. These shouldn't result + in either notifications or indicators. */ +static gboolean +name_blacklisted (PurpleAccount * account, const gchar * name) +{ + if (account != NULL) { + const gchar * username = purple_account_get_username(account); + gchar ** userparts = g_strsplit(username, "@", 2); + if (g_strcmp0(name, userparts[1]) == 0) { + g_strfreev(userparts); + return TRUE; + } + g_strfreev(userparts); + } + + GList * blacklist = purple_prefs_get_string_list("/plugins/gtk/libnotify/blocked_nicks"); + GList * pnt; + for (pnt = blacklist; pnt != NULL; pnt = g_list_next(pnt)) { + if (g_strcmp0(name, (gchar *)pnt->data) == 0) { + return TRUE; + } + } + return FALSE; +} + static void action_cb (NotifyNotification *notification, gchar *action, gpointer user_data) @@ -177,9 +296,9 @@ PurpleConversation *conv = NULL; purple_debug_info (PLUGIN_ID, "action_cb(), " - "notification: 0x%x, action: '%s'", notification, action); + "notification: 0x%x, action: '%s'", GPOINTER_TO_UINT(notification), action); - buddy = (PurpleBuddy *)g_object_get_data (G_OBJECT(notification), "buddy"); + buddy = (PurpleBuddy *)user_data; if (!buddy) { purple_debug_warning (PLUGIN_ID, "Got no buddy!"); @@ -199,13 +318,25 @@ } static gboolean -closed_cb (NotifyNotification *notification) +notification_list_closed_cb (NotifyNotification *notification, PurpleConversation * conv) { - PurpleContact *contact; + purple_debug_info (PLUGIN_ID, "closed_cb(), notification: 0x%x\n", GPOINTER_TO_UINT(notification)); - purple_debug_info (PLUGIN_ID, "closed_cb(), notification: 0x%x\n", notification); + if (conv != NULL) { + GList * notifylist = purple_conversation_get_data(conv, "notification-list"); + notifylist = g_list_remove(notifylist, notification); + purple_conversation_set_data(conv, "notification-list", notifylist); + } + g_object_unref(notification); + + return FALSE; +} + +static gboolean +closed_cb (NotifyNotification *notification, PurpleContact * contact) +{ + purple_debug_info (PLUGIN_ID, "closed_cb(), notification: 0x%x\n", GPOINTER_TO_UINT(notification)); - contact = (PurpleContact *)g_object_get_data (G_OBJECT(notification), "contact"); if (contact) g_hash_table_remove (buddy_hash, contact); @@ -218,11 +349,12 @@ * num_chars is utf-8 characters */ static gchar * truncate_escape_string (const gchar *str, - int num_chars) + int num_chars, + gboolean escape) { gchar *escaped_str; - if (g_utf8_strlen (str, num_chars*2+1) > num_chars) { + if (!notify_supports_truncation && g_utf8_strlen (str, num_chars*2+1) > num_chars) { gchar *truncated_str; gchar *str2; @@ -231,11 +363,11 @@ g_utf8_strncpy (str2, str, num_chars-2); truncated_str = g_strdup_printf ("%s..", str2); - escaped_str = g_markup_escape_text (truncated_str, strlen (truncated_str)); + escaped_str = escape ? g_markup_escape_text (truncated_str, strlen (truncated_str)) : g_strdup (truncated_str); g_free (str2); g_free (truncated_str); } else { - escaped_str = g_markup_escape_text (str, strlen (str)); + escaped_str = escape ? g_markup_escape_text (str, strlen (str)) : g_strdup (str); } return escaped_str; @@ -257,67 +389,105 @@ static void notify (const gchar *title, const gchar *body, - PurpleBuddy *buddy) + PurpleBuddy *buddy, + PurpleConversation *conv) { NotifyNotification *notification = NULL; - GdkPixbuf *icon; - PurpleBuddyIcon *buddy_icon; - gchar *tr_body; - PurpleContact *contact; + GdkPixbuf *icon = NULL; + PurpleBuddyIcon *buddy_icon = NULL; + gchar *tr_body = NULL; + PurpleContact *contact = NULL; - contact = purple_buddy_get_contact (buddy); + if (buddy != NULL) { + contact = purple_buddy_get_contact (buddy); + } if (body) - tr_body = truncate_escape_string (body, 60); + tr_body = truncate_escape_string (body, 60, TRUE); else tr_body = NULL; - notification = g_hash_table_lookup (buddy_hash, contact); + /* If we're appending we shouldn't update an already + existing notification */ + if (conv == NULL && contact != NULL) { + notification = g_hash_table_lookup (buddy_hash, contact); + } + /* This will only happen if we're a login message */ if (notification != NULL) { notify_notification_update (notification, title, tr_body, NULL); + /* this shouldn't be necessary, file a bug */ notify_notification_show (notification, NULL); purple_debug_info (PLUGIN_ID, "notify(), update: " "title: '%s', body: '%s', buddy: '%s'\n", - title, tr_body, best_name (buddy)); + title, tr_body, buddy != NULL ? best_name (buddy) : "(null)"); g_free (tr_body); return; } - notification = notify_notification_new (title, tr_body, NULL, NULL); + + notification = notify_notification_new (title, tr_body, "notification-message-im"); purple_debug_info (PLUGIN_ID, "notify(), new: " "title: '%s', body: '%s', buddy: '%s'\n", - title, tr_body, best_name (buddy)); + title, tr_body, buddy != NULL ? best_name (buddy) : "(null)"); g_free (tr_body); - buddy_icon = purple_buddy_get_icon (buddy); - if (buddy_icon) { + if (notify_supports_append) { + if (conv != NULL) { + notify_notification_set_hint_string(notification, "x-canonical-append", "allow"); + } + } + + if (buddy != NULL) { + buddy_icon = purple_buddy_get_icon (buddy); + } + + if (buddy_icon != NULL) { icon = pixbuf_from_buddy_icon (buddy_icon); purple_debug_info (PLUGIN_ID, "notify(), has a buddy icon.\n"); } else { - icon = pidgin_create_prpl_icon (buddy->account, 1); - purple_debug_info (PLUGIN_ID, "notify(), has a prpl icon.\n"); + if (buddy != NULL) { + icon = pidgin_create_prpl_icon (buddy->account, PIDGIN_PRPL_ICON_LARGE); + purple_debug_info (PLUGIN_ID, "notify(), has a prpl icon.\n"); + } } - if (icon) { + icon = normalize_icon (icon, 48); + + if (icon != NULL) { notify_notification_set_icon_from_pixbuf (notification, icon); g_object_unref (icon); - } else { - purple_debug_warning (PLUGIN_ID, "notify(), couldn't find any icon!\n"); - } - - g_hash_table_insert (buddy_hash, contact, notification); - g_object_set_data (G_OBJECT(notification), "contact", contact); - - g_signal_connect (notification, "closed", G_CALLBACK(closed_cb), NULL); + GValue iconname = {0}; + g_value_init(&iconname, G_TYPE_STRING); + g_value_set_static_string(&iconname, ""); + g_object_set_property(G_OBJECT(notification), "icon-name", &iconname); + } + + if (contact != NULL && conv == NULL) { + g_hash_table_insert (buddy_hash, contact, notification); + + g_signal_connect (notification, "closed", G_CALLBACK(closed_cb), contact); + } + if (conv != NULL) { + GList * notifylist = purple_conversation_get_data(conv, "notification-list"); + notifylist = g_list_append(notifylist, notification); + purple_conversation_set_data(conv, "notification-list", notifylist); + g_signal_connect(notification, "closed", G_CALLBACK(notification_list_closed_cb), conv); + } + if (contact == NULL && conv == NULL) { + /* Should never happen, but just in case, let's not have a memory leak */ + g_signal_connect(notification, "closed", G_CALLBACK(g_object_unref), NULL); + } notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL); - notify_notification_add_action (notification, "show", _("Show"), action_cb, NULL, NULL); + if (notify_supports_actions) { + notify_notification_add_action (notification, "show", _("Show"), action_cb, buddy, NULL); + } if (!notify_notification_show (notification, NULL)) { purple_debug_error (PLUGIN_ID, "notify(), failed to send notification\n"); @@ -329,7 +499,7 @@ notify_buddy_signon_cb (PurpleBuddy *buddy, gpointer data) { - gchar *tr_name, *title; + gchar *tr_name; gboolean blocked; g_return_if_fail (buddy); @@ -347,21 +517,18 @@ if (!should_notify_unavailable (purple_buddy_get_account (buddy))) return; - tr_name = truncate_escape_string (best_name (buddy), 25); - - title = g_strdup_printf (_("%s signed on"), tr_name); + tr_name = truncate_escape_string (best_name (buddy), 25, FALSE); - notify (title, NULL, buddy); + notify (tr_name, _("is online"), buddy, NULL); g_free (tr_name); - g_free (title); } static void notify_buddy_signoff_cb (PurpleBuddy *buddy, gpointer data) { - gchar *tr_name, *title; + gchar *tr_name; gboolean blocked; g_return_if_fail (buddy); @@ -379,42 +546,61 @@ if (!should_notify_unavailable (purple_buddy_get_account (buddy))) return; - tr_name = truncate_escape_string (best_name (buddy), 25); - - title = g_strdup_printf (_("%s signed off"), tr_name); + tr_name = truncate_escape_string (best_name (buddy), 25, FALSE); - notify (title, NULL, buddy); + notify (tr_name, _("is offline"), buddy, NULL); g_free (tr_name); - g_free (title); } static void notify_msg_sent (PurpleAccount *account, const gchar *sender, - const gchar *message) + const gchar *message, + PurpleConversation * conv) { - PurpleBuddy *buddy; - gchar *title, *body, *tr_name; + PurpleBuddy *buddy = NULL; + gchar *body = NULL, *tr_name = NULL; gboolean blocked; - buddy = purple_find_buddy (account, sender); - if (!buddy) - return; - blocked = purple_prefs_get_bool ("/plugins/gtk/libnotify/blocked"); if (!purple_privacy_check(account, sender) && blocked) return; - tr_name = truncate_escape_string (best_name (buddy), 25); + if (g_list_find (just_signed_on_accounts, account)) + return; + + buddy = purple_find_buddy (account, sender); + + if (buddy != NULL) { + tr_name = truncate_escape_string (best_name (buddy), 25, FALSE); + } else { + if (conv != NULL) { + const gchar * temp = purple_conversation_get_title(conv); + if (temp != NULL) { + if (sender == NULL || !g_strcmp0(sender, temp)) { + tr_name = g_strdup(temp); + } else { + tr_name = g_strdup_printf("%s (%s)", sender, temp); + } + } else { + if (sender != NULL) { + tr_name = g_strdup(sender); + } + } + } + } + + if (tr_name == NULL) { + purple_debug_warning(PLUGIN_ID, "Unable to find a title for the notification"); + return; + } - title = g_strdup_printf (_("%s says:"), tr_name); body = purple_markup_strip_html (message); - notify (title, body, buddy); + notify (tr_name, body, buddy, conv); g_free (tr_name); - g_free (title); g_free (body); } @@ -430,24 +616,38 @@ if (!purple_prefs_get_bool ("/plugins/gtk/libnotify/newmsg")) return; + if (name_blacklisted(account, sender)) return; + conv = purple_find_conversation_with_account (PURPLE_CONV_TYPE_IM, sender, account); #ifndef DEBUG /* in debug mode, always show notifications */ if (conv && purple_conversation_has_focus (conv)) { - purple_debug_info (PLUGIN_ID, "Conversation has focus 0x%x\n", conv); + purple_debug_info (PLUGIN_ID, "Conversation has focus 0x%x\n", GPOINTER_TO_UINT(conv)); return; } #endif if (conv && purple_prefs_get_bool ("/plugins/gtk/libnotify/newconvonly")) { - purple_debug_info (PLUGIN_ID, "Conversation is not new 0x%x\n", conv); + purple_debug_info (PLUGIN_ID, "Conversation is not new 0x%x\n", GPOINTER_TO_UINT(conv)); + return; + } + + if (conv == NULL) { return; } if (!should_notify_unavailable (account)) return; - notify_msg_sent (account, sender, message); + PidginConversation * pconv = PIDGIN_CONVERSATION(conv); + if (pconv != NULL) { + if (pconv->entry != NULL && pconv->imhtml != NULL) { + if (GTK_WIDGET_HAS_FOCUS(pconv->entry) || GTK_WIDGET_HAS_FOCUS(pconv->imhtml)) { + purple_debug_warning(PLUGIN_ID, "Pidgin conversation's widgets are in focus"); + return; + }}} + + notify_msg_sent (account, sender, message, conv); } static void @@ -463,10 +663,182 @@ if (nick && !strcmp (sender, nick)) return; - if (!g_strstr_len (message, strlen(message), nick)) + if (!purple_utf8_has_word (message, nick)) + return; + + PidginConversation * pconv = PIDGIN_CONVERSATION(conv); + if (pconv != NULL) { + if (pconv->entry != NULL && pconv->imhtml != NULL) { + if (GTK_WIDGET_HAS_FOCUS(pconv->entry) || GTK_WIDGET_HAS_FOCUS(pconv->imhtml)) { + purple_debug_warning(PLUGIN_ID, "Pidgin conversation's widgets are in focus"); return; + }}} + + if (name_blacklisted(account, sender)) return; + + notify_msg_sent (account, sender, message, conv); +} + +static void +conv_delete_cb (PurpleConversation * conv, void * data) +{ + GList * notifylist = purple_conversation_get_data(conv, "notification-list"); + if (notifylist != NULL) { + GList * i; + for (i = notifylist; i != NULL; i = i->next) { + NotifyNotification * notification = NOTIFY_NOTIFICATION(i->data); + if (notification == NULL) break; + + g_signal_handlers_disconnect_by_func(G_OBJECT(notification), notification_list_closed_cb, conv); + notify_notification_close(notification, NULL); /* Don't care if it fails, it's going to die. */ + g_object_unref(G_OBJECT(notification)); + } + g_list_free(notifylist); + + purple_conversation_set_data(conv, "notification-list", NULL); + } + + return; +} + +static void +remove_from_blacklist (void) +{ + gchar *bpath; + + bpath = g_build_filename (g_get_user_config_dir(), + BLACKLIST_DIR, + BLACKLIST_FILENAME, + NULL); + + if (g_file_test (bpath, G_FILE_TEST_EXISTS)) { + GFile *bfile; + bfile = g_file_new_for_path (bpath); + + if (bfile) { + GError *error = NULL; + g_file_delete (bfile, NULL, &error); + + if (error) { + g_warning ("Unable to remove blacklist file: %s", error->message); + g_error_free (error); + } + + g_object_unref (bfile); + } + } + + g_free (bpath); + + return; +} + +static gboolean +plugin_never_loaded (gpointer data) +{ + gchar *bdir; + gchar *bpath; + GError *error = NULL; + + bdir = g_build_filename (g_get_user_config_dir (), + BLACKLIST_DIR, + NULL); + if (!g_file_test (bdir, G_FILE_TEST_IS_DIR)) { + GFile *dirfile; + + dirfile = g_file_new_for_path (bdir); + if (dirfile) { + g_file_make_directory_with_parents (dirfile, + NULL, + &error); + if (error) { + g_warning ("Unable to create blacklist directory: %s", + error->message); + g_error_free (error); + g_object_unref (dirfile); + g_free (bdir); + return FALSE; + } + } else { + g_warning ("Unable to create blacklist directory: Unable to create " + "GFile for path %s", bdir); + g_free (bdir); + return FALSE; + } + + g_object_unref (dirfile); + } + g_free (bdir); + + bpath = g_build_filename (g_get_user_config_dir (), + BLACKLIST_DIR, + BLACKLIST_FILENAME, + NULL); + + if (g_file_set_contents (bpath, + PIDGIN_DESKTOP_FILE, + -1, + &error)) { + g_debug ("Successfully wrote blacklist file to %s", bpath); + } else { + g_debug ("Unable to write blacklist file to %s: %s", + bpath, + error ? error->message : "Unknown"); + if (error) + g_error_free (error); + } + + g_free (bpath); + + return FALSE; +} + +static gboolean +force_load_once (gpointer data) +{ + PurplePlugin * plugin = (PurplePlugin *)data; + + if (!purple_prefs_get_bool("/plugins/gtk/libnotify/auto_loaded")) { + purple_plugin_load(plugin); + purple_plugins_save_loaded(PIDGIN_PREFS_ROOT "/plugins/loaded"); + purple_prefs_set_bool("/plugins/gtk/libnotify/auto_loaded", TRUE); + } + + return FALSE; +} + +static void +notify_check_caps_helper (gpointer data, gpointer user_data) +{ + gchar * cap = (gchar *)data; + + if (cap == NULL) return; - notify_msg_sent (account, sender, message); + if (!strcmp(cap, "actions")) { + notify_supports_actions = TRUE; + } else if (!strcmp(cap, "append")) { + notify_supports_append = TRUE; + } else if (!strcmp(cap, "x-canonical-append")) { + notify_supports_append = TRUE; + } else if (!strcmp(cap, "truncation")) { + notify_supports_truncation = TRUE; + } else if (!strcmp(cap, "x-canonical-truncation")) { + notify_supports_truncation = TRUE; + } + + return; +} + +static void +notify_check_caps(void) +{ + GList * caps = notify_get_server_caps(); + + g_list_foreach(caps, notify_check_caps_helper, NULL); + g_list_foreach(caps, (GFunc)g_free, NULL); + g_list_free(caps); + + return; } extern void attach_request_ui_ops (); @@ -482,6 +854,14 @@ return FALSE; } + /* They really do love me! */ + if (never_loaded != 0) { + g_source_remove(never_loaded); + } + remove_from_blacklist(); + + notify_check_caps(); + conv_handle = purple_conversations_get_handle (); blist_handle = purple_blist_get_handle (); conn_handle = purple_connections_get_handle(); @@ -500,6 +880,9 @@ purple_signal_connect (conv_handle, "received-chat-msg", plugin, PURPLE_CALLBACK(notify_chat_nick), NULL); + purple_signal_connect (conv_handle, "deleting-conversation", plugin, + PURPLE_CALLBACK(conv_delete_cb), NULL); + /* used just to not display the flood of guifications we'd get */ purple_signal_connect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle), NULL); @@ -530,6 +913,9 @@ purple_signal_disconnect (conv_handle, "received-chat-msg", plugin, PURPLE_CALLBACK(notify_chat_nick)); + purple_signal_disconnect (conv_handle, "deleting-conversation", plugin, + PURPLE_CALLBACK(conv_delete_cb)); + purple_signal_disconnect (conn_handle, "signed-on", plugin, PURPLE_CALLBACK(event_connection_throttle)); @@ -539,6 +925,11 @@ notify_uninit (); + /* If this goes off, we were unloaded by the user + and not by shutdown. Same thing as us never + getting loaded at all. */ + never_loaded = g_timeout_add_seconds(30, plugin_never_loaded, NULL); + return TRUE; } @@ -575,20 +966,6 @@ &prefs_info /* prefs info */ }; -static gboolean -force_load_once (gpointer data) -{ - PurplePlugin * plugin = (PurplePlugin *)data; - - if (!purple_prefs_get_bool("/plugins/gtk/libnotify/auto_loaded")) { - purple_plugin_load(plugin); - purple_plugins_save_loaded(PIDGIN_PREFS_ROOT "/plugins/loaded"); - purple_prefs_set_bool("/plugins/gtk/libnotify/auto_loaded", TRUE); - } - - return FALSE; -} - static void init_plugin (PurplePlugin *plugin) { @@ -599,7 +976,24 @@ info.summary = _("Displays popups via libnotify."); info.description = _("Pidgin-libnotify:\nDisplays popups via libnotify."); + /* If we get init'd and we never get loaded + chances are the user hasn't enabled this + plugin. */ + never_loaded = g_timeout_add_seconds(30, plugin_never_loaded, NULL); + purple_prefs_add_none ("/plugins/gtk/libnotify"); + + /* Create a list of nicks that are commonly used by + IRC servers but don't represent real people. */ + GList * nicklist = NULL; + nicklist = g_list_append(nicklist, "NickServ"); + nicklist = g_list_append(nicklist, "ChanServ"); + nicklist = g_list_append(nicklist, "MsgServ"); + nicklist = g_list_append(nicklist, "freenode-connect"); + + purple_prefs_add_string_list ("/plugins/gtk/libnotify/blocked_nicks", nicklist); + g_list_free(nicklist); + purple_prefs_add_bool ("/plugins/gtk/libnotify/newmsg", TRUE); purple_prefs_add_bool ("/plugins/gtk/libnotify/blocked", TRUE); purple_prefs_add_bool ("/plugins/gtk/libnotify/newconvonly", FALSE); debian/patches/de_po.diff0000644000000000000000000000063711201357465012547 0ustar Author: Jürgen Göricke Description: Fix translation for sign off message. --- pidgin-libnotify-0.14/po/de.po 2008-12-14 12:20:36.000000000 -0500 +++ de.po 2009-05-09 14:53:15.000000000 -0400 @@ -48,7 +48,7 @@ #: src/pidgin-libnotify.c:379 #, c-format msgid "%s signed off" -msgstr "%s hat sich angemeldet" +msgstr "%s hat sich abgemeldet" #: src/pidgin-libnotify.c:406 #, c-format debian/patches/series0000644000000000000000000000024412051401435012025 0ustar de_po.diff force-load.patch best_name.patch it_po.diff add-cs-translation.diff replace-pidgin-action-requests.diff ubuntu_notify_support.patch messaging_menu.patch debian/patches/add-cs-translation.diff0000644000000000000000000000632412010536206015136 0ustar From: Jakub Adam Date: Mon, 22 Aug 2011 22:17:16 +0200 Subject: add-cs-translation.diff --- configure.ac | 2 +- po/cs.po | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletions(-) create mode 100644 po/cs.po Index: pidgin-libnotify-0.14/configure.ac =================================================================== --- pidgin-libnotify-0.14.orig/configure.ac 2012-08-08 15:07:49.686241080 -0400 +++ pidgin-libnotify-0.14/configure.ac 2012-08-08 15:15:16.180924392 -0400 @@ -36,7 +36,7 @@ AC_PROG_INTLTOOL GETTEXT_PACKAGE=pidgin-libnotify AC_SUBST(GETTEXT_PACKAGE) -ALL_LINGUAS="es fr it nl pl pt pt_BR sl hu zh_CN ro gl ru bg de sv" +ALL_LINGUAS="bg cs de es fr gl hu it nl pl pt pt_BR ro ru sl sv zh_CN" AM_GLIB_GNU_GETTEXT # Index: pidgin-libnotify-0.14/po/cs.po =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ pidgin-libnotify-0.14/po/cs.po 2012-08-08 15:15:16.000000000 -0400 @@ -0,0 +1,81 @@ +# Czech (cs) translation of pidgin-libnotify +# Copyright (C) 2011 Jakub Adam +# This file is distributed under the same license as the pidgin-libnotify package. +# Jakub Adam , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: pidgin-libnotify\n" +"POT-Creation-Date: 2011-08-21 12:58+0200\n" +"PO-Revision-Date: 2011-08-21 00:00::00+GMT\n" +"Last-Translator: Jakub Adam \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../src/pidgin-libnotify.c:62 +msgid "New IM messages" +msgstr "Nové zprávy" + +#: ../src/pidgin-libnotify.c:67 +msgid "New chat messages" +msgstr "Nové příspěvky v chatu" + +#: ../src/pidgin-libnotify.c:72 +msgid "Notify chat only when someone says my username" +msgstr "Upozornit na chat jen pokud někdo napíše mé uživatelské jméno" + +#: ../src/pidgin-libnotify.c:77 +msgid "Only new conversations" +msgstr "Pouze nové konverzace" + +#: ../src/pidgin-libnotify.c:82 +msgid "Ignore events from blocked users" +msgstr "Ignorovat události od blokovaných uživatelů" + +#: ../src/pidgin-libnotify.c:87 +msgid "Buddy signs on" +msgstr "Kamarád se přihlásil" + +#: ../src/pidgin-libnotify.c:92 +msgid "Buddy signs off" +msgstr "Kamarád se odhlásil" + +#: ../src/pidgin-libnotify.c:97 +msgid "Only when available" +msgstr "Jen, když jsem k dispozici" + +#: ../src/pidgin-libnotify.c:342 +msgid "Show" +msgstr "Ukaž" + +#: ../src/pidgin-libnotify.c:375 +#, c-format +msgid "%s signed on" +msgstr "%s se přihlásil" + +#: ../src/pidgin-libnotify.c:407 +#, c-format +msgid "%s signed off" +msgstr "%s se odhlásil" + +#: ../src/pidgin-libnotify.c:434 +#, c-format +msgid "%s says:" +msgstr "%s napsal:" + +#: ../src/pidgin-libnotify.c:610 +msgid "Libnotify Popups" +msgstr "Vyskakovací okna libnotify" + +#: ../src/pidgin-libnotify.c:611 +msgid "Displays popups via libnotify." +msgstr "Zobrazuje vyskakovací okna pomocí libnotify" + +#: ../src/pidgin-libnotify.c:612 +msgid "" +"Pidgin-libnotify:\n" +"Displays popups via libnotify." +msgstr "" +"Pidgin-libnotify:\n" +"Upozorňuje na příchozí zprávy a další události pomocí vyskakovacích oken." debian/patches/force-load.patch0000644000000000000000000000172012051401412013637 0ustar === modified file 'src/pidgin-libnotify.c' --- a/src/pidgin-libnotify.c +++ b/src/pidgin-libnotify.c @@ -568,6 +568,20 @@ &prefs_info /* prefs info */ }; +static gboolean +force_load_once (gpointer data) +{ + PurplePlugin * plugin = (PurplePlugin *)data; + + if (!purple_prefs_get_bool("/plugins/gtk/libnotify/auto_loaded")) { + purple_plugin_load(plugin); + purple_plugins_save_loaded(PIDGIN_PREFS_ROOT "/plugins/loaded"); + purple_prefs_set_bool("/plugins/gtk/libnotify/auto_loaded", TRUE); + } + + return FALSE; +} + static void init_plugin (PurplePlugin *plugin) { @@ -585,6 +599,9 @@ purple_prefs_add_bool ("/plugins/gtk/libnotify/signon", TRUE); purple_prefs_add_bool ("/plugins/gtk/libnotify/signoff", FALSE); purple_prefs_add_bool ("/plugins/gtk/libnotify/only_available", FALSE); + purple_prefs_add_bool ("/plugins/gtk/libnotify/auto_loaded", FALSE); + + g_idle_add(force_load_once, plugin); } PURPLE_INIT_PLUGIN(notify, init_plugin, info) debian/patches/best_name.patch0000644000000000000000000000205512051402010013556 0ustar Description: Rather than using the logic in the best_name functionality. libnotify should be using the built-in functionality of pidgin. There is already a function purple_buddy_get_contact_alias which returns the correct alias. Author: Stephen Ostrow Bug: http://sourceforge.net/tracker/?func=detail&aid=2831741&group_id=144907&atid=760303 Bug-Ubuntu: https://launchpad.net/bugs/408624 Index: pidgin-libnotify-0.14/src/pidgin-libnotify.c =================================================================== --- pidgin-libnotify-0.14.orig/src/pidgin-libnotify.c 2012-11-16 10:14:37.751591394 +0100 +++ pidgin-libnotify-0.14/src/pidgin-libnotify.c 2012-11-16 10:14:38.695591359 +0100 @@ -131,16 +131,10 @@ } /* do NOT g_free() the string returned by this function */ -static gchar * +const static gchar * best_name (PurpleBuddy *buddy) { - if (buddy->alias) { - return buddy->alias; - } else if (buddy->server_alias) { - return buddy->server_alias; - } else { - return buddy->name; - } + return purple_buddy_get_contact_alias(buddy); } static GdkPixbuf *