Added support for external addressbook Nokia service in hildon (com.nokia.asdbus).
[modest] / src / modest-account-protocol.c
1 /* Copyright (c) 2008, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <tny-simple-list.h>
31 #include "modest-account-protocol.h"
32 #include "modest-account-mgr-helpers.h"
33 #include "widgets/modest-default-account-settings-dialog.h"
34 #include "modest-runtime.h"
35 #include "modest-marshal.h"
36
37 enum {
38         PROP_0,
39         PROP_PORT,
40         PROP_ALTERNATE_PORT,
41         PROP_ACCOUNT_G_TYPE,
42 };
43
44 typedef struct _ModestAccountProtocolPrivate ModestAccountProtocolPrivate;
45 struct _ModestAccountProtocolPrivate {
46         guint port;
47         guint alternate_port;
48         TnyList *account_options;
49         GHashTable *custom_auth_mechs;
50         GType account_g_type;
51
52         GHashTable *account_dialogs;
53 };
54
55 /* 'private'/'protected' functions */
56 static void   modest_account_protocol_class_init (ModestAccountProtocolClass *klass);
57 static void   modest_account_protocol_finalize   (GObject *obj);
58 static void   modest_account_protocol_get_property (GObject *obj,
59                                             guint property_id,
60                                             GValue *value,
61                                             GParamSpec *pspec);
62 static void   modest_account_protocol_set_property (GObject *obj,
63                                             guint property_id,
64                                             const GValue *value,
65                                             GParamSpec *pspec);
66 static void   modest_account_protocol_instance_init (ModestAccountProtocol *obj);
67
68 #define MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE(o)     (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
69                                                                                  MODEST_TYPE_ACCOUNT_PROTOCOL, \
70                                                                                  ModestAccountProtocolPrivate))
71
72 static TnyAccount *modest_account_protocol_create_account_default (ModestAccountProtocol *self);
73
74 static ModestAccountSettingsDialog *modest_account_protocol_create_account_settings_dialog_default (ModestAccountProtocol *self);
75
76 static ModestPairList* modest_account_protocol_get_easysetupwizard_tabs_default (ModestAccountProtocol *self);
77
78 static void modest_account_protocol_save_settings_default (ModestAccountProtocol *self, 
79                                                            ModestAccountSettingsDialog *dialog,
80                                                            ModestAccountSettings *settings);
81
82 static void modest_account_protocol_save_wizard_settings_default (ModestAccountProtocol *self, 
83                                                                   GList *wizard_pages,
84                                                                   ModestAccountSettings *settings);
85
86 static ModestWizardDialogResponseOverrideFunc 
87 modest_account_protocol_get_wizard_response_override_default (ModestAccountProtocol *self);
88
89 static void modest_account_protocol_check_support_default (ModestAccountProtocol *self,
90                                                            ModestAccountProtocolCheckSupportFunc func,
91                                                            gpointer userdata);
92 static void modest_account_protocol_cancel_check_support_default (ModestAccountProtocol *self);
93 static void modest_account_protocol_wizard_finished_default (ModestAccountProtocol *self);
94 static gboolean modest_account_protocol_decode_part_to_stream_default (ModestAccountProtocol *protocol,
95                                                                        TnyMimePart *part,
96                                                                        const gchar *stream_uri,
97                                                                        TnyStream *stream,
98                                                                        gssize *written,
99                                                                        GError **error);
100 static gboolean modest_account_protocol_decode_part_to_stream_async_default (ModestAccountProtocol *protocol,
101                                                                              TnyMimePart *self, 
102                                                                              const gchar *stream_uri,
103                                                                              TnyStream *stream, 
104                                                                              TnyMimePartCallback callback, 
105                                                                              TnyStatusCallback status_callback, 
106                                                                              gpointer user_data);
107 static gboolean modest_account_protocol_is_supported_default (ModestAccountProtocol *self);
108 static gchar *modest_account_protocol_get_from_default (ModestAccountProtocol *self,
109                                                         const gchar *account_id,
110                                                         const gchar *mailbox);
111 static ModestPairList *modest_account_protocol_get_from_list_default (ModestAccountProtocol *self,
112                                                                       const gchar *account_id);
113 static gchar *modest_account_protocol_get_signature_default (ModestAccountProtocol *self,
114                                                              const gchar *account_id,
115                                                              const gchar *mailbox,
116                                                              gboolean *has_signature);
117 static const GdkPixbuf *modest_account_protocol_get_icon_default (ModestAccountProtocol *self,
118                                                                   ModestAccountProtocolIconType icon_type, 
119                                                                   GObject *object, 
120                                                                   guint icon_size);
121
122 static gchar *modest_account_protocol_get_service_name_default (ModestAccountProtocol *self,
123                                                                 const gchar *account_id,
124                                                                 const gchar *mailbox);
125
126 static const GdkPixbuf *modest_account_protocol_get_service_icon_default (ModestAccountProtocol *self,
127                                                                           const gchar *account_id,
128                                                                           const gchar *mailbox,
129                                                                           guint icon_size);
130 static void modest_account_protocol_save_remote_draft_default (ModestAccountProtocol *self,
131                                                                const gchar *account_id,
132                                                                TnyMsg *new_msg,
133                                                                TnyMsg *old_msg,
134                                                                ModestAccountProtocolSaveRemoteDraftCallback callback,
135                                                                gpointer userdata);
136 static gboolean
137 modest_account_protocol_handle_calendar_default (ModestAccountProtocol *self,
138                                                  ModestWindow *window,
139                                                  TnyMimePart *calendar_part,
140                                                  GtkContainer *container);
141
142 /* globals */
143 static GObjectClass *parent_class = NULL;
144
145 GType
146 modest_account_protocol_get_type (void)
147 {
148         static GType my_type = 0;
149
150         if (!my_type) {
151                 static const GTypeInfo my_info = {
152                         sizeof(ModestAccountProtocolClass),
153                         NULL,   /* base init */
154                         NULL,   /* base finalize */
155                         (GClassInitFunc) modest_account_protocol_class_init,
156                         NULL,   /* class finalize */
157                         NULL,   /* class data */
158                         sizeof(ModestAccountProtocol),
159                         0,      /* n_preallocs */
160                         (GInstanceInitFunc) modest_account_protocol_instance_init,
161                         NULL
162                 };
163
164                 my_type = g_type_register_static (MODEST_TYPE_PROTOCOL,
165                                                   "ModestAccountProtocol",
166                                                   &my_info, 0);
167         }
168         return my_type;
169 }
170
171 static void
172 modest_account_protocol_class_init (ModestAccountProtocolClass *klass)
173 {
174         GObjectClass *object_class;
175         ModestAccountProtocolClass *account_class;
176
177         object_class = (GObjectClass *) klass;
178         account_class = MODEST_ACCOUNT_PROTOCOL_CLASS (klass);
179         parent_class = g_type_class_peek_parent (klass);
180         object_class->finalize = modest_account_protocol_finalize;
181         object_class->set_property = modest_account_protocol_set_property;
182         object_class->get_property = modest_account_protocol_get_property;
183
184         g_object_class_install_property (object_class,
185                                          PROP_PORT,
186                                          g_param_spec_uint ("port",
187                                                            _("Standard port"),
188                                                            _("The standard port for the protocol"),
189                                                            0, G_MAXINT, 0,
190                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
191
192         g_object_class_install_property (object_class,
193                                          PROP_ALTERNATE_PORT,
194                                          g_param_spec_uint ("alternate-port",
195                                                            _("Alternate port"),
196                                                            _("The alternate port for the protocol (usually used in SSL)"),
197                                                            0, G_MAXINT, 0,
198                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
199
200         g_object_class_install_property (object_class,
201                                          PROP_ACCOUNT_G_TYPE,
202                                          g_param_spec_gtype ("account-g-type",
203                                                              _("Account factory GType"),
204                                                              _("Account factory GType used for creating new instances."),
205                                                              TNY_TYPE_ACCOUNT,
206                                                              G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
207
208         g_type_class_add_private (object_class,
209                                   sizeof(ModestAccountProtocolPrivate));
210
211         /* Virtual methods */
212         account_class->create_account_settings_dialog = 
213                 modest_account_protocol_create_account_settings_dialog_default;
214         account_class->get_easysetupwizard_tabs = 
215                 modest_account_protocol_get_easysetupwizard_tabs_default;
216         account_class->save_settings = 
217                 modest_account_protocol_save_settings_default;
218         account_class->save_wizard_settings = 
219                 modest_account_protocol_save_wizard_settings_default;
220         account_class->create_account =
221                 modest_account_protocol_create_account_default;
222         account_class->get_wizard_response_override =
223                 modest_account_protocol_get_wizard_response_override_default;
224         account_class->is_supported =
225                 modest_account_protocol_is_supported_default;
226         account_class->check_support =
227                 modest_account_protocol_check_support_default;
228         account_class->cancel_check_support =
229                 modest_account_protocol_cancel_check_support_default;
230         account_class->wizard_finished =
231                 modest_account_protocol_wizard_finished_default;
232         account_class->decode_part_to_stream =
233                 modest_account_protocol_decode_part_to_stream_default;
234         account_class->decode_part_to_stream_async =
235                 modest_account_protocol_decode_part_to_stream_async_default;
236         account_class->get_from =
237                 modest_account_protocol_get_from_default;
238         account_class->get_from_list =
239                 modest_account_protocol_get_from_list_default;
240         account_class->get_signature =
241                 modest_account_protocol_get_signature_default;
242         account_class->get_icon =
243                 modest_account_protocol_get_icon_default;
244         account_class->get_service_name =
245                 modest_account_protocol_get_service_name_default;
246         account_class->get_service_icon =
247                 modest_account_protocol_get_service_icon_default;
248         account_class->save_remote_draft =
249                 modest_account_protocol_save_remote_draft_default;
250         account_class->handle_calendar =
251                 modest_account_protocol_handle_calendar_default;
252
253 }
254
255 static void
256 modest_account_protocol_instance_init (ModestAccountProtocol *obj)
257 {
258         ModestAccountProtocolPrivate *priv;
259
260         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (obj);
261
262         priv->port = 0;
263         priv->alternate_port = 0;
264         priv->account_g_type = 0;
265         priv->account_options = tny_simple_list_new ();
266         priv->custom_auth_mechs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
267
268         priv->account_dialogs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
269 }
270
271 static gboolean
272 remove_account (const gchar *account_name, GObject *account, GObject *account_to_remove)
273 {
274         return (account == account_to_remove);
275 }
276
277 static void
278 account_dialog_weak_handler (ModestAccountProtocol *self, GObject *where_the_object_was)
279 {
280         ModestAccountProtocolPrivate *priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
281
282         g_hash_table_foreach_remove (priv->account_dialogs, (GHRFunc) remove_account, where_the_object_was);
283 }
284
285 static gboolean
286 dialogs_remove (const gchar *account_name, GObject *account_dialog, ModestAccountProtocol *self)
287 {
288         g_object_weak_unref (account_dialog, (GWeakNotify) account_dialog_weak_handler, self);
289
290         return TRUE;
291 }
292
293 static void   
294 modest_account_protocol_finalize   (GObject *obj)
295 {
296         ModestAccountProtocol *protocol = MODEST_ACCOUNT_PROTOCOL (obj);
297         ModestAccountProtocolPrivate *priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (protocol);
298
299         if (priv->account_dialogs) {
300                 g_hash_table_foreach_remove (priv->account_dialogs, (GHRFunc) dialogs_remove, obj);
301                 g_hash_table_destroy (priv->account_dialogs);
302         }
303
304         if (priv->account_options)
305                 g_object_unref (priv->account_options);
306         priv->account_options = NULL;
307
308         if (priv->custom_auth_mechs)
309                 g_hash_table_destroy (priv->custom_auth_mechs);
310         priv->custom_auth_mechs = NULL;
311
312         G_OBJECT_CLASS (parent_class)->finalize (obj);
313 }
314
315 static void   
316 modest_account_protocol_get_property (GObject *obj,
317                                       guint property_id,
318                                       GValue *value,
319                                       GParamSpec *pspec)
320 {
321         ModestAccountProtocol *protocol = MODEST_ACCOUNT_PROTOCOL (obj);
322         ModestAccountProtocolPrivate *priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (protocol);
323
324         switch (property_id) {
325         case PROP_PORT:
326                 g_value_set_uint (value, priv->port);
327                 break;
328         case PROP_ALTERNATE_PORT:
329                 g_value_set_uint (value, priv->alternate_port);
330                 break;
331         case PROP_ACCOUNT_G_TYPE:
332                 g_value_set_gtype (value, priv->account_g_type);
333                 break;
334         default:
335                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
336         }
337
338 }
339
340 static void   
341 modest_account_protocol_set_property (GObject *obj,
342                                       guint property_id,
343                                       const GValue *value,
344                                       GParamSpec *pspec)
345 {
346         ModestAccountProtocol *protocol = MODEST_ACCOUNT_PROTOCOL (obj);
347
348         switch (property_id) {
349         case PROP_PORT:
350                 modest_account_protocol_set_port (protocol, g_value_get_uint (value));
351                 break;
352         case PROP_ALTERNATE_PORT:
353                 modest_account_protocol_set_alternate_port (protocol, g_value_get_uint (value));
354                 break;
355         case PROP_ACCOUNT_G_TYPE:
356                 modest_account_protocol_set_account_g_type (protocol, g_value_get_gtype (value));
357                 break;
358         default:
359                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
360         }
361
362 }
363
364
365 ModestProtocol*
366 modest_account_protocol_new (const gchar *name, const gchar *display_name,
367                              guint port, guint alternate_port,
368                              GType account_g_type)
369 {
370         return g_object_new (MODEST_TYPE_ACCOUNT_PROTOCOL, 
371                              "display-name", display_name, "name", name, 
372                              "port", port, "alternate-port", alternate_port,
373                              "account-g-type", account_g_type,
374                              NULL);
375 }
376
377 guint
378 modest_account_protocol_get_port (ModestAccountProtocol *self)
379 {
380         ModestAccountProtocolPrivate *priv;
381
382         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), 0);
383
384         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
385         return priv->port;
386 }
387
388 void         
389 modest_account_protocol_set_port (ModestAccountProtocol *self,
390                                   guint port)
391 {
392         ModestAccountProtocolPrivate *priv;
393
394         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
395
396         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
397         priv->port = port;
398 }
399
400
401 guint
402 modest_account_protocol_get_alternate_port (ModestAccountProtocol *self)
403 {
404         ModestAccountProtocolPrivate *priv;
405
406         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), 0);
407
408         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
409         return priv->alternate_port;
410 }
411
412 void         
413 modest_account_protocol_set_alternate_port (ModestAccountProtocol *self,
414                                             guint alternate_port)
415 {
416         ModestAccountProtocolPrivate *priv;
417
418         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
419
420         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
421         priv->alternate_port = alternate_port;
422 }
423
424 GType
425 modest_account_protocol_get_account_g_type (ModestAccountProtocol *self)
426 {
427         ModestAccountProtocolPrivate *priv;
428
429         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), 0);
430
431         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
432         return priv->account_g_type;
433 }
434
435 TnyList *
436 modest_account_protocol_get_account_options (ModestAccountProtocol *self)
437 {
438         TnyList *result;
439         ModestAccountProtocolPrivate *priv;
440
441         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
442         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
443
444         result = tny_list_copy (priv->account_options);
445
446         return result;
447 }
448
449 void
450 modest_account_protocol_set_account_options (ModestAccountProtocol *self,
451                                              TnyList *list)
452 {
453         ModestAccountProtocolPrivate *priv;
454
455         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
456         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
457
458         if (priv->account_options) {
459                 g_object_unref (priv->account_options);
460                 priv->account_options = NULL;
461         }
462         priv->account_options = tny_list_copy (list);
463 }
464
465 gboolean
466 modest_account_protocol_has_custom_secure_auth_mech (ModestAccountProtocol *self, 
467                                                      ModestProtocolType auth_protocol_type)
468 {
469         ModestAccountProtocolPrivate *priv;
470
471         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), FALSE);
472         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
473
474         return g_hash_table_lookup_extended (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type), NULL, NULL);
475 }
476
477 const gchar *
478 modest_account_protocol_get_custom_secure_auth_mech (ModestAccountProtocol *self, 
479                                                      ModestProtocolType auth_protocol_type)
480 {
481         ModestAccountProtocolPrivate *priv;
482
483         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
484         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
485
486         return (const gchar *) g_hash_table_lookup (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type));
487 }
488
489 void
490 modest_account_protocol_set_custom_secure_auth_mech (ModestAccountProtocol *self, ModestProtocolType auth_protocol_type, const gchar *secure_auth_mech)
491 {
492         ModestAccountProtocolPrivate *priv;
493
494         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
495         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
496
497         g_hash_table_replace (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type), g_strdup (secure_auth_mech));
498 }
499
500 void
501 modest_account_protocol_unset_custom_secure_auth_mech (ModestAccountProtocol *self, ModestProtocolType auth_protocol_type)
502 {
503         ModestAccountProtocolPrivate *priv;
504
505         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
506         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
507
508         g_hash_table_remove (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type));
509 }
510
511
512 void         
513 modest_account_protocol_set_account_g_type (ModestAccountProtocol *self,
514                                             GType account_g_type)
515 {
516         ModestAccountProtocolPrivate *priv;
517
518         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
519
520         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
521         priv->account_g_type = account_g_type;
522 }
523
524 static TnyAccount *
525 modest_account_protocol_create_account_default (ModestAccountProtocol *self)
526 {
527         ModestAccountProtocolPrivate *priv;
528
529         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
530
531         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
532         if (priv->account_g_type > 0) {
533                 return g_object_new (priv->account_g_type, NULL);
534         } else {
535                 return NULL;
536         }
537 }
538
539 TnyAccount *
540 modest_account_protocol_create_account (ModestAccountProtocol *self)
541 {
542         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
543
544         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->create_account (self); 
545 }
546
547 /* This is a template method for getting the account settings
548    dialog. It calls create_account_settings that must be implemented
549    by subclasses and then perform several common operations with the
550    dialog */
551 ModestAccountSettingsDialog *
552 modest_account_protocol_get_account_settings_dialog (ModestAccountProtocol *self,
553                                                      const gchar *account_name)
554 {
555         ModestAccountSettingsDialog *dialog;
556         ModestAccountSettings *settings;
557         ModestAccountProtocolPrivate *priv;
558
559         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
560         dialog = g_hash_table_lookup (priv->account_dialogs, account_name);
561
562         if (dialog == NULL) {
563
564                 dialog = MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->create_account_settings_dialog (self);
565
566                 /* Check existence of dialog */
567                 if (dialog == NULL)
568                         return NULL;
569
570                 /* Load settings */
571                 settings = modest_account_mgr_load_account_settings (modest_runtime_get_account_mgr (),
572                                                                      account_name);
573                 modest_account_settings_dialog_load_settings (dialog, settings);
574
575                 /* Close dialog on response */
576                 g_signal_connect_swapped (dialog,
577                                           "response",
578                                           G_CALLBACK (gtk_widget_destroy),
579                                           dialog);
580
581                 g_hash_table_insert (priv->account_dialogs, g_strdup (account_name), dialog);
582                 g_object_weak_ref (G_OBJECT (dialog), (GWeakNotify) account_dialog_weak_handler, self);
583         }
584
585         return dialog;
586 }
587
588 ModestPairList*
589 modest_account_protocol_get_easysetupwizard_tabs (ModestAccountProtocol *self)
590 {
591         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_easysetupwizard_tabs (self);
592 }
593
594
595 void 
596 modest_account_protocol_save_settings (ModestAccountProtocol *self, 
597                                        ModestAccountSettingsDialog *dialog,
598                                        ModestAccountSettings *settings)
599 {
600         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->save_settings (self, dialog, settings);
601 }
602
603 void 
604 modest_account_protocol_save_wizard_settings (ModestAccountProtocol *self, 
605                                               GList *wizard_pages,
606                                               ModestAccountSettings *settings)
607 {
608         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->save_wizard_settings (self, wizard_pages, settings);
609 }
610
611 /* Default implementations */
612 static ModestAccountSettingsDialog *
613 modest_account_protocol_create_account_settings_dialog_default (ModestAccountProtocol *self)
614 {
615         return modest_default_account_settings_dialog_new ();
616 }
617
618 static ModestPairList*
619 modest_account_protocol_get_easysetupwizard_tabs_default (ModestAccountProtocol *self)
620 {
621         g_warning ("You must implement get_easysetupwizard_tabs");
622         return NULL;
623 }
624
625 static void 
626 modest_account_protocol_save_settings_default (ModestAccountProtocol *self, 
627                                                ModestAccountSettingsDialog *dialog,
628                                                ModestAccountSettings *settings)
629 {
630         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
631         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS_DIALOG (dialog));
632         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
633
634         g_warning ("You must implement save_settings");
635 }
636
637 static void 
638 modest_account_protocol_save_wizard_settings_default (ModestAccountProtocol *self, 
639                                                       GList *wizard_pages,
640                                                       ModestAccountSettings *settings)
641 {
642         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
643         g_return_if_fail (wizard_pages);
644         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
645
646         g_warning ("You must implement save_wizard_settings");
647 }
648
649 static ModestWizardDialogResponseOverrideFunc
650 modest_account_protocol_get_wizard_response_override_default (ModestAccountProtocol *self)
651 {
652         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
653
654         return NULL;
655 }
656
657 ModestWizardDialogResponseOverrideFunc
658 modest_account_protocol_get_wizard_response_override (ModestAccountProtocol *self)
659 {
660         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
661
662         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_wizard_response_override (self);   
663 }
664
665 static gboolean
666 modest_account_protocol_is_supported_default (ModestAccountProtocol *self)
667 {
668         return TRUE;
669 }
670
671 gboolean
672 modest_account_protocol_is_supported (ModestAccountProtocol *self)
673 {
674         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->is_supported (self);
675 }
676
677 static void
678 modest_account_protocol_check_support_default (ModestAccountProtocol *self,
679                                                ModestAccountProtocolCheckSupportFunc func,
680                                                gpointer userdata)
681 {
682         if (func)
683                 func (self, TRUE, userdata);
684 }
685
686 void
687 modest_account_protocol_check_support (ModestAccountProtocol *self,
688                                        ModestAccountProtocolCheckSupportFunc func,
689                                        gpointer userdata)
690 {
691         MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->check_support (self, func, userdata);
692 }
693
694 static void
695 modest_account_protocol_cancel_check_support_default (ModestAccountProtocol *self)
696 {
697         return;
698 }
699
700 void
701 modest_account_protocol_cancel_check_support (ModestAccountProtocol *self)
702 {
703         MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->cancel_check_support (self);
704 }
705
706 static void
707 modest_account_protocol_wizard_finished_default (ModestAccountProtocol *self)
708 {
709         return;
710 }
711
712 void
713 modest_account_protocol_wizard_finished (ModestAccountProtocol *self)
714 {
715         MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->wizard_finished (self);
716 }
717
718 static gboolean
719 modest_account_protocol_decode_part_to_stream_default (ModestAccountProtocol *self,
720                                                        TnyMimePart *part,
721                                                        const gchar *stream_uri,
722                                                        TnyStream *stream,
723                                                        gssize *written,
724                                                        GError **error)
725 {
726         /* By default account protocols do not handle themselves the transfer */
727         return FALSE;
728 }
729
730 gboolean
731 modest_account_protocol_decode_part_to_stream (ModestAccountProtocol *self,
732                                                TnyMimePart *part,
733                                                const gchar *stream_uri,
734                                                TnyStream *stream,
735                                                gssize *written,
736                                                GError **error)
737 {
738         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->decode_part_to_stream (self,
739                                                                                 part,
740                                                                                 stream_uri,
741                                                                                 stream,
742                                                                                 written,
743                                                                                 error);
744 }
745
746 static gboolean
747 modest_account_protocol_decode_part_to_stream_async_default (ModestAccountProtocol *self,
748                                                              TnyMimePart *part,
749                                                              const gchar *stream_uri,
750                                                              TnyStream *stream, 
751                                                              TnyMimePartCallback callback, 
752                                                              TnyStatusCallback status_callback, 
753                                                              gpointer user_data)
754 {
755         /* By default account protocols do not handle themselves the transfer */
756         return FALSE;
757 }
758
759 gboolean
760 modest_account_protocol_decode_part_to_stream_async (ModestAccountProtocol *self,
761                                                      TnyMimePart *part, 
762                                                      const gchar *stream_uri,
763                                                      TnyStream *stream, 
764                                                      TnyMimePartCallback callback, 
765                                                      TnyStatusCallback status_callback, 
766                                                      gpointer user_data)
767 {
768         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->decode_part_to_stream_async (self,
769                                                                                       part,
770                                                                                       stream_uri,
771                                                                                       stream,
772                                                                                       callback,
773                                                                                       status_callback,
774                                                                                       user_data);
775 }
776
777 gchar *
778 modest_account_protocol_get_from (ModestAccountProtocol *self,
779                                   const gchar *account_id,
780                                   const gchar *mailbox)
781 {
782         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_from (self, account_id, mailbox);
783 }
784 static gchar *
785 modest_account_protocol_get_from_default (ModestAccountProtocol *self,
786                                           const gchar *account_id,
787                                           const gchar *mailbox)
788 {
789         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
790
791         return NULL;
792 }
793
794 ModestPairList *
795 modest_account_protocol_get_from_list (ModestAccountProtocol *self,
796                                        const gchar *account_id)
797 {
798         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_from_list (self, account_id);
799 }
800 static ModestPairList *
801 modest_account_protocol_get_from_list_default (ModestAccountProtocol *self,
802                                                const gchar *account_id)
803 {
804         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
805
806         return NULL;
807 }
808
809 gchar *
810 modest_account_protocol_get_signature (ModestAccountProtocol *self,
811                                        const gchar *account_id,
812                                        const gchar *mailbox,
813                                        gboolean *has_signature)
814 {
815         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_signature (self, account_id, mailbox, has_signature);
816 }
817
818 static gchar *
819 modest_account_protocol_get_signature_default (ModestAccountProtocol *self,
820                                                const gchar *account_id,
821                                                const gchar *mailbox,
822                                                gboolean *has_signature)
823 {
824         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
825         if (has_signature)
826                 *has_signature = FALSE;
827
828         return NULL;
829 }
830
831 const GdkPixbuf*
832 modest_account_protocol_get_icon (ModestAccountProtocol *self,
833                                   ModestAccountProtocolIconType icon_type,
834                                   GObject *object,
835                                   guint icon_size)
836 {
837         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_icon (self, icon_type, object, icon_size);
838 }
839
840 static const GdkPixbuf * 
841 modest_account_protocol_get_icon_default (ModestAccountProtocol *self, ModestAccountProtocolIconType icon_type, 
842                                           GObject *object, guint icon_size)
843 {
844         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
845
846         return NULL;
847 }
848
849 gchar *
850 modest_account_protocol_get_service_name (ModestAccountProtocol *self,
851                                           const gchar *account_id,
852                                           const gchar *mailbox)
853 {
854         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_service_name (self, account_id, mailbox);
855 }
856
857 static gchar *
858 modest_account_protocol_get_service_name_default (ModestAccountProtocol *self,
859                                                   const gchar *account_id,
860                                                   const gchar *mailbox)
861 {
862         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
863
864         return NULL;
865 }
866
867 const GdkPixbuf *
868 modest_account_protocol_get_service_icon (ModestAccountProtocol *self,
869                                           const gchar *account_id,
870                                           const gchar *mailbox,
871                                           guint icon_size)
872 {
873         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_service_icon (self, account_id, mailbox, icon_size);
874 }
875
876 static const GdkPixbuf *
877 modest_account_protocol_get_service_icon_default (ModestAccountProtocol *self,
878                                                   const gchar *account_id,
879                                                   const gchar *mailbox,
880                                                   guint icon_size)
881 {
882         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
883
884         return NULL;
885 }
886
887 void
888 modest_account_protocol_save_remote_draft (ModestAccountProtocol *self,
889                                            const gchar *account_id,
890                                            TnyMsg *new_msg,
891                                            TnyMsg *old_msg,
892                                            ModestAccountProtocolSaveRemoteDraftCallback callback,
893                                            gpointer userdata)
894 {
895         MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->save_remote_draft (self, account_id, 
896                                                                      new_msg, old_msg,
897                                                                      callback, userdata);
898 }
899
900 static void
901 modest_account_protocol_save_remote_draft_default (ModestAccountProtocol *self,
902                                                    const gchar *account_id,
903                                                    TnyMsg *new_msg,
904                                                    TnyMsg *old_msg,
905                                                    ModestAccountProtocolSaveRemoteDraftCallback callback,
906                                                    gpointer userdata)
907 {
908         if (callback) {
909                 callback (self, NULL, account_id, NULL, new_msg, old_msg, userdata);
910         }
911 }
912
913 gboolean
914 modest_account_protocol_handle_calendar (ModestAccountProtocol *self,
915                                          ModestWindow *window,
916                                          TnyMimePart *calendar_part,
917                                          GtkContainer *container)
918 {
919         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->handle_calendar (self, window, 
920                                                                           calendar_part, container);
921 }
922
923 static gboolean
924 modest_account_protocol_handle_calendar_default (ModestAccountProtocol *self,
925                                                  ModestWindow *window,
926                                                  TnyMimePart *calendar_part,
927                                                  GtkContainer *container)
928 {
929         return FALSE;
930 }