* src/modest-account-mgr-helpers.c:
[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                 has_errors || (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME,
500                                                                            username, TRUE));
501                 has_errors || (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PASSWORD,
502                                                                            password, TRUE));
503                 has_errors || (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
504                                                                            protocol, TRUE));
505                 has_errors || (has_errors = !modest_account_mgr_set_int (self, account_name, MODEST_ACCOUNT_PORT,
506                                                                         port, TRUE));
507                 has_errors || (has_errors = !modest_account_mgr_set_string (self, account_name, 
508                                                                            MODEST_ACCOUNT_AUTH_MECH,
509                                                                            auth_protocol, TRUE));               
510                 has_errors || (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY,
511                                                                            security,
512                                                                            TRUE));
513         } else {
514                 const gchar *uri = modest_server_account_settings_get_uri (settings);
515                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_URI,
516                                                             uri, TRUE);
517                 has_errors || (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
518                                                                            protocol, TRUE));
519         }
520
521         return !has_errors;
522
523 }
524
525
526 ModestAccountSettings *
527 modest_account_mgr_load_account_settings (ModestAccountMgr *self, 
528                                           const gchar* name)
529 {
530         ModestAccountSettings *settings;
531         gchar *string;
532         gchar *server_account;
533         gchar *default_account;
534         gboolean use_signature = FALSE;
535         
536         g_return_val_if_fail (self, NULL);
537         g_return_val_if_fail (name, NULL);
538         
539         if (!modest_account_mgr_account_exists (self, name, FALSE)) {
540                 /* For instance, maybe you are mistakenly checking for a server account name? */
541                 g_warning ("%s: Account %s does not exist.", __FUNCTION__, name);
542                 return NULL;
543         }
544         
545         settings = modest_account_settings_new ();
546
547         modest_account_settings_set_account_name (settings, name);
548
549         string = modest_account_mgr_get_string (self, name,
550                                                 MODEST_ACCOUNT_DISPLAY_NAME,
551                                                 FALSE);
552         modest_account_settings_set_display_name (settings, string);
553         g_free (string);
554
555         string = modest_account_mgr_get_string (self, name,
556                                                 MODEST_ACCOUNT_FULLNAME,
557                                                 FALSE);
558         modest_account_settings_set_fullname (settings, string);
559         g_free (string);
560
561         string = modest_account_mgr_get_string (self, name,
562                                                 MODEST_ACCOUNT_EMAIL,
563                                                 FALSE);
564         modest_account_settings_set_email_address (settings, string);
565         g_free (string);
566
567         modest_account_settings_set_enabled (settings, modest_account_mgr_get_enabled (self, name));
568         modest_account_settings_set_retrieve_type (settings, modest_account_mgr_get_retrieve_type (self, name));
569         modest_account_settings_set_retrieve_limit (settings, modest_account_mgr_get_retrieve_limit (self, name));
570
571         default_account    = modest_account_mgr_get_default_account (self);
572         modest_account_settings_set_is_default (settings,
573                                                 (default_account && strcmp (default_account, name) == 0));
574         g_free (default_account);
575
576         string = modest_account_mgr_get_signature (self, name, &use_signature);
577         modest_account_settings_set_use_signature (settings, use_signature);
578         modest_account_settings_set_signature (settings, string);
579         g_free (string);
580
581         modest_account_settings_set_leave_messages_on_server 
582                 (settings, modest_account_mgr_get_leave_on_server (self, name));
583         modest_account_settings_set_use_connection_specific_smtp 
584                 (settings, modest_account_mgr_get_use_connection_specific_smtp (self, name));
585
586         /* store */
587         server_account     = modest_account_mgr_get_string (self, name,
588                                                             MODEST_ACCOUNT_STORE_ACCOUNT,
589                                                             FALSE);
590         if (server_account) {
591                 ModestServerAccountSettings *store_settings;
592                 store_settings = modest_account_mgr_load_server_settings (self, server_account);
593                 modest_account_settings_set_store_settings (settings,
594                                                             store_settings);
595                 g_object_unref (store_settings);
596                 g_free (server_account);
597         }
598
599         /* transport */
600         server_account = modest_account_mgr_get_string (self, name,
601                                                         MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
602                                                         FALSE);
603         if (server_account) {
604                 ModestServerAccountSettings *transport_settings;
605                 transport_settings = modest_account_mgr_load_server_settings (self, server_account);
606                 modest_account_settings_set_transport_settings (settings, transport_settings);
607                 g_object_unref (transport_settings);
608                 g_free (server_account);
609         }
610
611         return settings;
612 }
613
614 void
615 modest_account_mgr_save_account_settings (ModestAccountMgr *mgr,
616                                           ModestAccountSettings *settings)
617 {
618         g_return_if_fail (MODEST_IS_ACCOUNT_MGR (mgr));
619         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
620
621         const gchar *account_name;
622         const gchar *store_account_name;
623         const gchar *transport_account_name;
624         ModestServerAccountSettings *store_settings;
625         ModestServerAccountSettings *transport_settings;
626
627         account_name = modest_account_settings_get_account_name (settings);
628         g_return_if_fail (account_name != NULL);
629
630         modest_account_mgr_set_display_name (mgr, account_name,
631                                              modest_account_settings_get_display_name (settings));
632         modest_account_mgr_set_user_fullname (mgr, account_name,
633                                               modest_account_settings_get_fullname (settings));
634         modest_account_mgr_set_user_email (mgr, account_name,
635                                            modest_account_settings_get_email_address (settings));
636         modest_account_mgr_set_retrieve_type (mgr, account_name,
637                                               modest_account_settings_get_retrieve_type (settings));
638         modest_account_mgr_set_retrieve_limit (mgr, account_name,
639                                                modest_account_settings_get_retrieve_limit (settings));
640         modest_account_mgr_set_leave_on_server (mgr, account_name,
641                                                 modest_account_settings_get_leave_messages_on_server (settings));
642         modest_account_mgr_set_signature (mgr, account_name,
643                                           modest_account_settings_get_signature (settings),
644                                           modest_account_settings_get_use_signature (settings));
645         modest_account_mgr_set_use_connection_specific_smtp 
646                 (mgr, account_name,
647                  modest_account_settings_get_use_connection_specific_smtp (settings));
648
649         store_settings = modest_account_settings_get_store_settings (settings);
650         store_account_name = modest_server_account_settings_get_account_name (store_settings);
651         if (store_settings != NULL) {
652                 modest_account_mgr_save_server_settings (mgr, store_settings);
653         }
654         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_STORE_ACCOUNT, store_account_name, FALSE);
655         g_object_unref (store_settings);
656
657         transport_settings = modest_account_settings_get_transport_settings (settings);
658         transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
659         if (transport_settings != NULL) {
660                 modest_account_mgr_save_server_settings (mgr, transport_settings);
661         }
662         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT, transport_account_name, FALSE);
663         g_object_unref (transport_settings);
664         modest_account_mgr_set_enabled (mgr, account_name, TRUE);
665 }
666
667
668 gint 
669 on_accounts_list_sort_by_title(gconstpointer a, gconstpointer b)
670 {
671         return g_utf8_collate((const gchar*)a, (const gchar*)b);
672 }
673
674 /** Get the first one, alphabetically, by title. */
675 gchar* 
676 modest_account_mgr_get_first_account_name (ModestAccountMgr *self)
677 {
678         const gchar* account_name = NULL;
679         GSList *account_names = modest_account_mgr_account_names (self, TRUE /* only enabled */);
680
681         /* Return TRUE if there is no account */
682         if (!account_names)
683                 return NULL;
684
685         /* Get the first one, alphabetically, by title: */
686         /* gchar *old_default = modest_account_mgr_get_default_account (self); */
687         GSList* list_sorted = g_slist_sort (account_names, on_accounts_list_sort_by_title);
688
689         GSList* iter = list_sorted;
690         gboolean found = FALSE;
691         while (iter && !found) {
692                 account_name = (const gchar*)list_sorted->data;
693
694                 if (account_name)
695                         found = TRUE;
696
697                 if (!found)
698                         iter = g_slist_next (iter);
699         }
700
701         gchar* result = NULL;
702         if (account_name)
703                 result = g_strdup (account_name);
704                 
705         modest_account_mgr_free_account_names (account_names);
706         account_names = NULL;
707
708         return result;
709 }
710
711 gboolean
712 modest_account_mgr_set_first_account_as_default (ModestAccountMgr *self)
713 {
714         gboolean result = FALSE;
715         
716         gchar* account_name = modest_account_mgr_get_first_account_name(self);
717         if (account_name) {
718                 result = modest_account_mgr_set_default_account (self, account_name);
719                 g_free (account_name);
720         }
721         else
722                 result = TRUE; /* If there are no accounts then it's not a failure. */
723
724         return result;
725 }
726
727 gchar*
728 modest_account_mgr_get_from_string (ModestAccountMgr *self, const gchar* name)
729 {
730         gchar *fullname, *email, *from;
731         
732         g_return_val_if_fail (self, NULL);
733         g_return_val_if_fail (name, NULL);
734
735         fullname      = modest_account_mgr_get_string (self, name,MODEST_ACCOUNT_FULLNAME,
736                                                        FALSE);
737         email         = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_EMAIL,
738                                                        FALSE);
739         from = g_strdup_printf ("%s <%s>",
740                                 fullname ? fullname : "",
741                                 email    ? email    : "");
742         g_free (fullname);
743         g_free (email);
744
745         return from;
746 }
747
748 /* Add a number to the end of the text, or increment a number that is already there.
749  */
750 static gchar*
751 util_increment_name (const gchar* text)
752 {
753         /* Get the end character,
754          * also doing a UTF-8 validation which is required for using g_utf8_prev_char().
755          */
756         const gchar* end = NULL;
757         if (!g_utf8_validate (text, -1, &end))
758                 return NULL;
759   
760         if (!end)
761                 return NULL;
762                 
763         --end; /* Go to before the null-termination. */
764                 
765         /* Look at each UTF-8 characer, starting at the end: */
766         const gchar* p = end;
767         const gchar* alpha_end = NULL;
768         while (p)
769         {       
770                 /* Stop when we reach the first character that is not a numeric digit: */
771                 const gunichar ch = g_utf8_get_char (p);
772                 if (!g_unichar_isdigit (ch)) {
773                         alpha_end = p;
774                         break;
775                 }
776                 
777                 p = g_utf8_prev_char (p);       
778         }
779         
780         if(!alpha_end) {
781                 /* The text must consist completely of numeric digits. */
782                 alpha_end = text;
783         }
784         else
785                 ++alpha_end;
786         
787         /* Intepret and increment the number, if any: */
788         gint num = atol (alpha_end);
789         ++num;
790         
791         /* Get the name part: */
792         gint name_len = alpha_end - text;
793         gchar *name_without_number = g_malloc(name_len + 1);
794         memcpy (name_without_number, text, name_len);
795         name_without_number[name_len] = 0;\
796         
797     /* Concatenate the text part and the new number: */ 
798         gchar *result = g_strdup_printf("%s%d", name_without_number, num);
799         g_free (name_without_number);
800         
801         return result;  
802 }
803
804 gchar*
805 modest_account_mgr_get_unused_account_name (ModestAccountMgr *self, const gchar* starting_name,
806         gboolean server_account)
807 {
808         gchar *account_name = g_strdup (starting_name);
809
810         while (modest_account_mgr_account_exists (self, 
811                 account_name, server_account /*  server_account */)) {
812                         
813                 gchar * account_name2 = util_increment_name (account_name);
814                 g_free (account_name);
815                 account_name = account_name2;
816         }
817         
818         return account_name;
819 }
820
821 gchar*
822 modest_account_mgr_get_unused_account_display_name (ModestAccountMgr *self, const gchar* starting_name)
823 {
824         gchar *account_name = g_strdup (starting_name);
825
826         while (modest_account_mgr_account_with_display_name_exists (self, account_name)) {
827                         
828                 gchar * account_name2 = util_increment_name (account_name);
829                 g_free (account_name);
830                 account_name = account_name2;
831         }
832         
833         return account_name;
834 }
835
836 void 
837 modest_account_mgr_set_leave_on_server (ModestAccountMgr *self, 
838                                         const gchar *account_name, 
839                                         gboolean leave_on_server)
840 {
841         modest_account_mgr_set_bool (self, 
842                                      account_name,
843                                      MODEST_ACCOUNT_LEAVE_ON_SERVER, 
844                                      leave_on_server, 
845                                      FALSE);
846 }
847
848 gboolean 
849 modest_account_mgr_get_leave_on_server (ModestAccountMgr *self, 
850                                         const gchar* account_name)
851 {
852         return modest_account_mgr_get_bool (self, 
853                                             account_name,
854                                             MODEST_ACCOUNT_LEAVE_ON_SERVER, 
855                                             FALSE);
856 }
857
858 gint 
859 modest_account_mgr_get_last_updated (ModestAccountMgr *self, 
860                                      const gchar* account_name)
861 {
862         return modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
863                                            account_name, 
864                                            MODEST_ACCOUNT_LAST_UPDATED, 
865                                            TRUE);
866 }
867
868 void 
869 modest_account_mgr_set_last_updated (ModestAccountMgr *self, 
870                                      const gchar* account_name,
871                                      gint time)
872 {
873         modest_account_mgr_set_int (self, 
874                                     account_name, 
875                                     MODEST_ACCOUNT_LAST_UPDATED, 
876                                     time, 
877                                     TRUE);
878
879         /* TODO: notify about changes */
880 }
881
882 gint  
883 modest_account_mgr_get_retrieve_limit (ModestAccountMgr *self, 
884                                        const gchar* account_name)
885 {
886         return modest_account_mgr_get_int (self, 
887                                            account_name,
888                                            MODEST_ACCOUNT_LIMIT_RETRIEVE, 
889                                            FALSE);
890 }
891
892 void  
893 modest_account_mgr_set_retrieve_limit (ModestAccountMgr *self, 
894                                        const gchar* account_name,
895                                        gint limit_retrieve)
896 {
897         modest_account_mgr_set_int (self, 
898                                     account_name,
899                                     MODEST_ACCOUNT_LIMIT_RETRIEVE, 
900                                     limit_retrieve, 
901                                     FALSE /* not server account */);
902 }
903
904 gint  
905 modest_account_mgr_get_server_account_port (ModestAccountMgr *self, 
906                                             const gchar* account_name)
907 {
908         return modest_account_mgr_get_int (self, 
909                                            account_name,
910                                            MODEST_ACCOUNT_PORT, 
911                                            TRUE);
912 }
913
914 void
915 modest_account_mgr_set_server_account_port (ModestAccountMgr *self, 
916                                             const gchar *account_name,
917                                             gint port_num)
918 {
919         modest_account_mgr_set_int (self, 
920                                     account_name,
921                                     MODEST_ACCOUNT_PORT, 
922                                     port_num, TRUE /* server account */);
923 }
924
925 gchar* 
926 modest_account_mgr_get_server_account_name (ModestAccountMgr *self, 
927                                             const gchar *account_name,
928                                             TnyAccountType account_type)
929 {
930         return modest_account_mgr_get_string (self, 
931                                               account_name,
932                                               (account_type == TNY_ACCOUNT_TYPE_STORE) ?
933                                               MODEST_ACCOUNT_STORE_ACCOUNT :
934                                               MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
935                                               FALSE);
936 }
937
938 static const gchar *
939 get_retrieve_type_name (ModestAccountRetrieveType retrieve_type)
940 {
941         switch(retrieve_type) {
942         case MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY:
943                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
944                 break;
945         case MODEST_ACCOUNT_RETRIEVE_MESSAGES:
946                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES;
947                 break;
948         case MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS:
949                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS;
950                 break;
951         default:
952                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
953         };
954 }
955
956 static ModestAccountRetrieveType
957 get_retrieve_type (const gchar *name)
958 {
959         if (!name || name[0] == 0)
960                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
961         if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) == 0) {
962                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES;
963         } else if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS) == 0) {
964                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS;
965         } else {
966                 /* we fall back to headers only */
967                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
968         }
969 }
970
971 ModestAccountRetrieveType
972 modest_account_mgr_get_retrieve_type (ModestAccountMgr *self, 
973                                       const gchar *account_name)
974 {
975         gchar *string;
976         ModestAccountRetrieveType result;
977
978         string =  modest_account_mgr_get_string (self, 
979                                                  account_name,
980                                                  MODEST_ACCOUNT_RETRIEVE, 
981                                                  FALSE /* not server account */);
982         result = get_retrieve_type (string);
983         g_free (string);
984
985         return result;
986 }
987
988 void 
989 modest_account_mgr_set_retrieve_type (ModestAccountMgr *self, 
990                                       const gchar *account_name,
991                                       ModestAccountRetrieveType retrieve_type)
992 {
993         modest_account_mgr_set_string (self, 
994                                        account_name,
995                                        MODEST_ACCOUNT_RETRIEVE, 
996                                        get_retrieve_type_name (retrieve_type), 
997                                        FALSE /* not server account */);
998 }
999
1000
1001 void
1002 modest_account_mgr_set_user_fullname (ModestAccountMgr *self, 
1003                                       const gchar *account_name,
1004                                       const gchar *fullname)
1005 {
1006         modest_account_mgr_set_string (self, 
1007                                        account_name,
1008                                        MODEST_ACCOUNT_FULLNAME, 
1009                                        fullname, 
1010                                        FALSE /* not server account */);
1011 }
1012
1013 void
1014 modest_account_mgr_set_user_email (ModestAccountMgr *self, 
1015                                    const gchar *account_name,
1016                                    const gchar *email)
1017 {
1018         modest_account_mgr_set_string (self, 
1019                                        account_name,
1020                                        MODEST_ACCOUNT_EMAIL, 
1021                                        email, 
1022                                        FALSE /* not server account */);
1023 }