* add some parameter checks
[modest] / src / modest-account-mgr-helpers.c
1 /* Copyright (c) 2006, 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 <modest-account-mgr-helpers.h>
31 #include <modest-account-mgr-priv.h>
32 #include <tny-simple-list.h>
33 #include <modest-runtime.h>
34 #include <string.h>
35
36 static const gchar * null_means_empty (const gchar * str);
37
38 static const gchar *
39 null_means_empty (const gchar * str)
40 {
41         return str ? str : "";
42 }
43
44 gboolean
45 modest_account_mgr_set_enabled (ModestAccountMgr *self, const gchar* name,
46                                         gboolean enabled)
47 {
48         return modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_ENABLED, enabled,FALSE);
49 }
50
51
52 gboolean
53 modest_account_mgr_get_enabled (ModestAccountMgr *self, const gchar* name)
54 {
55         return modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_ENABLED, FALSE);
56 }
57
58 gboolean modest_account_mgr_set_signature (ModestAccountMgr *self, const gchar* name, 
59         const gchar* signature, gboolean use_signature)
60 {
61         gboolean result = modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, 
62                 use_signature, FALSE);
63         result = result && modest_account_mgr_set_string (self, name, MODEST_ACCOUNT_SIGNATURE, 
64                                                           null_means_empty (signature), FALSE);
65         return result;
66 }
67
68 gchar* modest_account_mgr_get_signature (ModestAccountMgr *self, const gchar* name, 
69         gboolean* use_signature)
70 {
71         if (use_signature) {
72                 *use_signature = 
73                         modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, FALSE);
74         }
75         
76         return modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SIGNATURE, FALSE);
77 }
78
79 ModestTransportStoreProtocol modest_account_mgr_get_store_protocol (ModestAccountMgr *self, const gchar* name)
80 {
81        ModestTransportStoreProtocol result = MODEST_PROTOCOL_STORE_POP; /* Arbitrary default */
82        
83        gchar *server_account_name = modest_account_mgr_get_string (self, name,
84                                                                    MODEST_ACCOUNT_STORE_ACCOUNT,
85                                                                    FALSE);
86        if (server_account_name) {
87                ModestServerAccountSettings* server_settings = 
88                        modest_account_mgr_load_server_settings (self, server_account_name);
89                result = modest_server_account_settings_get_protocol (server_settings);
90                
91                g_object_unref (server_settings);
92                
93                g_free (server_account_name);
94        }
95        
96        return result;
97 }
98
99
100 gboolean modest_account_mgr_set_connection_specific_smtp (ModestAccountMgr *self, 
101         const gchar* connection_name, const gchar* server_account_name)
102 {
103         modest_account_mgr_remove_connection_specific_smtp (self, connection_name);
104         
105         ModestConf *conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
106
107         gboolean result = TRUE;
108         GError *err = NULL;
109         GSList *list = modest_conf_get_list (conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
110                                                     MODEST_CONF_VALUE_STRING, &err);
111         if (err) {
112                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
113                 g_error_free (err);
114                 err = NULL;
115                 result = FALSE;
116         } else {        
117                 /* The server account is in the item after the connection name: */
118                 list = g_slist_append (list, (gpointer)connection_name);
119                 list = g_slist_append (list, (gpointer)server_account_name);
120         
121                 /* Reset the changed list: */
122                 modest_conf_set_list (conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST, list,
123                                                     MODEST_CONF_VALUE_STRING, &err);
124                 if (err) {
125                         g_printerr ("modest: %s: error setting list: %s.\n", __FUNCTION__, err->message);
126                         g_error_free (err);
127                         result = FALSE;
128                 }
129         }
130                                 
131         /* TODO: Should we free the items too, or just the list? */
132         g_slist_free (list);
133         
134         return result;
135 }
136
137 /**
138  * modest_account_mgr_remove_connection_specific_smtp
139  * @self: a ModestAccountMgr instance
140  * @name: the account name
141  * @connection_name: A libconic IAP connection name
142  * 
143  * Disassacoiate a server account to use with the specific connection for this account.
144  *
145  * Returns: TRUE if it worked, FALSE otherwise
146  */                              
147 gboolean modest_account_mgr_remove_connection_specific_smtp (ModestAccountMgr *self, 
148         const gchar* connection_name)
149 {
150         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
151         
152         gboolean result = TRUE;
153         GError *err = NULL;
154         GSList *list = modest_conf_get_list (priv->modest_conf, 
155                                                         MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
156                                                     MODEST_CONF_VALUE_STRING, &err);
157         if (err) {
158                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
159                 g_error_free (err);
160                 err = NULL;
161                 result = FALSE;
162         }
163
164         if (!list)
165                 return FALSE;
166                 
167         /* The server account is in the item after the connection name: */
168         GSList *list_connection = g_slist_find_custom (list, connection_name, (GCompareFunc)strcmp);
169         if (list_connection) {
170                 GSList *account_node = g_slist_next (list_connection);
171                 /* remove both items: */
172                 list = g_slist_delete_link(list, list_connection);
173                 list = g_slist_delete_link(list, account_node);
174         }
175         
176         /* Reset the changed list: */
177         modest_conf_set_list (priv->modest_conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST, list,
178                                                     MODEST_CONF_VALUE_STRING, &err);
179         if (err) {
180                 g_printerr ("modest: %s: error setting list: %s.\n", __FUNCTION__, err->message);
181                 g_error_free (err);
182                 result = FALSE;
183         }
184                                 
185         /* TODO: Should we free the items too, or just the list? */
186         g_slist_free (list);
187         
188         return result;
189 }
190
191
192 gboolean modest_account_mgr_get_use_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name)
193 {
194         return modest_account_mgr_get_bool (self, account_name, 
195                 MODEST_ACCOUNT_USE_CONNECTION_SPECIFIC_SMTP, FALSE);
196 }
197
198 gboolean modest_account_mgr_set_use_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name, 
199         gboolean new_value)
200 {
201         return modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USE_CONNECTION_SPECIFIC_SMTP, 
202                 new_value, FALSE);
203 }
204
205 /**
206  * modest_account_mgr_get_connection_specific_smtp
207  * @self: a ModestAccountMgr instance
208  * @connection_name: A libconic IAP connection name
209  * 
210  * Retrieve a server account to use with this specific connection for this account.
211  *
212  * Returns: a server account name to use for this connection, or NULL if none is specified.
213  */                      
214 gchar* modest_account_mgr_get_connection_specific_smtp (ModestAccountMgr *self,  const gchar* connection_name)
215 {
216         gchar *result = NULL;
217         
218         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
219         
220         GError *err = NULL;
221         GSList *list = modest_conf_get_list (priv->modest_conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
222                                                     MODEST_CONF_VALUE_STRING, &err);
223         if (err) {
224                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
225                 g_error_free (err);
226                 err = NULL;
227         }
228
229         if (!list)
230                 return NULL;
231
232         /* The server account is in the item after the connection name: */
233         GSList *iter = list;
234         while (iter) {
235                 const gchar* this_connection_name = (const gchar*)(iter->data);
236                 if (strcmp (this_connection_name, connection_name) == 0) {
237                         iter = g_slist_next (iter);
238                         
239                         if (iter) {
240                                 const gchar* account_name = (const gchar*)(iter->data);
241                                 if (account_name) {
242                                         result = g_strdup (account_name);
243                                         break;
244                                 }
245                         }
246                 }
247                 
248                 /* Skip 2 to go to the next connection in the list: */
249                 iter = g_slist_next (iter);
250                 if (iter)
251                         iter = g_slist_next (iter);
252         }
253                 
254         /*
255         if (!result) {
256                 printf ("  debug: no server found for connection_name=%s.\n", connection_name); 
257         }
258         */
259                                 
260         /* TODO: Should we free the items too, or just the list? */
261         g_slist_free (list);
262         
263         return result;
264 }
265                                          
266 gchar*
267 modest_account_mgr_get_server_account_username (ModestAccountMgr *self, const gchar* account_name)
268 {
269         return modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_USERNAME, 
270                 TRUE /* server account */);
271 }
272
273 void
274 modest_account_mgr_set_server_account_username (ModestAccountMgr *self, const gchar* account_name, 
275         const gchar* username)
276 {
277         /* Note that this won't work properly as long as the gconf cache is broken 
278          * in Maemo Bora: */
279         gchar *existing_username = modest_account_mgr_get_server_account_username(self, 
280                 account_name);
281         
282         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME, 
283                 username, TRUE /* server account */);
284                 
285         /* We don't know anything about new usernames: */
286         if (strcmp (existing_username, username) != 0)
287                 modest_account_mgr_set_server_account_username_has_succeeded (self, account_name,
288                                                                               TRUE);
289                 
290         g_free (existing_username);
291 }
292
293 gboolean
294 modest_account_mgr_get_server_account_username_has_succeeded (ModestAccountMgr *self, const gchar* account_name)
295 {
296         return modest_account_mgr_get_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
297                                             TRUE /* server account */);
298 }
299
300 void
301 modest_account_mgr_set_server_account_username_has_succeeded (ModestAccountMgr *self, 
302                                                   const gchar* account_name, 
303                                                   gboolean succeeded)
304 {
305         modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
306                                      succeeded, TRUE /* server account */);
307 }
308
309 void
310 modest_account_mgr_set_server_account_password (ModestAccountMgr *self, const gchar* account_name, 
311                                     const gchar* password)
312 {
313         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
314                                        password, TRUE /* server account */);
315 }
316
317         
318 gchar*
319 modest_account_mgr_get_server_account_password (ModestAccountMgr *self, const gchar* account_name)
320 {
321         return modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
322                 TRUE /* server account */);     
323 }
324
325 gboolean
326 modest_account_mgr_get_server_account_has_password (ModestAccountMgr *self, const gchar* account_name)
327 {
328         gboolean result = FALSE;
329         gchar *password = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
330                 TRUE /* server account */);
331         if (password && strlen (password)) {
332                 result = TRUE;
333         }
334         
335         g_free (password);
336         return result;
337 }
338                          
339         
340 gchar*
341 modest_account_mgr_get_server_account_hostname (ModestAccountMgr *self, 
342                                                 const gchar* account_name)
343 {
344         return modest_account_mgr_get_string (self, 
345                                               account_name, 
346                                               MODEST_ACCOUNT_HOSTNAME, 
347                                               TRUE /* server account */);
348 }
349  
350 void
351 modest_account_mgr_set_server_account_hostname (ModestAccountMgr *self, 
352                                                 const gchar *server_account_name,
353                                                 const gchar *hostname)
354 {
355         modest_account_mgr_set_string (self, 
356                                        server_account_name,
357                                        MODEST_ACCOUNT_HOSTNAME, 
358                                        hostname, 
359                                        TRUE /* server account */);
360 }
361
362
363
364 ModestAuthProtocol
365 modest_account_mgr_get_server_account_secure_auth (ModestAccountMgr *self, 
366         const gchar* account_name)
367 {
368         ModestAuthProtocol result = MODEST_PROTOCOL_AUTH_NONE;
369         gchar* value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, 
370                 TRUE /* server account */);
371         if (value) {
372                 result = modest_protocol_info_get_auth_protocol (value);
373                         
374                 g_free (value);
375         }
376         
377         return result;
378 }
379
380
381 void
382 modest_account_mgr_set_server_account_secure_auth (ModestAccountMgr *self, 
383         const gchar* account_name, ModestAuthProtocol secure_auth)
384 {
385         /* Get the conf string for the enum value: */
386         const gchar* str_value = NULL;
387
388         str_value = modest_protocol_info_get_auth_protocol_name (secure_auth);
389         
390         /* Set it in the configuration: */
391         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, str_value, TRUE);
392 }
393
394 ModestConnectionProtocol
395 modest_account_mgr_get_server_account_security (ModestAccountMgr *self, 
396         const gchar* account_name)
397 {
398         ModestConnectionProtocol result = MODEST_PROTOCOL_CONNECTION_NORMAL;
399         gchar* value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_SECURITY, 
400                 TRUE /* server account */);
401         if (value) {
402                 result = modest_protocol_info_get_connection_protocol (value);
403                         
404                 g_free (value);
405         }
406         
407         return result;
408 }
409
410 void
411 modest_account_mgr_set_server_account_security (ModestAccountMgr *self, 
412         const gchar* account_name, ModestConnectionProtocol security)
413 {
414         /* Get the conf string for the enum value: */
415         const gchar* str_value = NULL;
416         str_value = modest_protocol_info_get_connection_protocol_name (security);
417         
418         /* Set it in the configuration: */
419         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY, str_value, TRUE);
420 }
421
422 ModestServerAccountSettings*
423 modest_account_mgr_load_server_settings (ModestAccountMgr *self, const gchar* name)
424 {
425         ModestServerAccountSettings *settings;
426         gchar *string;
427         
428         g_return_val_if_fail (modest_account_mgr_account_exists (self, name, TRUE), NULL);
429         settings = modest_server_account_settings_new ();
430
431         modest_server_account_settings_set_account_name (settings, name);
432
433         string = modest_account_mgr_get_string (self, name, 
434                                                 MODEST_ACCOUNT_HOSTNAME,TRUE);
435         modest_server_account_settings_set_hostname (settings, string);
436         g_free (string);
437
438         string = modest_account_mgr_get_string (self, name, 
439                                                 MODEST_ACCOUNT_USERNAME,TRUE);
440         modest_server_account_settings_set_username (settings, string); 
441         g_free (string);
442
443         string = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_PROTO, TRUE);
444         modest_server_account_settings_set_protocol (settings,
445                                                      modest_protocol_info_get_transport_store_protocol (string));
446         g_free (string);
447
448         modest_server_account_settings_set_port (settings,
449                                                  modest_account_mgr_get_int (self, name, MODEST_ACCOUNT_PORT, TRUE));
450
451         string = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_AUTH_MECH, TRUE);
452         modest_server_account_settings_set_auth_protocol (settings,
453                                                           modest_protocol_info_get_auth_protocol(string));
454         g_free (string);
455                 
456         string = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SECURITY, TRUE);
457         modest_server_account_settings_set_security (settings,
458                                                      modest_protocol_info_get_connection_protocol(string));
459         g_free (string);
460
461         string = modest_account_mgr_get_string (self, name, 
462                                                 MODEST_ACCOUNT_PASSWORD, TRUE);
463         modest_server_account_settings_set_password (settings, string);
464         g_free (string);
465         
466         return settings;
467 }
468
469 gboolean 
470 modest_account_mgr_save_server_settings (ModestAccountMgr *self,
471                                          ModestServerAccountSettings *settings)
472 {
473         gboolean has_errors = FALSE;
474         const gchar *account_name;
475         const gchar *protocol;
476         const gchar *uri;
477         
478         g_return_val_if_fail (MODEST_IS_SERVER_ACCOUNT_SETTINGS (settings), FALSE);
479         account_name = modest_server_account_settings_get_account_name (settings);
480
481         /* if we don't have a valid account name we cannot save */
482         g_return_val_if_fail (account_name, FALSE);
483
484         protocol = modest_protocol_info_get_transport_store_protocol_name (
485                 modest_server_account_settings_get_protocol (settings));
486         uri = modest_server_account_settings_get_uri (settings);
487         if (!uri) {
488                 const gchar *hostname = null_means_empty (modest_server_account_settings_get_hostname (settings));
489                 const gchar *username = null_means_empty (modest_server_account_settings_get_username (settings));
490                 const gchar *password = null_means_empty (modest_server_account_settings_get_password (settings));
491                 gint port = modest_server_account_settings_get_port (settings);
492                 const gchar *auth_protocol = modest_protocol_info_get_auth_protocol_name (
493                         modest_server_account_settings_get_auth_protocol (settings));
494                 const gchar *security = modest_protocol_info_get_connection_protocol_name (
495                         modest_server_account_settings_get_security (settings));
496
497                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_HOSTNAME, 
498                                                             hostname, TRUE);
499                 if (!has_errors)
500                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME,
501                                                                            username, TRUE));
502                 if (!has_errors)
503                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PASSWORD,
504                                                                            password, TRUE));
505                 if (!has_errors)
506                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
507                                                                            protocol, TRUE));
508                 if (!has_errors)
509                         (has_errors = !modest_account_mgr_set_int (self, account_name, MODEST_ACCOUNT_PORT,
510                                                                         port, TRUE));
511                 if (!has_errors)
512                         (has_errors = !modest_account_mgr_set_string (self, account_name, 
513                                                                            MODEST_ACCOUNT_AUTH_MECH,
514                                                                            auth_protocol, TRUE));               
515                 if (!has_errors)
516                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY,
517                                                                            security,
518                                                                            TRUE));
519         } else {
520                 const gchar *uri = modest_server_account_settings_get_uri (settings);
521                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_URI,
522                                                             uri, TRUE);
523                 if (!has_errors)
524                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
525                                                                            protocol, TRUE));
526         }
527
528         return !has_errors;
529
530 }
531
532
533 ModestAccountSettings *
534 modest_account_mgr_load_account_settings (ModestAccountMgr *self, 
535                                           const gchar* name)
536 {
537         ModestAccountSettings *settings;
538         gchar *string;
539         gchar *server_account;
540         gchar *default_account;
541         gboolean use_signature = FALSE;
542         
543         g_return_val_if_fail (self, NULL);
544         g_return_val_if_fail (name, NULL);
545         
546         if (!modest_account_mgr_account_exists (self, name, FALSE)) {
547                 /* For instance, maybe you are mistakenly checking for a server account name? */
548                 g_warning ("%s: Account %s does not exist.", __FUNCTION__, name);
549                 return NULL;
550         }
551         
552         settings = modest_account_settings_new ();
553
554         modest_account_settings_set_account_name (settings, name);
555
556         string = modest_account_mgr_get_string (self, name,
557                                                 MODEST_ACCOUNT_DISPLAY_NAME,
558                                                 FALSE);
559         modest_account_settings_set_display_name (settings, string);
560         g_free (string);
561
562         string = modest_account_mgr_get_string (self, name,
563                                                 MODEST_ACCOUNT_FULLNAME,
564                                                 FALSE);
565         modest_account_settings_set_fullname (settings, string);
566         g_free (string);
567
568         string = modest_account_mgr_get_string (self, name,
569                                                 MODEST_ACCOUNT_EMAIL,
570                                                 FALSE);
571         modest_account_settings_set_email_address (settings, string);
572         g_free (string);
573
574         modest_account_settings_set_enabled (settings, modest_account_mgr_get_enabled (self, name));
575         modest_account_settings_set_retrieve_type (settings, modest_account_mgr_get_retrieve_type (self, name));
576         modest_account_settings_set_retrieve_limit (settings, modest_account_mgr_get_retrieve_limit (self, name));
577
578         default_account    = modest_account_mgr_get_default_account (self);
579         modest_account_settings_set_is_default (settings,
580                                                 (default_account && strcmp (default_account, name) == 0));
581         g_free (default_account);
582
583         string = modest_account_mgr_get_signature (self, name, &use_signature);
584         modest_account_settings_set_use_signature (settings, use_signature);
585         modest_account_settings_set_signature (settings, string);
586         g_free (string);
587
588         modest_account_settings_set_leave_messages_on_server 
589                 (settings, modest_account_mgr_get_leave_on_server (self, name));
590         modest_account_settings_set_use_connection_specific_smtp 
591                 (settings, modest_account_mgr_get_use_connection_specific_smtp (self, name));
592
593         /* store */
594         server_account     = modest_account_mgr_get_string (self, name,
595                                                             MODEST_ACCOUNT_STORE_ACCOUNT,
596                                                             FALSE);
597         if (server_account) {
598                 ModestServerAccountSettings *store_settings;
599                 store_settings = modest_account_mgr_load_server_settings (self, server_account);
600                 modest_account_settings_set_store_settings (settings,
601                                                             store_settings);
602                 g_object_unref (store_settings);
603                 g_free (server_account);
604         }
605
606         /* transport */
607         server_account = modest_account_mgr_get_string (self, name,
608                                                         MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
609                                                         FALSE);
610         if (server_account) {
611                 ModestServerAccountSettings *transport_settings;
612                 transport_settings = modest_account_mgr_load_server_settings (self, server_account);
613                 modest_account_settings_set_transport_settings (settings, transport_settings);
614                 g_object_unref (transport_settings);
615                 g_free (server_account);
616         }
617
618         return settings;
619 }
620
621 void
622 modest_account_mgr_save_account_settings (ModestAccountMgr *mgr,
623                                           ModestAccountSettings *settings)
624 {
625         g_return_if_fail (MODEST_IS_ACCOUNT_MGR (mgr));
626         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
627
628         const gchar *account_name;
629         const gchar *store_account_name;
630         const gchar *transport_account_name;
631         ModestServerAccountSettings *store_settings;
632         ModestServerAccountSettings *transport_settings;
633
634         account_name = modest_account_settings_get_account_name (settings);
635         g_return_if_fail (account_name != NULL);
636
637         modest_account_mgr_set_display_name (mgr, account_name,
638                                              modest_account_settings_get_display_name (settings));
639         modest_account_mgr_set_user_fullname (mgr, account_name,
640                                               modest_account_settings_get_fullname (settings));
641         modest_account_mgr_set_user_email (mgr, account_name,
642                                            modest_account_settings_get_email_address (settings));
643         modest_account_mgr_set_retrieve_type (mgr, account_name,
644                                               modest_account_settings_get_retrieve_type (settings));
645         modest_account_mgr_set_retrieve_limit (mgr, account_name,
646                                                modest_account_settings_get_retrieve_limit (settings));
647         modest_account_mgr_set_leave_on_server (mgr, account_name,
648                                                 modest_account_settings_get_leave_messages_on_server (settings));
649         modest_account_mgr_set_signature (mgr, account_name,
650                                           modest_account_settings_get_signature (settings),
651                                           modest_account_settings_get_use_signature (settings));
652         modest_account_mgr_set_use_connection_specific_smtp 
653                 (mgr, account_name,
654                  modest_account_settings_get_use_connection_specific_smtp (settings));
655
656         store_settings = modest_account_settings_get_store_settings (settings);
657         store_account_name = modest_server_account_settings_get_account_name (store_settings);
658         if (store_settings != NULL) {
659                 modest_account_mgr_save_server_settings (mgr, store_settings);
660         }
661         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_STORE_ACCOUNT, store_account_name, FALSE);
662         g_object_unref (store_settings);
663
664         transport_settings = modest_account_settings_get_transport_settings (settings);
665         transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
666         if (transport_settings != NULL) {
667                 modest_account_mgr_save_server_settings (mgr, transport_settings);
668         }
669         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT, transport_account_name, FALSE);
670         g_object_unref (transport_settings);
671         modest_account_mgr_set_enabled (mgr, account_name, TRUE);
672 }
673
674
675 gint 
676 on_accounts_list_sort_by_title(gconstpointer a, gconstpointer b)
677 {
678         return g_utf8_collate((const gchar*)a, (const gchar*)b);
679 }
680
681 /** Get the first one, alphabetically, by title. */
682 gchar* 
683 modest_account_mgr_get_first_account_name (ModestAccountMgr *self)
684 {
685         const gchar* account_name = NULL;
686         GSList *account_names = modest_account_mgr_account_names (self, TRUE /* only enabled */);
687
688         /* Return TRUE if there is no account */
689         if (!account_names)
690                 return NULL;
691
692         /* Get the first one, alphabetically, by title: */
693         /* gchar *old_default = modest_account_mgr_get_default_account (self); */
694         GSList* list_sorted = g_slist_sort (account_names, on_accounts_list_sort_by_title);
695
696         GSList* iter = list_sorted;
697         gboolean found = FALSE;
698         while (iter && !found) {
699                 account_name = (const gchar*)list_sorted->data;
700
701                 if (account_name)
702                         found = TRUE;
703
704                 if (!found)
705                         iter = g_slist_next (iter);
706         }
707
708         gchar* result = NULL;
709         if (account_name)
710                 result = g_strdup (account_name);
711                 
712         modest_account_mgr_free_account_names (account_names);
713         account_names = NULL;
714
715         return result;
716 }
717
718 gboolean
719 modest_account_mgr_set_first_account_as_default (ModestAccountMgr *self)
720 {
721         gboolean result = FALSE;
722         
723         gchar* account_name = modest_account_mgr_get_first_account_name(self);
724         if (account_name) {
725                 result = modest_account_mgr_set_default_account (self, account_name);
726                 g_free (account_name);
727         }
728         else
729                 result = TRUE; /* If there are no accounts then it's not a failure. */
730
731         return result;
732 }
733
734 gchar*
735 modest_account_mgr_get_from_string (ModestAccountMgr *self, const gchar* name)
736 {
737         gchar *fullname, *email, *from;
738         
739         g_return_val_if_fail (self, NULL);
740         g_return_val_if_fail (name, NULL);
741
742         fullname      = modest_account_mgr_get_string (self, name,MODEST_ACCOUNT_FULLNAME,
743                                                        FALSE);
744         email         = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_EMAIL,
745                                                        FALSE);
746         from = g_strdup_printf ("%s <%s>",
747                                 fullname ? fullname : "",
748                                 email    ? email    : "");
749         g_free (fullname);
750         g_free (email);
751
752         return from;
753 }
754
755 /* Add a number to the end of the text, or increment a number that is already there.
756  */
757 static gchar*
758 util_increment_name (const gchar* text)
759 {
760         /* Get the end character,
761          * also doing a UTF-8 validation which is required for using g_utf8_prev_char().
762          */
763         const gchar* end = NULL;
764         if (!g_utf8_validate (text, -1, &end))
765                 return NULL;
766   
767         if (!end)
768                 return NULL;
769                 
770         --end; /* Go to before the null-termination. */
771                 
772         /* Look at each UTF-8 characer, starting at the end: */
773         const gchar* p = end;
774         const gchar* alpha_end = NULL;
775         while (p)
776         {       
777                 /* Stop when we reach the first character that is not a numeric digit: */
778                 const gunichar ch = g_utf8_get_char (p);
779                 if (!g_unichar_isdigit (ch)) {
780                         alpha_end = p;
781                         break;
782                 }
783                 
784                 p = g_utf8_prev_char (p);       
785         }
786         
787         if(!alpha_end) {
788                 /* The text must consist completely of numeric digits. */
789                 alpha_end = text;
790         }
791         else
792                 ++alpha_end;
793         
794         /* Intepret and increment the number, if any: */
795         gint num = atol (alpha_end);
796         ++num;
797         
798         /* Get the name part: */
799         gint name_len = alpha_end - text;
800         gchar *name_without_number = g_malloc(name_len + 1);
801         memcpy (name_without_number, text, name_len);
802         name_without_number[name_len] = 0;\
803         
804     /* Concatenate the text part and the new number: */ 
805         gchar *result = g_strdup_printf("%s%d", name_without_number, num);
806         g_free (name_without_number);
807         
808         return result;  
809 }
810
811 gchar*
812 modest_account_mgr_get_unused_account_name (ModestAccountMgr *self, const gchar* starting_name,
813         gboolean server_account)
814 {
815         gchar *account_name = g_strdup (starting_name);
816
817         while (modest_account_mgr_account_exists (self, 
818                 account_name, server_account /*  server_account */)) {
819                         
820                 gchar * account_name2 = util_increment_name (account_name);
821                 g_free (account_name);
822                 account_name = account_name2;
823         }
824         
825         return account_name;
826 }
827
828 gchar*
829 modest_account_mgr_get_unused_account_display_name (ModestAccountMgr *self, const gchar* starting_name)
830 {
831         gchar *account_name = g_strdup (starting_name);
832
833         while (modest_account_mgr_account_with_display_name_exists (self, account_name)) {
834                         
835                 gchar * account_name2 = util_increment_name (account_name);
836                 g_free (account_name);
837                 account_name = account_name2;
838         }
839         
840         return account_name;
841 }
842
843 void 
844 modest_account_mgr_set_leave_on_server (ModestAccountMgr *self, 
845                                         const gchar *account_name, 
846                                         gboolean leave_on_server)
847 {
848         modest_account_mgr_set_bool (self, 
849                                      account_name,
850                                      MODEST_ACCOUNT_LEAVE_ON_SERVER, 
851                                      leave_on_server, 
852                                      FALSE);
853 }
854
855 gboolean 
856 modest_account_mgr_get_leave_on_server (ModestAccountMgr *self, 
857                                         const gchar* account_name)
858 {
859         return modest_account_mgr_get_bool (self, 
860                                             account_name,
861                                             MODEST_ACCOUNT_LEAVE_ON_SERVER, 
862                                             FALSE);
863 }
864
865 gint 
866 modest_account_mgr_get_last_updated (ModestAccountMgr *self, 
867                                      const gchar* account_name)
868 {
869         return modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
870                                            account_name, 
871                                            MODEST_ACCOUNT_LAST_UPDATED, 
872                                            TRUE);
873 }
874
875 void 
876 modest_account_mgr_set_last_updated (ModestAccountMgr *self, 
877                                      const gchar* account_name,
878                                      gint time)
879 {
880         modest_account_mgr_set_int (self, 
881                                     account_name, 
882                                     MODEST_ACCOUNT_LAST_UPDATED, 
883                                     time, 
884                                     TRUE);
885
886         /* TODO: notify about changes */
887 }
888
889 gint  
890 modest_account_mgr_get_retrieve_limit (ModestAccountMgr *self, 
891                                        const gchar* account_name)
892 {
893         return modest_account_mgr_get_int (self, 
894                                            account_name,
895                                            MODEST_ACCOUNT_LIMIT_RETRIEVE, 
896                                            FALSE);
897 }
898
899 void  
900 modest_account_mgr_set_retrieve_limit (ModestAccountMgr *self, 
901                                        const gchar* account_name,
902                                        gint limit_retrieve)
903 {
904         modest_account_mgr_set_int (self, 
905                                     account_name,
906                                     MODEST_ACCOUNT_LIMIT_RETRIEVE, 
907                                     limit_retrieve, 
908                                     FALSE /* not server account */);
909 }
910
911 gint  
912 modest_account_mgr_get_server_account_port (ModestAccountMgr *self, 
913                                             const gchar* account_name)
914 {
915         return modest_account_mgr_get_int (self, 
916                                            account_name,
917                                            MODEST_ACCOUNT_PORT, 
918                                            TRUE);
919 }
920
921 void
922 modest_account_mgr_set_server_account_port (ModestAccountMgr *self, 
923                                             const gchar *account_name,
924                                             gint port_num)
925 {
926         modest_account_mgr_set_int (self, 
927                                     account_name,
928                                     MODEST_ACCOUNT_PORT, 
929                                     port_num, TRUE /* server account */);
930 }
931
932 gchar* 
933 modest_account_mgr_get_server_account_name (ModestAccountMgr *self, 
934                                             const gchar *account_name,
935                                             TnyAccountType account_type)
936 {
937         return modest_account_mgr_get_string (self, 
938                                               account_name,
939                                               (account_type == TNY_ACCOUNT_TYPE_STORE) ?
940                                               MODEST_ACCOUNT_STORE_ACCOUNT :
941                                               MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
942                                               FALSE);
943 }
944
945 static const gchar *
946 get_retrieve_type_name (ModestAccountRetrieveType retrieve_type)
947 {
948         switch(retrieve_type) {
949         case MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY:
950                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
951                 break;
952         case MODEST_ACCOUNT_RETRIEVE_MESSAGES:
953                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES;
954                 break;
955         case MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS:
956                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS;
957                 break;
958         default:
959                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
960         };
961 }
962
963 static ModestAccountRetrieveType
964 get_retrieve_type (const gchar *name)
965 {
966         if (!name || name[0] == 0)
967                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
968         if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) == 0) {
969                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES;
970         } else if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS) == 0) {
971                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS;
972         } else {
973                 /* we fall back to headers only */
974                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
975         }
976 }
977
978 ModestAccountRetrieveType
979 modest_account_mgr_get_retrieve_type (ModestAccountMgr *self, 
980                                       const gchar *account_name)
981 {
982         gchar *string;
983         ModestAccountRetrieveType result;
984
985         string =  modest_account_mgr_get_string (self, 
986                                                  account_name,
987                                                  MODEST_ACCOUNT_RETRIEVE, 
988                                                  FALSE /* not server account */);
989         result = get_retrieve_type (string);
990         g_free (string);
991
992         return result;
993 }
994
995 void 
996 modest_account_mgr_set_retrieve_type (ModestAccountMgr *self, 
997                                       const gchar *account_name,
998                                       ModestAccountRetrieveType retrieve_type)
999 {
1000         modest_account_mgr_set_string (self, 
1001                                        account_name,
1002                                        MODEST_ACCOUNT_RETRIEVE, 
1003                                        get_retrieve_type_name (retrieve_type), 
1004                                        FALSE /* not server account */);
1005 }
1006
1007
1008 void
1009 modest_account_mgr_set_user_fullname (ModestAccountMgr *self, 
1010                                       const gchar *account_name,
1011                                       const gchar *fullname)
1012 {
1013         modest_account_mgr_set_string (self, 
1014                                        account_name,
1015                                        MODEST_ACCOUNT_FULLNAME, 
1016                                        fullname, 
1017                                        FALSE /* not server account */);
1018 }
1019
1020 void
1021 modest_account_mgr_set_user_email (ModestAccountMgr *self, 
1022                                    const gchar *account_name,
1023                                    const gchar *email)
1024 {
1025         modest_account_mgr_set_string (self, 
1026                                        account_name,
1027                                        MODEST_ACCOUNT_EMAIL, 
1028                                        email, 
1029                                        FALSE /* not server account */);
1030 }