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-mailbox.gob (7148B) - 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 %headertop{
     21 #include "mn-mailbox.h"
     22 %}
     23 
     24 %privateheader{
     25 #include <time.h>
     26 #include "mn-evolution-client.h"
     27 %}
     28 
     29 %{
     30 #include <stdarg.h>
     31 #include <gobject/gvaluecollector.h>
     32 #include <glib/gi18n.h>
     33 #include "mn-evolution.h"
     34 #include "mn-mailbox-private.h"
     35 #include "mn-message.h"
     36 #include "mn-util.h"
     37 #include "mn-stock.h"
     38 #include "mn-evolution-message.h"
     39 #include "mn-shell.h"
     40 #include "mn-evolution-client-dbus.h"
     41 
     42 typedef struct
     43 {
     44   const char	*uid;
     45   unsigned int	sent_time;
     46   unsigned int	received_time;
     47   const char	*id;
     48   const char	*from;
     49   const char	*subject;
     50 } MessageInfo;
     51 %}
     52 
     53 class MN:Evolution:Mailbox from MN:Mailbox
     54 {
     55   public char *uri destroywith g_free;
     56   property STRING uri (link, flags = MN_MAILBOX_PARAM_LOAD_SAVE | MN_MAILBOX_PARAM_REQUIRED);
     57 
     58   /*
     59    * Evolution might not be running when we instantiate the mailbox,
     60    * so we cache the folder name.
     61    */
     62   public char *folder_name destroywith g_free;
     63   property STRING folder_name (link, flags = MN_MAILBOX_PARAM_LOAD_SAVE | MN_MAILBOX_PARAM_REQUIRED);
     64 
     65   private MNEvolutionClient *client;
     66   private gboolean signals_connected;
     67   private DBusGProxyCall *pending_call;
     68 
     69   private time_t last_browsed;
     70 
     71   class_init (class)
     72   {
     73     MN_MAILBOX_CLASS(class)->type = "evolution";
     74   }
     75 
     76   init (self)
     77   {
     78     mn_mailbox_set_format(MN_MAILBOX(self), "Evolution");
     79     mn_mailbox_set_stock_id(MN_MAILBOX(self), MN_STOCK_EVOLUTION_MAILBOX);
     80 
     81     /* we receive notifications from Evolution, no need to poll */
     82     mn_mailbox_set_poll(MN_MAILBOX(self), FALSE);
     83   }
     84 
     85   override (MN:Mailbox) void
     86     seal (MNMailbox *mailbox)
     87   {
     88     PARENT_HANDLER(mailbox);
     89 
     90     if (! mailbox->runtime_name)
     91       mailbox->runtime_name = g_strdup(SELF(mailbox)->folder_name);
     92   }
     93 
     94   finalize (self)
     95   {
     96     if (selfp->client)
     97       {
     98 	if (selfp->pending_call)
     99 	  {
    100 	    g_assert(selfp->client->proxy != NULL);
    101 	    dbus_g_proxy_cancel_call(selfp->client->proxy, selfp->pending_call);
    102 	  }
    103 
    104 	self_disconnect_proxy_signals(self);
    105 
    106 	g_signal_handlers_disconnect_by_func(selfp->client, mn_mailbox_check, self);
    107       }
    108   }
    109 
    110   private void
    111     connect_proxy_signals (self)
    112   {
    113     g_return_if_fail(selfp->client != NULL);
    114     g_return_if_fail(selfp->client->proxy != NULL);
    115 
    116     if (selfp->signals_connected)
    117       return;
    118 
    119     dbus_g_proxy_connect_signal(selfp->client->proxy,
    120 				MN_EVOLUTION_SERVER_SIGNAL_FOLDER_CHANGED,
    121 				G_CALLBACK(self_folder_changed_h),
    122 				self,
    123 				NULL);
    124     dbus_g_proxy_connect_signal(selfp->client->proxy,
    125 				MN_EVOLUTION_SERVER_SIGNAL_MESSAGE_READING,
    126 				G_CALLBACK(self_message_reading_h),
    127 				self,
    128 				NULL);
    129 
    130     selfp->signals_connected = TRUE;
    131   }
    132 
    133   private void
    134     disconnect_proxy_signals (self)
    135   {
    136     g_return_if_fail(selfp->client != NULL);
    137 
    138     if (! selfp->signals_connected)
    139       return;
    140 
    141     selfp->signals_connected = FALSE;
    142 
    143     if (! selfp->client->proxy)
    144       return;
    145 
    146     dbus_g_proxy_disconnect_signal(selfp->client->proxy,
    147 				   MN_EVOLUTION_SERVER_SIGNAL_FOLDER_CHANGED,
    148 				   G_CALLBACK(self_folder_changed_h),
    149 				   self);
    150     dbus_g_proxy_disconnect_signal(selfp->client->proxy,
    151 				   MN_EVOLUTION_SERVER_SIGNAL_MESSAGE_READING,
    152 				   G_CALLBACK(self_message_reading_h),
    153 				   self);
    154   }
    155 
    156   private void
    157     folder_changed_h (DBusGProxy *proxy, const char *uri, gpointer user_data)
    158   {
    159     Self *self = user_data;
    160 
    161     if (! strcmp(uri, self->uri))
    162       {
    163 	GDK_THREADS_ENTER();
    164 	mn_mailbox_check(MN_MAILBOX(self));
    165 	GDK_THREADS_LEAVE();
    166       }
    167   }
    168 
    169   private void
    170     message_reading_h (DBusGProxy *proxy, const char *uri, gpointer user_data)
    171   {
    172     Self *self = user_data;
    173 
    174     if (! strcmp(uri, self->uri))
    175       {
    176 	selfp->last_browsed = mn_time();
    177 
    178 	GDK_THREADS_ENTER();
    179 	mn_mailbox_check(MN_MAILBOX(self));
    180 	GDK_THREADS_LEAVE();
    181       }
    182   }
    183 
    184   private void
    185     value_array_get_values (GValueArray *value_array (check null), ...)
    186   {
    187     va_list args;
    188     int i;
    189 
    190     va_start(args, value_array);
    191 
    192     for (i = 0; i < value_array->n_values; i++)
    193       {
    194 	GValue *value = g_value_array_get_nth(value_array, i);
    195 	char *error = NULL;
    196 
    197 	G_VALUE_LCOPY(value, args, G_VALUE_NOCOPY_CONTENTS, &error);
    198 	g_assert(error == NULL);
    199       }
    200 
    201     va_end(args);
    202   }
    203 
    204   override (MN:Mailbox) void
    205     check (MNMailbox *mailbox)
    206   {
    207     Self *self = SELF(mailbox);
    208 
    209     PARENT_HANDLER(mailbox);
    210 
    211     mn_mailbox_set_error(mailbox, NULL);
    212 
    213     if (! selfp->client)
    214       {
    215 	selfp->client = mn_evolution_client_get();
    216 	g_signal_connect_swapped(selfp->client, "notify::proxy", G_CALLBACK(mn_mailbox_check), self);
    217       }
    218 
    219     if (! selfp->client->proxy)	/* not connected */
    220       {
    221 	selfp->pending_call = NULL;
    222 
    223 	self_disconnect_proxy_signals(self);
    224 
    225 	mn_mailbox_set_error(mailbox, _("unable to contact Evolution"));
    226 
    227 	return;
    228       }
    229 
    230     self_connect_proxy_signals(self);
    231 
    232     if (selfp->pending_call)
    233       dbus_g_proxy_cancel_call(selfp->client->proxy, selfp->pending_call);
    234 
    235     selfp->pending_call = org_gnome_MailNotification_Evolution_get_unseen_messages_async(selfp->client->proxy,
    236 											 self->uri,
    237 											 self_get_unseen_messages_cb,
    238 											 self);
    239   }
    240 
    241   private void
    242     get_unseen_messages_cb (DBusGProxy *proxy,
    243 			    GPtrArray *messages_array,
    244 			    GError *err,
    245 			    gpointer user_data)
    246   {
    247     Self *self = user_data;
    248 
    249     GDK_THREADS_ENTER();
    250 
    251     if (err)
    252       {
    253 	mn_mailbox_set_error(MN_MAILBOX(self), "%s", err->message);
    254 	g_error_free(err);
    255       }
    256     else
    257       {
    258 	int i;
    259 	GSList *messages = NULL;
    260 
    261 	for (i = 0; i < messages_array->len; i++)
    262 	  {
    263 	    GValueArray *value_array = g_ptr_array_index(messages_array, i);
    264 	    MessageInfo info;
    265 	    MNMessageFlags flags = 0;
    266 
    267 	    self_value_array_get_values(value_array,
    268 					&info.uid,
    269 					&info.sent_time,
    270 					&info.received_time,
    271 					&info.id,
    272 					&info.from,
    273 					&info.subject);
    274 
    275 	    if (info.received_time > selfp->last_browsed)
    276 	      flags |= MN_MESSAGE_NEW;
    277 
    278 	    messages = g_slist_prepend(messages,
    279 				       mn_evolution_message_new(MN_MAILBOX(self),
    280 								info.sent_time,
    281 								info.id,
    282 								info.from,
    283 								info.subject,
    284 								flags,
    285 								info.uid));
    286 	  }
    287 
    288 	mn_g_ptr_array_free_deep_custom(messages_array, (GFunc) g_value_array_free, NULL);
    289 
    290 	mn_mailbox_set_messages(MN_MAILBOX(self), messages);
    291 	mn_g_object_slist_free(messages);
    292       }
    293 
    294     selfp->pending_call = NULL;
    295 
    296     GDK_THREADS_LEAVE();
    297   }
    298 }