Better addresses split (fixes NB#98684).
[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
36 enum {
37         PROP_0,
38         PROP_PORT,
39         PROP_ALTERNATE_PORT,
40         PROP_ACCOUNT_G_TYPE,
41 };
42
43 typedef struct _ModestAccountProtocolPrivate ModestAccountProtocolPrivate;
44 struct _ModestAccountProtocolPrivate {
45         guint port;
46         guint alternate_port;
47         TnyList *account_options;
48         GHashTable *custom_auth_mechs;
49         GType account_g_type;
50 };
51
52 /* 'private'/'protected' functions */
53 static void   modest_account_protocol_class_init (ModestAccountProtocolClass *klass);
54 static void   modest_account_protocol_finalize   (GObject *obj);
55 static void   modest_account_protocol_get_property (GObject *obj,
56                                             guint property_id,
57                                             GValue *value,
58                                             GParamSpec *pspec);
59 static void   modest_account_protocol_set_property (GObject *obj,
60                                             guint property_id,
61                                             const GValue *value,
62                                             GParamSpec *pspec);
63 static void   modest_account_protocol_instance_init (ModestAccountProtocol *obj);
64
65 #define MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE(o)     (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
66                                                                                  MODEST_TYPE_ACCOUNT_PROTOCOL, \
67                                                                                  ModestAccountProtocolPrivate))
68
69 static TnyAccount *modest_account_protocol_create_account_default (ModestAccountProtocol *self);
70
71 static ModestAccountSettingsDialog *modest_account_protocol_create_account_settings_dialog_default (ModestAccountProtocol *self);
72
73 static ModestPairList* modest_account_protocol_get_easysetupwizard_tabs_default (ModestAccountProtocol *self);
74
75 static void modest_account_protocol_save_settings_default (ModestAccountProtocol *self, 
76                                                            ModestAccountSettingsDialog *dialog,
77                                                            ModestAccountSettings *settings);
78
79 static void modest_account_protocol_save_wizard_settings_default (ModestAccountProtocol *self, 
80                                                                   GList *wizard_pages,
81                                                                   ModestAccountSettings *settings);
82
83 /* globals */
84 static GObjectClass *parent_class = NULL;
85
86 GType
87 modest_account_protocol_get_type (void)
88 {
89         static GType my_type = 0;
90
91         if (!my_type) {
92                 static const GTypeInfo my_info = {
93                         sizeof(ModestAccountProtocolClass),
94                         NULL,   /* base init */
95                         NULL,   /* base finalize */
96                         (GClassInitFunc) modest_account_protocol_class_init,
97                         NULL,   /* class finalize */
98                         NULL,   /* class data */
99                         sizeof(ModestAccountProtocol),
100                         0,      /* n_preallocs */
101                         (GInstanceInitFunc) modest_account_protocol_instance_init,
102                         NULL
103                 };
104
105                 my_type = g_type_register_static (MODEST_TYPE_PROTOCOL,
106                                                   "ModestAccountProtocol",
107                                                   &my_info, 0);
108         }
109         return my_type;
110 }
111
112 static void
113 modest_account_protocol_class_init (ModestAccountProtocolClass *klass)
114 {
115         GObjectClass *object_class;
116         ModestAccountProtocolClass *account_class;
117
118         object_class = (GObjectClass *) klass;
119         account_class = MODEST_ACCOUNT_PROTOCOL_CLASS (klass);
120         parent_class = g_type_class_peek_parent (klass);
121         object_class->finalize = modest_account_protocol_finalize;
122         object_class->set_property = modest_account_protocol_set_property;
123         object_class->get_property = modest_account_protocol_get_property;
124
125         g_object_class_install_property (object_class,
126                                          PROP_PORT,
127                                          g_param_spec_uint ("port",
128                                                            _("Standard port"),
129                                                            _("The standard port for the protocol"),
130                                                            0, G_MAXINT, 0,
131                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
132
133         g_object_class_install_property (object_class,
134                                          PROP_ALTERNATE_PORT,
135                                          g_param_spec_uint ("alternate-port",
136                                                            _("Alternate port"),
137                                                            _("The alternate port for the protocol (usually used in SSL)"),
138                                                            0, G_MAXINT, 0,
139                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
140
141         g_object_class_install_property (object_class,
142                                          PROP_ACCOUNT_G_TYPE,
143                                          g_param_spec_gtype ("account-g-type",
144                                                              _("Account factory GType"),
145                                                              _("Account factory GType used for creating new instances."),
146                                                              TNY_TYPE_ACCOUNT,
147                                                              G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
148
149         g_type_class_add_private (object_class,
150                                   sizeof(ModestAccountProtocolPrivate));
151
152         /* Virtual methods */
153         account_class->create_account_settings_dialog = 
154                 modest_account_protocol_create_account_settings_dialog_default;
155         account_class->get_easysetupwizard_tabs = 
156                 modest_account_protocol_get_easysetupwizard_tabs_default;
157         account_class->save_settings = 
158                 modest_account_protocol_save_settings_default;
159         account_class->save_wizard_settings = 
160                 modest_account_protocol_save_wizard_settings_default;
161         account_class->create_account =
162                 modest_account_protocol_create_account_default;
163 }
164
165 static void
166 modest_account_protocol_instance_init (ModestAccountProtocol *obj)
167 {
168         ModestAccountProtocolPrivate *priv;
169
170         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (obj);
171
172         priv->port = 0;
173         priv->alternate_port = 0;
174         priv->account_g_type = 0;
175         priv->account_options = tny_simple_list_new ();
176         priv->custom_auth_mechs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
177 }
178
179 static void   
180 modest_account_protocol_finalize   (GObject *obj)
181 {
182         ModestAccountProtocol *protocol = MODEST_ACCOUNT_PROTOCOL (obj);
183         ModestAccountProtocolPrivate *priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (protocol);
184
185         if (priv->account_options)
186                 g_object_unref (priv->account_options);
187         priv->account_options = NULL;
188
189         if (priv->custom_auth_mechs)
190                 g_hash_table_destroy (priv->custom_auth_mechs);
191         priv->custom_auth_mechs = NULL;
192
193         G_OBJECT_CLASS (parent_class)->finalize (obj);
194 }
195
196 static void   
197 modest_account_protocol_get_property (GObject *obj,
198                                       guint property_id,
199                                       GValue *value,
200                                       GParamSpec *pspec)
201 {
202         ModestAccountProtocol *protocol = MODEST_ACCOUNT_PROTOCOL (obj);
203         ModestAccountProtocolPrivate *priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (protocol);
204
205         switch (property_id) {
206         case PROP_PORT:
207                 g_value_set_uint (value, priv->port);
208                 break;
209         case PROP_ALTERNATE_PORT:
210                 g_value_set_uint (value, priv->alternate_port);
211                 break;
212         case PROP_ACCOUNT_G_TYPE:
213                 g_value_set_gtype (value, priv->account_g_type);
214                 break;
215         default:
216                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
217         }
218
219 }
220
221 static void   
222 modest_account_protocol_set_property (GObject *obj,
223                                       guint property_id,
224                                       const GValue *value,
225                                       GParamSpec *pspec)
226 {
227         ModestAccountProtocol *protocol = MODEST_ACCOUNT_PROTOCOL (obj);
228
229         switch (property_id) {
230         case PROP_PORT:
231                 modest_account_protocol_set_port (protocol, g_value_get_uint (value));
232                 break;
233         case PROP_ALTERNATE_PORT:
234                 modest_account_protocol_set_alternate_port (protocol, g_value_get_uint (value));
235                 break;
236         case PROP_ACCOUNT_G_TYPE:
237                 modest_account_protocol_set_account_g_type (protocol, g_value_get_gtype (value));
238                 break;
239         default:
240                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
241         }
242
243 }
244
245
246 ModestProtocol*
247 modest_account_protocol_new (const gchar *name, const gchar *display_name,
248                              guint port, guint alternate_port,
249                              GType account_g_type)
250 {
251         return g_object_new (MODEST_TYPE_ACCOUNT_PROTOCOL, 
252                              "display-name", display_name, "name", name, 
253                              "port", port, "alternate-port", alternate_port,
254                              "account-g-type", account_g_type,
255                              NULL);
256 }
257
258 guint
259 modest_account_protocol_get_port (ModestAccountProtocol *self)
260 {
261         ModestAccountProtocolPrivate *priv;
262
263         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), 0);
264
265         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
266         return priv->port;
267 }
268
269 void         
270 modest_account_protocol_set_port (ModestAccountProtocol *self,
271                                   guint port)
272 {
273         ModestAccountProtocolPrivate *priv;
274
275         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
276
277         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
278         priv->port = port;
279 }
280
281
282 guint
283 modest_account_protocol_get_alternate_port (ModestAccountProtocol *self)
284 {
285         ModestAccountProtocolPrivate *priv;
286
287         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), 0);
288
289         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
290         return priv->alternate_port;
291 }
292
293 void         
294 modest_account_protocol_set_alternate_port (ModestAccountProtocol *self,
295                                             guint alternate_port)
296 {
297         ModestAccountProtocolPrivate *priv;
298
299         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
300
301         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
302         priv->alternate_port = alternate_port;
303 }
304
305 GType
306 modest_account_protocol_get_account_g_type (ModestAccountProtocol *self)
307 {
308         ModestAccountProtocolPrivate *priv;
309
310         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), 0);
311
312         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
313         return priv->account_g_type;
314 }
315
316 TnyList *
317 modest_account_protocol_get_account_options (ModestAccountProtocol *self)
318 {
319         TnyList *result;
320         ModestAccountProtocolPrivate *priv;
321
322         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
323         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
324
325         result = tny_list_copy (priv->account_options);
326
327         return result;
328 }
329
330 void
331 modest_account_protocol_set_account_options (ModestAccountProtocol *self,
332                                              TnyList *list)
333 {
334         ModestAccountProtocolPrivate *priv;
335
336         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
337         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
338
339         if (priv->account_options) {
340                 g_object_unref (priv->account_options);
341                 priv->account_options = NULL;
342         }
343         priv->account_options = tny_list_copy (list);
344 }
345
346 gboolean
347 modest_account_protocol_has_custom_secure_auth_mech (ModestAccountProtocol *self, 
348                                                      ModestProtocolType auth_protocol_type)
349 {
350         ModestAccountProtocolPrivate *priv;
351
352         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), FALSE);
353         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
354
355         return g_hash_table_lookup_extended (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type), NULL, NULL);
356 }
357
358 const gchar *
359 modest_account_protocol_get_custom_secure_auth_mech (ModestAccountProtocol *self, 
360                                                      ModestProtocolType auth_protocol_type)
361 {
362         ModestAccountProtocolPrivate *priv;
363
364         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
365         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
366
367         return (const gchar *) g_hash_table_lookup (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type));
368 }
369
370 void
371 modest_account_protocol_set_custom_secure_auth_mech (ModestAccountProtocol *self, ModestProtocolType auth_protocol_type, const gchar *secure_auth_mech)
372 {
373         ModestAccountProtocolPrivate *priv;
374
375         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
376         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
377
378         g_hash_table_replace (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type), g_strdup (secure_auth_mech));
379 }
380
381 void
382 modest_account_protocol_unset_custom_secure_auth_mech (ModestAccountProtocol *self, ModestProtocolType auth_protocol_type)
383 {
384         ModestAccountProtocolPrivate *priv;
385
386         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
387         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);      
388
389         g_hash_table_remove (priv->custom_auth_mechs, GINT_TO_POINTER (auth_protocol_type));
390 }
391
392
393 void         
394 modest_account_protocol_set_account_g_type (ModestAccountProtocol *self,
395                                             GType account_g_type)
396 {
397         ModestAccountProtocolPrivate *priv;
398
399         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
400
401         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
402         priv->account_g_type = account_g_type;
403 }
404
405 static TnyAccount *
406 modest_account_protocol_create_account_default (ModestAccountProtocol *self)
407 {
408         ModestAccountProtocolPrivate *priv;
409
410         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
411
412         priv = MODEST_ACCOUNT_PROTOCOL_GET_PRIVATE (self);
413         if (priv->account_g_type > 0) {
414                 return g_object_new (priv->account_g_type, NULL);
415         } else {
416                 return NULL;
417         }
418 }
419
420 TnyAccount *
421 modest_account_protocol_create_account (ModestAccountProtocol *self)
422 {
423         g_return_val_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self), NULL);
424
425         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->create_account (self); 
426 }
427
428 /* This is a template method for getting the account settings
429    dialog. It calls create_account_settings that must be implemented
430    by subclasses and then perform several common operations with the
431    dialog */
432 ModestAccountSettingsDialog *
433 modest_account_protocol_get_account_settings_dialog (ModestAccountProtocol *self,
434                                                      const gchar *account_name)
435 {
436         ModestAccountSettingsDialog *dialog;
437         ModestAccountSettings *settings;
438
439         dialog = MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->create_account_settings_dialog (self);
440         
441         /* Load settings */
442         settings = modest_account_mgr_load_account_settings (modest_runtime_get_account_mgr (), 
443                                                              account_name);
444         modest_account_settings_dialog_load_settings (dialog, settings);
445         
446         /* Close dialog on response */
447         g_signal_connect_swapped (dialog,
448                                   "response",
449                                   G_CALLBACK (gtk_widget_destroy),
450                                   dialog);
451
452         return dialog;
453 }
454
455 ModestPairList*
456 modest_account_protocol_get_easysetupwizard_tabs (ModestAccountProtocol *self)
457 {
458         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->get_easysetupwizard_tabs (self);
459 }
460
461
462 void 
463 modest_account_protocol_save_settings (ModestAccountProtocol *self, 
464                                        ModestAccountSettingsDialog *dialog,
465                                        ModestAccountSettings *settings)
466 {
467         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->save_settings (self, dialog, settings);
468 }
469
470 void 
471 modest_account_protocol_save_wizard_settings (ModestAccountProtocol *self, 
472                                               GList *wizard_pages,
473                                               ModestAccountSettings *settings)
474 {
475         return MODEST_ACCOUNT_PROTOCOL_GET_CLASS (self)->save_wizard_settings (self, wizard_pages, settings);
476 }
477
478 /* Default implementations */
479 static ModestAccountSettingsDialog *
480 modest_account_protocol_create_account_settings_dialog_default (ModestAccountProtocol *self)
481 {
482         return modest_default_account_settings_dialog_new ();
483 }
484
485 static ModestPairList*
486 modest_account_protocol_get_easysetupwizard_tabs_default (ModestAccountProtocol *self)
487 {
488         g_warning ("You must implement get_easysetupwizard_tabs");
489         return NULL;
490 }
491
492 static void 
493 modest_account_protocol_save_settings_default (ModestAccountProtocol *self, 
494                                                ModestAccountSettingsDialog *dialog,
495                                                ModestAccountSettings *settings)
496 {
497         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
498         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS_DIALOG (dialog));
499         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
500
501         g_warning ("You must implement save_settings");
502 }
503
504 static void 
505 modest_account_protocol_save_wizard_settings_default (ModestAccountProtocol *self, 
506                                                       GList *wizard_pages,
507                                                       ModestAccountSettings *settings)
508 {
509         g_return_if_fail (MODEST_IS_ACCOUNT_PROTOCOL (self));
510         g_return_if_fail (wizard_pages);
511         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
512
513         g_warning ("You must implement save_wizard_settings");
514 }