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 }