mail-notification

Fork of Jean-Yves Lefort's mail-notification, a tray icon to notify of new mail
git clone https://code.djc.id.au/git/mail-notification/

src/mn-evolution-plugin.c (6866B) - raw

      1 /*
      2  * Mail Notification
      3  * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License along
     16  * with this program; if not, write to the Free Software Foundation, Inc.,
     17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     18  */
     19 
     20 #include <stdarg.h>
     21 #include <string.h>
     22 #include <libintl.h>
     23 #include <gtk/gtk.h>
     24 #include <dbus/dbus.h>
     25 #include <dbus/dbus-glib-lowlevel.h>
     26 #include <dbus/dbus-glib-bindings.h>
     27 #include <camel/camel-folder.h>
     28 #include <mail/em-event.h>
     29 #include <mail/mail-tools.h>
     30 #include "mn-evolution.h"
     31 #include "mn-evolution-server.h"
     32 #include "mn-evolution-plugin.h"
     33 
     34 #define ENABLE_SUCCESS	0
     35 #define ENABLE_FAILURE	1
     36 
     37 static MNEvolutionServer *evo_server = NULL;
     38 static DBusGConnection *session_bus = NULL;
     39 static DBusGProxy *session_bus_proxy = NULL;
     40 
     41 static void show_error_dialog (const char *primary, const char *format, ...) G_GNUC_PRINTF(2, 3);
     42 
     43 static void
     44 show_error_dialog (const char *primary, const char *format, ...)
     45 {
     46   GtkWidget *dialog;
     47   va_list args;
     48   char *secondary;
     49 
     50   g_return_if_fail(primary != NULL);
     51   g_return_if_fail(format != NULL);
     52 
     53   dialog = gtk_message_dialog_new(NULL,
     54 				  0,
     55 				  GTK_MESSAGE_ERROR,
     56 				  GTK_BUTTONS_OK,
     57 				  "%s",
     58 				  primary);
     59 
     60   va_start(args, format);
     61   secondary = g_strdup_vprintf(format, args);
     62   va_end(args);
     63 
     64   gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", secondary);
     65   g_free(secondary);
     66 
     67   gtk_window_set_title(GTK_WINDOW(dialog), ""); /* HIG */
     68 
     69   g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
     70   gtk_widget_show(dialog);
     71 }
     72 
     73 gboolean
     74 mn_evolution_plugin_register_server (GObject *server,
     75 				     const char *service,
     76 				     const char *path,
     77 				     GError **err)
     78 {
     79   unsigned int name_reply;
     80 
     81   g_return_val_if_fail(G_IS_OBJECT(server), FALSE);
     82   g_return_val_if_fail(service != NULL, FALSE);
     83   g_return_val_if_fail(path != NULL, FALSE);
     84 
     85   dbus_g_connection_register_g_object(session_bus, path, server);
     86 
     87   if (! org_freedesktop_DBus_request_name(session_bus_proxy,
     88 					  service,
     89 					  DBUS_NAME_FLAG_DO_NOT_QUEUE,
     90 					  &name_reply,
     91 					  err))
     92     return FALSE;
     93 
     94   if (name_reply != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
     95     {
     96       /* unlikely to ever happen, not worth a translation */
     97       g_set_error(err, 0, 0, "cannot register name \"%s\"", service);
     98       return FALSE;
     99     }
    100 
    101   return TRUE;
    102 }
    103 
    104 gboolean
    105 mn_evolution_plugin_unregister_server (const char *service, GError **err)
    106 {
    107   unsigned int name_reply;
    108 
    109   g_return_val_if_fail(service != NULL, FALSE);
    110 
    111   if (! org_freedesktop_DBus_release_name(session_bus_proxy,
    112 					  service,
    113 					  &name_reply,
    114 					  err))
    115     return FALSE;
    116 
    117   if (name_reply != DBUS_RELEASE_NAME_REPLY_RELEASED)
    118     {
    119       /* unlikely to ever happen, not worth a translation */
    120       g_set_error(err, 0, 0, "cannot unregister name \"%s\"", service);
    121       return FALSE;
    122     }
    123 
    124   return TRUE;
    125 }
    126 
    127 static void
    128 disable_plugin (void)
    129 {
    130   g_object_unref(evo_server);
    131   evo_server = NULL;
    132 
    133   /*
    134    * Do not unref session_bus_proxy, since it might break when the
    135    * DBusGProxy memory management issue is fixed
    136    * (https://bugs.freedesktop.org/show_bug.cgi?id=14030).
    137    */
    138   session_bus_proxy = NULL;
    139 
    140   dbus_g_connection_unref(session_bus);
    141   session_bus = NULL;
    142 }
    143 
    144 static DBusHandlerResult
    145 session_bus_filter_cb (DBusConnection *conn, DBusMessage *message, void *user_data)
    146 {
    147   if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected"))
    148     {
    149       GDK_THREADS_ENTER();
    150 
    151       show_error_dialog(dgettext(GETTEXT_PACKAGE, "A fatal error has occurred in the Evolution Mail Notification plugin"),
    152 			dgettext(GETTEXT_PACKAGE, "The connection to the D-Bus session bus was lost."));
    153 
    154       disable_plugin();
    155 
    156       GDK_THREADS_LEAVE();
    157 
    158       return DBUS_HANDLER_RESULT_HANDLED;
    159     }
    160 
    161   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    162 }
    163 
    164 static gboolean
    165 connect_to_session_bus (void)
    166 {
    167   DBusConnection *raw_bus;
    168   GError *err = NULL;
    169 
    170   g_return_val_if_fail(session_bus == NULL, FALSE);
    171 
    172   session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &err);
    173   if (! session_bus)
    174     {
    175       show_error_dialog(dgettext(GETTEXT_PACKAGE, "Unable to initialize the Mail Notification plugin"),
    176 			dgettext(GETTEXT_PACKAGE, "Unable to connect to the D-Bus session bus: %s."),
    177 			err->message);
    178       g_error_free(err);
    179       return FALSE;
    180     }
    181 
    182   raw_bus = dbus_g_connection_get_connection(session_bus);
    183 
    184   dbus_connection_set_exit_on_disconnect(raw_bus, FALSE);
    185 
    186   if (! dbus_connection_add_filter(raw_bus, session_bus_filter_cb, NULL, NULL))
    187     {
    188       show_error_dialog(dgettext(GETTEXT_PACKAGE, "Unable to initialize the Mail Notification plugin"),
    189 			/* too unlikely to be worth a translation */
    190 			"Unable to add a D-Bus filter: not enough memory.");
    191 
    192       dbus_g_connection_unref(session_bus);
    193       session_bus = NULL;
    194 
    195       return FALSE;
    196     }
    197 
    198   session_bus_proxy = dbus_g_proxy_new_for_name(session_bus,
    199 						DBUS_SERVICE_DBUS,
    200 						DBUS_PATH_DBUS,
    201 						DBUS_INTERFACE_DBUS);
    202 
    203   return TRUE;
    204 }
    205 
    206 int
    207 e_plugin_lib_enable (EPlugin *ep, int enable)
    208 {
    209   static gboolean enabled = FALSE;
    210   GError *err = NULL;
    211 
    212   if (! enable || enabled)
    213     return ENABLE_SUCCESS;
    214 
    215   enabled = TRUE;
    216 
    217   if (! connect_to_session_bus())
    218     return ENABLE_FAILURE;
    219 
    220   evo_server = mn_evolution_server_new();
    221   if (! mn_evolution_plugin_register_server(G_OBJECT(evo_server),
    222 					    MN_EVOLUTION_SERVER_SERVICE,
    223 					    MN_EVOLUTION_SERVER_PATH,
    224 					    &err))
    225     {
    226       show_error_dialog(dgettext(GETTEXT_PACKAGE, "Unable to initialize the Mail Notification plugin"),
    227 			dgettext(GETTEXT_PACKAGE, "Unable to register the Mail Notification Evolution D-Bus server: %s."),
    228 			err->message);
    229       g_error_free(err);
    230 
    231       disable_plugin();
    232       return ENABLE_FAILURE;
    233     }
    234 
    235   return ENABLE_SUCCESS;
    236 }
    237 
    238 void
    239 org_jylefort_mail_notification_folder_changed (EPlugin *plugin,
    240 					       EMEventTargetFolder *folder)
    241 {
    242   if (evo_server)
    243     mn_evolution_server_folder_changed(evo_server, folder->uri);
    244 }
    245 
    246 void
    247 org_jylefort_mail_notification_message_reading (EPlugin *plugin,
    248 						EMEventTargetMessage *message)
    249 {
    250   if (evo_server)
    251     {
    252       char *url;
    253 
    254       url = mail_tools_folder_to_url(message->folder);
    255       mn_evolution_server_message_reading(evo_server, url);
    256       g_free(url);
    257     }
    258 }