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