* Fixes NB#85060, show the password dialog whenever the password is not defined...
[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* 
69 modest_account_mgr_get_signature (ModestAccountMgr *self, 
70                                   const gchar* name, 
71                                   gboolean* use_signature)
72 {
73         *use_signature = 
74                 modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, FALSE);
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_id, const gchar* server_account_name)
102 {
103         modest_account_mgr_remove_connection_specific_smtp (self, connection_id);
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_id);
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_id: A libconic IAP connection id
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_id)
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_id, (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_id: A libconic IAP connection id
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_id)
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_id = (const gchar*)(iter->data);
236                 if (strcmp (this_connection_id, connection_id) == 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_id=%s.\n", connection_id);     
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, FALSE);
288                 
289         g_free (existing_username);
290 }
291
292 gboolean
293 modest_account_mgr_get_server_account_username_has_succeeded (ModestAccountMgr *self, const gchar* account_name)
294 {
295         return modest_account_mgr_get_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
296                                             TRUE /* server account */);
297 }
298
299 void
300 modest_account_mgr_set_server_account_username_has_succeeded (ModestAccountMgr *self, 
301                                                   const gchar* account_name, 
302                                                   gboolean succeeded)
303 {
304         modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
305                                      succeeded, TRUE /* server account */);
306 }
307
308 gchar*
309 modest_account_mgr_get_server_account_password (ModestAccountMgr *self, const gchar* account_name)
310 {
311         return modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
312                 TRUE /* server account */);     
313 }
314
315 gboolean
316 modest_account_mgr_get_server_account_has_password (ModestAccountMgr *self, const gchar* account_name)
317 {
318         gboolean result = FALSE;
319         gchar *password = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_PASSWORD, 
320                 TRUE /* server account */);
321         if (password && strlen (password)) {
322                 result = TRUE;
323         }
324         
325         g_free (password);
326         return result;
327 }
328                          
329         
330 gchar*
331 modest_account_mgr_get_server_account_hostname (ModestAccountMgr *self, 
332                                                 const gchar* account_name)
333 {
334         return modest_account_mgr_get_string (self, 
335                                               account_name, 
336                                               MODEST_ACCOUNT_HOSTNAME, 
337                                               TRUE /* server account */);
338 }
339  
340 void
341 modest_account_mgr_set_server_account_hostname (ModestAccountMgr *self, 
342                                                 const gchar *server_account_name,
343                                                 const gchar *hostname)
344 {
345         modest_account_mgr_set_string (self, 
346                                        server_account_name,
347                                        MODEST_ACCOUNT_HOSTNAME, 
348                                        hostname, 
349                                        TRUE /* server account */);
350 }
351
352
353
354 ModestAuthProtocol
355 modest_account_mgr_get_server_account_secure_auth (ModestAccountMgr *self, 
356         const gchar* account_name)
357 {
358         ModestAuthProtocol result = MODEST_PROTOCOL_AUTH_NONE;
359         gchar* value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, 
360                 TRUE /* server account */);
361         if (value) {
362                 result = modest_protocol_info_get_auth_protocol (value);
363                         
364                 g_free (value);
365         }
366         
367         return result;
368 }
369
370
371 void
372 modest_account_mgr_set_server_account_secure_auth (ModestAccountMgr *self, 
373         const gchar* account_name, ModestAuthProtocol secure_auth)
374 {
375         /* Get the conf string for the enum value: */
376         const gchar* str_value = NULL;
377
378         str_value = modest_protocol_info_get_auth_protocol_name (secure_auth);
379         
380         /* Set it in the configuration: */
381         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, str_value, TRUE);
382 }
383
384 ModestConnectionProtocol
385 modest_account_mgr_get_server_account_security (ModestAccountMgr *self, 
386         const gchar* account_name)
387 {
388         ModestConnectionProtocol result = MODEST_PROTOCOL_CONNECTION_NORMAL;
389         gchar* value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_SECURITY, 
390                 TRUE /* server account */);
391         if (value) {
392                 result = modest_protocol_info_get_connection_protocol (value);
393                         
394                 g_free (value);
395         }
396         
397         return result;
398 }
399
400 void
401 modest_account_mgr_set_server_account_security (ModestAccountMgr *self, 
402         const gchar* account_name, ModestConnectionProtocol security)
403 {
404         /* Get the conf string for the enum value: */
405         const gchar* str_value = NULL;
406         str_value = modest_protocol_info_get_connection_protocol_name (security);
407         
408         /* Set it in the configuration: */
409         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY, str_value, TRUE);
410 }
411
412 ModestServerAccountSettings*
413 modest_account_mgr_load_server_settings (ModestAccountMgr *self, const gchar* name)
414 {
415         ModestServerAccountSettings *settings;
416         gchar *string;
417         
418         g_return_val_if_fail (modest_account_mgr_account_exists (self, name, TRUE), NULL);
419         settings = modest_server_account_settings_new ();
420
421         modest_server_account_settings_set_account_name (settings, name);
422
423         string = modest_account_mgr_get_string (self, name, 
424                                                 MODEST_ACCOUNT_HOSTNAME,TRUE);
425         modest_server_account_settings_set_hostname (settings, string);
426         g_free (string);
427
428         string = modest_account_mgr_get_string (self, name, 
429                                                 MODEST_ACCOUNT_USERNAME,TRUE);
430         modest_server_account_settings_set_username (settings, string); 
431         g_free (string);
432
433         string = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_PROTO, TRUE);
434         modest_server_account_settings_set_protocol (settings,
435                                                      modest_protocol_info_get_transport_store_protocol (string));
436         g_free (string);
437
438         modest_server_account_settings_set_port (settings,
439                                                  modest_account_mgr_get_int (self, name, MODEST_ACCOUNT_PORT, TRUE));
440
441         string = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_AUTH_MECH, TRUE);
442         modest_server_account_settings_set_auth_protocol (settings,
443                                                           modest_protocol_info_get_auth_protocol(string));
444         g_free (string);
445                 
446         string = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SECURITY, TRUE);
447         modest_server_account_settings_set_security (settings,
448                                                      modest_protocol_info_get_connection_protocol(string));
449         g_free (string);
450
451         string = modest_account_mgr_get_string (self, name, 
452                                                 MODEST_ACCOUNT_PASSWORD, TRUE);
453         modest_server_account_settings_set_password (settings, string);
454         g_free (string);
455         
456         return settings;
457 }
458
459 gboolean 
460 modest_account_mgr_save_server_settings (ModestAccountMgr *self,
461                                          ModestServerAccountSettings *settings)
462 {
463         gboolean has_errors = FALSE;
464         const gchar *account_name;
465         const gchar *protocol;
466         const gchar *uri;
467         
468         g_return_val_if_fail (MODEST_IS_SERVER_ACCOUNT_SETTINGS (settings), FALSE);
469         account_name = modest_server_account_settings_get_account_name (settings);
470
471         /* if we don't have a valid account name we cannot save */
472         g_return_val_if_fail (account_name, FALSE);
473
474         protocol = modest_protocol_info_get_transport_store_protocol_name (
475                 modest_server_account_settings_get_protocol (settings));
476         uri = modest_server_account_settings_get_uri (settings);
477         if (!uri) {
478                 const gchar *hostname = null_means_empty (modest_server_account_settings_get_hostname (settings));
479                 const gchar *username = null_means_empty (modest_server_account_settings_get_username (settings));
480                 const gchar *password = null_means_empty (modest_server_account_settings_get_password (settings));
481                 gint port = modest_server_account_settings_get_port (settings);
482                 const gchar *auth_protocol = modest_protocol_info_get_auth_protocol_name (
483                         modest_server_account_settings_get_auth_protocol (settings));
484                 const gchar *security = modest_protocol_info_get_connection_protocol_name (
485                         modest_server_account_settings_get_security (settings));
486
487                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_HOSTNAME, 
488                                                             hostname, TRUE);
489                 if (!has_errors)
490                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME,
491                                                                            username, TRUE));
492                 if (!has_errors)
493                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PASSWORD,
494                                                                            password, TRUE));
495                 if (!has_errors)
496                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
497                                                                            protocol, TRUE));
498                 if (!has_errors)
499                         (has_errors = !modest_account_mgr_set_int (self, account_name, MODEST_ACCOUNT_PORT,
500                                                                         port, TRUE));
501                 if (!has_errors)
502                         (has_errors = !modest_account_mgr_set_string (self, account_name, 
503                                                                            MODEST_ACCOUNT_AUTH_MECH,
504                                                                            auth_protocol, TRUE));               
505                 if (!has_errors)
506                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY,
507                                                                            security,
508                                                                            TRUE));
509         } else {
510                 const gchar *uri = modest_server_account_settings_get_uri (settings);
511                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_URI,
512                                                             uri, TRUE);
513                 if (!has_errors)
514                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
515                                                                            protocol, TRUE));
516         }
517
518         return !has_errors;
519
520 }
521
522
523 ModestAccountSettings *
524 modest_account_mgr_load_account_settings (ModestAccountMgr *self, 
525                                           const gchar* name)
526 {
527         ModestAccountSettings *settings;
528         gchar *string;
529         gchar *server_account;
530         gchar *default_account;
531         gboolean use_signature = FALSE;
532         
533         g_return_val_if_fail (self, NULL);
534         g_return_val_if_fail (name, NULL);
535         
536         if (!modest_account_mgr_account_exists (self, name, FALSE)) {
537                 /* For instance, maybe you are mistakenly checking for a server account name? */
538                 g_warning ("%s: Account %s does not exist.", __FUNCTION__, name);
539                 return NULL;
540         }
541         
542         settings = modest_account_settings_new ();
543
544         modest_account_settings_set_account_name (settings, name);
545
546         string = modest_account_mgr_get_string (self, name,
547                                                 MODEST_ACCOUNT_DISPLAY_NAME,
548                                                 FALSE);
549         modest_account_settings_set_display_name (settings, string);
550         g_free (string);
551
552         string = modest_account_mgr_get_string (self, name,
553                                                 MODEST_ACCOUNT_FULLNAME,
554                                                 FALSE);
555         modest_account_settings_set_fullname (settings, string);
556         g_free (string);
557
558         string = modest_account_mgr_get_string (self, name,
559                                                 MODEST_ACCOUNT_EMAIL,
560                                                 FALSE);
561         modest_account_settings_set_email_address (settings, string);
562         g_free (string);
563
564         modest_account_settings_set_enabled (settings, modest_account_mgr_get_enabled (self, name));
565         modest_account_settings_set_retrieve_type (settings, modest_account_mgr_get_retrieve_type (self, name));
566         modest_account_settings_set_retrieve_limit (settings, modest_account_mgr_get_retrieve_limit (self, name));
567
568         default_account    = modest_account_mgr_get_default_account (self);
569         modest_account_settings_set_is_default (settings,
570                                                 (default_account && strcmp (default_account, name) == 0));
571         g_free (default_account);
572
573         string = modest_account_mgr_get_signature (self, name, &use_signature);
574         modest_account_settings_set_use_signature (settings, use_signature);
575         modest_account_settings_set_signature (settings, string);
576         g_free (string);
577
578         modest_account_settings_set_leave_messages_on_server 
579                 (settings, modest_account_mgr_get_leave_on_server (self, name));
580         modest_account_settings_set_use_connection_specific_smtp 
581                 (settings, modest_account_mgr_get_use_connection_specific_smtp (self, name));
582
583         /* store */
584         server_account     = modest_account_mgr_get_string (self, name,
585                                                             MODEST_ACCOUNT_STORE_ACCOUNT,
586                                                             FALSE);
587         if (server_account) {
588                 ModestServerAccountSettings *store_settings;
589                 store_settings = modest_account_mgr_load_server_settings (self, server_account);
590                 modest_account_settings_set_store_settings (settings,
591                                                             store_settings);
592                 g_object_unref (store_settings);
593                 g_free (server_account);
594         }
595
596         /* transport */
597         server_account = modest_account_mgr_get_string (self, name,
598                                                         MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
599                                                         FALSE);
600         if (server_account) {
601                 ModestServerAccountSettings *transport_settings;
602                 transport_settings = modest_account_mgr_load_server_settings (self, server_account);
603                 modest_account_settings_set_transport_settings (settings, transport_settings);
604                 g_object_unref (transport_settings);
605                 g_free (server_account);
606         }
607
608         return settings;
609 }
610
611 void
612 modest_account_mgr_save_account_settings (ModestAccountMgr *mgr,
613                                           ModestAccountSettings *settings)
614 {
615         g_return_if_fail (MODEST_IS_ACCOUNT_MGR (mgr));
616         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
617
618         const gchar *account_name;
619         const gchar *store_account_name;
620         const gchar *transport_account_name;
621         ModestServerAccountSettings *store_settings;
622         ModestServerAccountSettings *transport_settings;
623
624         account_name = modest_account_settings_get_account_name (settings);
625         g_return_if_fail (account_name != NULL);
626
627         modest_account_mgr_set_display_name (mgr, account_name,
628                                              modest_account_settings_get_display_name (settings));
629         modest_account_mgr_set_user_fullname (mgr, account_name,
630                                               modest_account_settings_get_fullname (settings));
631         modest_account_mgr_set_user_email (mgr, account_name,
632                                            modest_account_settings_get_email_address (settings));
633         modest_account_mgr_set_retrieve_type (mgr, account_name,
634                                               modest_account_settings_get_retrieve_type (settings));
635         modest_account_mgr_set_retrieve_limit (mgr, account_name,
636                                                modest_account_settings_get_retrieve_limit (settings));
637         modest_account_mgr_set_leave_on_server (mgr, account_name,
638                                                 modest_account_settings_get_leave_messages_on_server (settings));
639         modest_account_mgr_set_signature (mgr, account_name,
640                                           modest_account_settings_get_signature (settings),
641                                           modest_account_settings_get_use_signature (settings));
642         modest_account_mgr_set_use_connection_specific_smtp 
643                 (mgr, account_name,
644                  modest_account_settings_get_use_connection_specific_smtp (settings));
645
646         store_settings = modest_account_settings_get_store_settings (settings);
647         store_account_name = modest_server_account_settings_get_account_name (store_settings);
648         if (store_settings != NULL) {
649                 modest_account_mgr_save_server_settings (mgr, store_settings);
650         }
651         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_STORE_ACCOUNT, store_account_name, FALSE);
652         g_object_unref (store_settings);
653
654         transport_settings = modest_account_settings_get_transport_settings (settings);
655         transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
656         if (transport_settings != NULL) {
657                 modest_account_mgr_save_server_settings (mgr, transport_settings);
658         }
659         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT, transport_account_name, FALSE);
660         g_object_unref (transport_settings);
661         modest_account_mgr_set_enabled (mgr, account_name, TRUE);
662 }
663
664
665 gint 
666 on_accounts_list_sort_by_title(gconstpointer a, gconstpointer b)
667 {
668         return g_utf8_collate((const gchar*)a, (const gchar*)b);
669 }
670
671 /** Get the first one, alphabetically, by title. */
672 gchar* 
673 modest_account_mgr_get_first_account_name (ModestAccountMgr *self)
674 {
675         const gchar* account_name = NULL;
676         GSList *account_names = modest_account_mgr_account_names (self, TRUE /* only enabled */);
677
678         /* Return TRUE if there is no account */
679         if (!account_names)
680                 return NULL;
681
682         /* Get the first one, alphabetically, by title: */
683         /* gchar *old_default = modest_account_mgr_get_default_account (self); */
684         GSList* list_sorted = g_slist_sort (account_names, on_accounts_list_sort_by_title);
685
686         GSList* iter = list_sorted;
687         gboolean found = FALSE;
688         while (iter && !found) {
689                 account_name = (const gchar*)list_sorted->data;
690
691                 if (account_name)
692                         found = TRUE;
693
694                 if (!found)
695                         iter = g_slist_next (iter);
696         }
697
698         gchar* result = NULL;
699         if (account_name)
700                 result = g_strdup (account_name);
701                 
702         modest_account_mgr_free_account_names (account_names);
703         account_names = NULL;
704
705         return result;
706 }
707
708 gboolean
709 modest_account_mgr_set_first_account_as_default (ModestAccountMgr *self)
710 {
711         gboolean result = FALSE;
712         
713         gchar* account_name = modest_account_mgr_get_first_account_name(self);
714         if (account_name) {
715                 result = modest_account_mgr_set_default_account (self, account_name);
716                 g_free (account_name);
717         }
718         else
719                 result = TRUE; /* If there are no accounts then it's not a failure. */
720
721         return result;
722 }
723
724 gchar*
725 modest_account_mgr_get_from_string (ModestAccountMgr *self, const gchar* name)
726 {
727         gchar *fullname, *email, *from;
728         
729         g_return_val_if_fail (self, NULL);
730         g_return_val_if_fail (name, NULL);
731
732         fullname      = modest_account_mgr_get_string (self, name,MODEST_ACCOUNT_FULLNAME,
733                                                        FALSE);
734         email         = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_EMAIL,
735                                                        FALSE);
736         from = g_strdup_printf ("%s <%s>",
737                                 fullname ? fullname : "",
738                                 email    ? email    : "");
739         g_free (fullname);
740         g_free (email);
741
742         return from;
743 }
744
745 /* Add a number to the end of the text, or increment a number that is already there.
746  */
747 static gchar*
748 util_increment_name (const gchar* text)
749 {
750         /* Get the end character,
751          * also doing a UTF-8 validation which is required for using g_utf8_prev_char().
752          */
753         const gchar* end = NULL;
754         if (!g_utf8_validate (text, -1, &end))
755                 return NULL;
756   
757         if (!end)
758                 return NULL;
759                 
760         --end; /* Go to before the null-termination. */
761                 
762         /* Look at each UTF-8 characer, starting at the end: */
763         const gchar* p = end;
764         const gchar* alpha_end = NULL;
765         while (p)
766         {       
767                 /* Stop when we reach the first character that is not a numeric digit: */
768                 const gunichar ch = g_utf8_get_char (p);
769                 if (!g_unichar_isdigit (ch)) {
770                         alpha_end = p;
771                         break;
772                 }
773                 
774                 p = g_utf8_prev_char (p);       
775         }
776         
777         if(!alpha_end) {
778                 /* The text must consist completely of numeric digits. */
779                 alpha_end = text;
780         }
781         else
782                 ++alpha_end;
783         
784         /* Intepret and increment the number, if any: */
785         gint num = atol (alpha_end);
786         ++num;
787         
788         /* Get the name part: */
789         gint name_len = alpha_end - text;
790         gchar *name_without_number = g_malloc(name_len + 1);
791         memcpy (name_without_number, text, name_len);
792         name_without_number[name_len] = 0;\
793         
794     /* Concatenate the text part and the new number: */ 
795         gchar *result = g_strdup_printf("%s%d", name_without_number, num);
796         g_free (name_without_number);
797         
798         return result;  
799 }
800
801 gchar*
802 modest_account_mgr_get_unused_account_name (ModestAccountMgr *self, const gchar* starting_name,
803         gboolean server_account)
804 {
805         gchar *account_name = g_strdup (starting_name);
806
807         while (modest_account_mgr_account_exists (self, 
808                 account_name, server_account /*  server_account */)) {
809                         
810                 gchar * account_name2 = util_increment_name (account_name);
811                 g_free (account_name);
812                 account_name = account_name2;
813         }
814         
815         return account_name;
816 }
817
818 gchar*
819 modest_account_mgr_get_unused_account_display_name (ModestAccountMgr *self, const gchar* starting_name)
820 {
821         gchar *account_name = g_strdup (starting_name);
822
823         while (modest_account_mgr_account_with_display_name_exists (self, account_name)) {
824                         
825                 gchar * account_name2 = util_increment_name (account_name);
826                 g_free (account_name);
827                 account_name = account_name2;
828         }
829         
830         return account_name;
831 }
832
833 void 
834 modest_account_mgr_set_leave_on_server (ModestAccountMgr *self, 
835                                         const gchar *account_name, 
836                                         gboolean leave_on_server)
837 {
838         modest_account_mgr_set_bool (self, 
839                                      account_name,
840                                      MODEST_ACCOUNT_LEAVE_ON_SERVER, 
841                                      leave_on_server, 
842                                      FALSE);
843 }
844
845 gboolean 
846 modest_account_mgr_get_leave_on_server (ModestAccountMgr *self, 
847                                         const gchar* account_name)
848 {
849         return modest_account_mgr_get_bool (self, 
850                                             account_name,
851                                             MODEST_ACCOUNT_LEAVE_ON_SERVER, 
852                                             FALSE);
853 }
854
855 gint 
856 modest_account_mgr_get_last_updated (ModestAccountMgr *self, 
857                                      const gchar* account_name)
858 {
859         return modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
860                                            account_name, 
861                                            MODEST_ACCOUNT_LAST_UPDATED, 
862                                            TRUE);
863 }
864
865 void 
866 modest_account_mgr_set_last_updated (ModestAccountMgr *self, 
867                                      const gchar* account_name,
868                                      gint time)
869 {
870         modest_account_mgr_set_int (self, 
871                                     account_name, 
872                                     MODEST_ACCOUNT_LAST_UPDATED, 
873                                     time, 
874                                     TRUE);
875
876         /* TODO: notify about changes */
877 }
878
879 gint  
880 modest_account_mgr_get_retrieve_limit (ModestAccountMgr *self, 
881                                        const gchar* account_name)
882 {
883         return modest_account_mgr_get_int (self, 
884                                            account_name,
885                                            MODEST_ACCOUNT_LIMIT_RETRIEVE, 
886                                            FALSE);
887 }
888
889 void  
890 modest_account_mgr_set_retrieve_limit (ModestAccountMgr *self, 
891                                        const gchar* account_name,
892                                        gint limit_retrieve)
893 {
894         modest_account_mgr_set_int (self, 
895                                     account_name,
896                                     MODEST_ACCOUNT_LIMIT_RETRIEVE, 
897                                     limit_retrieve, 
898                                     FALSE /* not server account */);
899 }
900
901 gint  
902 modest_account_mgr_get_server_account_port (ModestAccountMgr *self, 
903                                             const gchar* account_name)
904 {
905         return modest_account_mgr_get_int (self, 
906                                            account_name,
907                                            MODEST_ACCOUNT_PORT, 
908                                            TRUE);
909 }
910
911 void
912 modest_account_mgr_set_server_account_port (ModestAccountMgr *self, 
913                                             const gchar *account_name,
914                                             gint port_num)
915 {
916         modest_account_mgr_set_int (self, 
917                                     account_name,
918                                     MODEST_ACCOUNT_PORT, 
919                                     port_num, TRUE /* server account */);
920 }
921
922 gchar* 
923 modest_account_mgr_get_server_account_name (ModestAccountMgr *self, 
924                                             const gchar *account_name,
925                                             TnyAccountType account_type)
926 {
927         return modest_account_mgr_get_string (self, 
928                                               account_name,
929                                               (account_type == TNY_ACCOUNT_TYPE_STORE) ?
930                                               MODEST_ACCOUNT_STORE_ACCOUNT :
931                                               MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
932                                               FALSE);
933 }
934
935 static const gchar *
936 get_retrieve_type_name (ModestAccountRetrieveType retrieve_type)
937 {
938         switch(retrieve_type) {
939         case MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY:
940                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
941                 break;
942         case MODEST_ACCOUNT_RETRIEVE_MESSAGES:
943                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES;
944                 break;
945         case MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS:
946                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS;
947                 break;
948         default:
949                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
950         };
951 }
952
953 static ModestAccountRetrieveType
954 get_retrieve_type (const gchar *name)
955 {
956         if (!name || name[0] == 0)
957                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
958         if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) == 0) {
959                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES;
960         } else if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS) == 0) {
961                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS;
962         } else {
963                 /* we fall back to headers only */
964                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
965         }
966 }
967
968 ModestAccountRetrieveType
969 modest_account_mgr_get_retrieve_type (ModestAccountMgr *self, 
970                                       const gchar *account_name)
971 {
972         gchar *string;
973         ModestAccountRetrieveType result;
974
975         string =  modest_account_mgr_get_string (self, 
976                                                  account_name,
977                                                  MODEST_ACCOUNT_RETRIEVE, 
978                                                  FALSE /* not server account */);
979         result = get_retrieve_type (string);
980         g_free (string);
981
982         return result;
983 }
984
985 void 
986 modest_account_mgr_set_retrieve_type (ModestAccountMgr *self, 
987                                       const gchar *account_name,
988                                       ModestAccountRetrieveType retrieve_type)
989 {
990         modest_account_mgr_set_string (self, 
991                                        account_name,
992                                        MODEST_ACCOUNT_RETRIEVE, 
993                                        get_retrieve_type_name (retrieve_type), 
994                                        FALSE /* not server account */);
995 }
996
997
998 void
999 modest_account_mgr_set_user_fullname (ModestAccountMgr *self, 
1000                                       const gchar *account_name,
1001                                       const gchar *fullname)
1002 {
1003         modest_account_mgr_set_string (self, 
1004                                        account_name,
1005                                        MODEST_ACCOUNT_FULLNAME, 
1006                                        fullname, 
1007                                        FALSE /* not server account */);
1008 }
1009
1010 void
1011 modest_account_mgr_set_user_email (ModestAccountMgr *self, 
1012                                    const gchar *account_name,
1013                                    const gchar *email)
1014 {
1015         modest_account_mgr_set_string (self, 
1016                                        account_name,
1017                                        MODEST_ACCOUNT_EMAIL, 
1018                                        email, 
1019                                        FALSE /* not server account */);
1020 }