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