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