Show folders with non read messages with active text color
[modest] / src / modest-account-mgr-helpers.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <modest-account-mgr-helpers.h>
31 #include <modest-account-mgr-priv.h>
32 #include <tny-simple-list.h>
33 #include <modest-runtime.h>
34 #include <modest-defs.h>
35 #include <string.h>
36 #include <strings.h>
37 #include <modest-account-protocol.h>
38 #include <modest-utils.h>
39
40 static const gchar * null_means_empty (const gchar * str);
41
42 static const gchar *
43 null_means_empty (const gchar * str)
44 {
45         return str ? str : "";
46 }
47
48 gboolean
49 modest_account_mgr_set_enabled (ModestAccountMgr *self, const gchar* name,
50                                         gboolean enabled)
51 {
52         return modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_ENABLED, enabled,FALSE);
53 }
54
55
56 gboolean
57 modest_account_mgr_get_enabled (ModestAccountMgr *self, const gchar* name)
58 {
59         return modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_ENABLED, FALSE);
60 }
61
62 gboolean modest_account_mgr_set_signature (ModestAccountMgr *self, const gchar* name, 
63         const gchar* signature, gboolean use_signature)
64 {
65         gboolean result = modest_account_mgr_set_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, 
66                 use_signature, FALSE);
67         result = result && modest_account_mgr_set_string (self, name, MODEST_ACCOUNT_SIGNATURE, 
68                                                           null_means_empty (signature), FALSE);
69         return result;
70 }
71
72 gchar* 
73 modest_account_mgr_get_signature (ModestAccountMgr *self, 
74                                   const gchar* name, 
75                                   gboolean* use_signature)
76 {
77         *use_signature = 
78                 modest_account_mgr_get_bool (self, name, MODEST_ACCOUNT_USE_SIGNATURE, FALSE);
79         
80         return modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SIGNATURE, FALSE);
81 }
82
83 ModestProtocolType modest_account_mgr_get_store_protocol (ModestAccountMgr *self, const gchar* name)
84 {
85        ModestProtocolType result = MODEST_PROTOCOLS_STORE_POP; /* Arbitrary default */
86        
87        gchar *server_account_name = modest_account_mgr_get_string (self, name,
88                                                                    MODEST_ACCOUNT_STORE_ACCOUNT,
89                                                                    FALSE);
90        if (server_account_name) {
91                ModestServerAccountSettings* server_settings = 
92                        modest_account_mgr_load_server_settings (self, server_account_name, FALSE);
93                result = modest_server_account_settings_get_protocol (server_settings);
94                
95                g_object_unref (server_settings);
96                
97                g_free (server_account_name);
98        }
99        
100        return result;
101 }
102
103
104 gboolean 
105 modest_account_mgr_set_connection_specific_smtp (ModestAccountMgr *self, 
106                                                  const gchar* connection_id, 
107                                                  const gchar* server_account_name)
108 {
109         modest_account_mgr_remove_connection_specific_smtp (self, connection_id);
110         
111         ModestConf *conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
112
113         gboolean result = TRUE;
114         GError *err = NULL;
115         GSList *list = modest_conf_get_list (conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
116                                                     MODEST_CONF_VALUE_STRING, &err);
117         if (err) {
118                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
119                 g_error_free (err);
120                 err = NULL;
121                 result = FALSE;
122         } else {        
123                 /* The server account is in the item after the connection name: */
124                 list = g_slist_append (list, g_strdup (connection_id));
125                 list = g_slist_append (list, g_strdup (server_account_name));
126         
127                 /* Reset the changed list: */
128                 modest_conf_set_list (conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST, list,
129                                                     MODEST_CONF_VALUE_STRING, &err);
130                 if (err) {
131                         g_printerr ("modest: %s: error setting list: %s.\n", __FUNCTION__, err->message);
132                         g_error_free (err);
133                         result = FALSE;
134                 }
135         }
136                                 
137         /* Free the list */
138         if (list) {
139                 g_slist_foreach (list, (GFunc) g_free, NULL);
140                 g_slist_free (list);
141         }
142         
143         return result;
144 }
145
146 /**
147  * modest_account_mgr_remove_connection_specific_smtp
148  * @self: a ModestAccountMgr instance
149  * @name: the account name
150  * @connection_id: A libconic IAP connection id
151  * 
152  * Disassacoiate a server account to use with the specific connection for this account.
153  *
154  * Returns: TRUE if it worked, FALSE otherwise
155  */                              
156 gboolean 
157 modest_account_mgr_remove_connection_specific_smtp (ModestAccountMgr *self, 
158                                                     const gchar* connection_id)
159 {
160         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
161         
162         gboolean result = TRUE;
163         GError *err = NULL;
164         GSList *list = modest_conf_get_list (priv->modest_conf, 
165                                              MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
166                                              MODEST_CONF_VALUE_STRING, &err);
167         if (err) {
168                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
169                 g_error_free (err);
170                 err = NULL;
171                 result = FALSE;
172         }
173
174         if (!list)
175                 return FALSE;
176                 
177         /* The server account is in the item after the connection name: */
178         GSList *list_connection = g_slist_find_custom (list, connection_id, (GCompareFunc)strcmp);
179         if (list_connection) {
180                 GSList *account_node = g_slist_next (list_connection);
181                 /* remove both items: */
182                 list = g_slist_delete_link(list, list_connection);
183                 list = g_slist_delete_link(list, account_node);
184         }
185         
186         /* Reset the changed list: */
187         modest_conf_set_list (priv->modest_conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST, list,
188                                                     MODEST_CONF_VALUE_STRING, &err);
189         if (err) {
190                 g_printerr ("modest: %s: error setting list: %s.\n", __FUNCTION__, err->message);
191                 g_error_free (err);
192                 result = FALSE;
193         }
194                                 
195         /* Free the list */
196         if (list) {
197                 g_slist_foreach (list, (GFunc) g_free, NULL);
198                 g_slist_free (list);
199         }
200         
201         return result;
202 }
203
204
205 gboolean modest_account_mgr_get_use_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name)
206 {
207         return modest_account_mgr_get_bool (self, account_name, 
208                 MODEST_ACCOUNT_USE_CONNECTION_SPECIFIC_SMTP, FALSE);
209 }
210
211 gboolean modest_account_mgr_set_use_connection_specific_smtp (ModestAccountMgr *self, const gchar* account_name, 
212         gboolean new_value)
213 {
214         return modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USE_CONNECTION_SPECIFIC_SMTP, 
215                 new_value, FALSE);
216 }
217
218 /**
219  * modest_account_mgr_get_connection_specific_smtp
220  * @self: a ModestAccountMgr instance
221  * @connection_id: A libconic IAP connection id
222  * 
223  * Retrieve a server account to use with this specific connection for this account.
224  *
225  * Returns: a server account name to use for this connection, or NULL if none is specified.
226  */                      
227 gchar* modest_account_mgr_get_connection_specific_smtp (ModestAccountMgr *self,  const gchar* connection_id)
228 {
229         gchar *result = NULL;
230         
231         ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
232         
233         GError *err = NULL;
234         GSList *list = modest_conf_get_list (priv->modest_conf, MODEST_CONF_CONNECTION_SPECIFIC_SMTP_LIST,
235                                                     MODEST_CONF_VALUE_STRING, &err);
236         if (err) {
237                 g_printerr ("modest: %s: error getting list: %s.\n", __FUNCTION__, err->message);
238                 g_error_free (err);
239                 err = NULL;
240         }
241
242         if (!list)
243                 return NULL;
244
245         /* The server account is in the item after the connection name: */
246         GSList *iter = list;
247         while (iter) {
248                 const gchar* this_connection_id = (const gchar*)(iter->data);
249                 if (strcmp (this_connection_id, connection_id) == 0) {
250                         iter = g_slist_next (iter);
251                         
252                         if (iter) {
253                                 const gchar* account_name = (const gchar*)(iter->data);
254                                 if (account_name) {
255                                         result = g_strdup (account_name);
256                                         break;
257                                 }
258                         }
259                 }
260                 
261                 /* Skip 2 to go to the next connection in the list: */
262                 iter = g_slist_next (iter);
263                 if (iter)
264                         iter = g_slist_next (iter);
265         }
266                 
267         /* Free the list */
268         if (list) {
269                 g_slist_foreach (list, (GFunc) g_free, NULL);
270                 g_slist_free (list);
271         }
272         
273         return result;
274 }
275                                          
276 gchar*
277 modest_account_mgr_get_server_account_username (ModestAccountMgr *self, const gchar* account_name)
278 {
279         return modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_USERNAME, 
280                 TRUE /* server account */);
281 }
282
283 void
284 modest_account_mgr_set_server_account_username (ModestAccountMgr *self, const gchar* account_name, 
285         const gchar* username)
286 {
287         /* Note that this won't work properly as long as the gconf cache is broken 
288          * in Maemo Bora: */
289         gchar *existing_username = modest_account_mgr_get_server_account_username(self, 
290                 account_name);
291         
292         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME, 
293                 username, TRUE /* server account */);
294                 
295         /* We don't know anything about new usernames: */
296         if (strcmp (existing_username, username) != 0)
297                 modest_account_mgr_set_server_account_username_has_succeeded (self, account_name, FALSE);
298                 
299         g_free (existing_username);
300 }
301
302 gboolean
303 modest_account_mgr_get_server_account_username_has_succeeded (ModestAccountMgr *self, const gchar* account_name)
304 {
305         return modest_account_mgr_get_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
306                                             TRUE /* server account */);
307 }
308
309 void
310 modest_account_mgr_set_server_account_username_has_succeeded (ModestAccountMgr *self, 
311                                                   const gchar* account_name, 
312                                                   gboolean succeeded)
313 {
314         modest_account_mgr_set_bool (self, account_name, MODEST_ACCOUNT_USERNAME_HAS_SUCCEEDED, 
315                                      succeeded, TRUE /* server account */);
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                 /* Clean password */
335                 bzero (password, strlen (password));
336         }
337
338         g_free (password);
339         return result;
340 }
341                          
342         
343 gchar*
344 modest_account_mgr_get_server_account_hostname (ModestAccountMgr *self, 
345                                                 const gchar* account_name)
346 {
347         return modest_account_mgr_get_string (self, 
348                                               account_name, 
349                                               MODEST_ACCOUNT_HOSTNAME, 
350                                               TRUE /* server account */);
351 }
352  
353 void
354 modest_account_mgr_set_server_account_hostname (ModestAccountMgr *self, 
355                                                 const gchar *server_account_name,
356                                                 const gchar *hostname)
357 {
358         modest_account_mgr_set_string (self, 
359                                        server_account_name,
360                                        MODEST_ACCOUNT_HOSTNAME, 
361                                        hostname, 
362                                        TRUE /* server account */);
363 }
364
365
366
367 ModestProtocolType
368 modest_account_mgr_get_server_account_secure_auth (ModestAccountMgr *self, 
369         const gchar* account_name)
370 {
371         ModestProtocolRegistry *protocol_registry;
372         ModestProtocolType result = MODEST_PROTOCOLS_AUTH_NONE;
373         gchar* value;
374
375         protocol_registry = modest_runtime_get_protocol_registry ();
376         value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, 
377                                                TRUE /* server account */);
378         if (value) {
379                 ModestProtocol *protocol;
380
381                 protocol = modest_protocol_registry_get_protocol_by_name (protocol_registry, MODEST_PROTOCOL_REGISTRY_AUTH_PROTOCOLS, value);
382                 g_free (value);
383
384                 if (protocol)
385                         result = modest_protocol_get_type_id (protocol);
386                         
387         }
388         
389         return result;
390 }
391
392
393 void
394 modest_account_mgr_set_server_account_secure_auth (ModestAccountMgr *self, 
395         const gchar* account_name, ModestProtocolType secure_auth)
396 {
397         const gchar* str_value;
398         ModestProtocolRegistry *protocol_registry;
399         ModestProtocol *protocol;
400
401         /* Get the conf string for the protocol: */
402         protocol_registry = modest_runtime_get_protocol_registry ();
403         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, secure_auth);
404         str_value = modest_protocol_get_name (protocol);
405         
406         /* Set it in the configuration: */
407         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_AUTH_MECH, str_value, TRUE);
408 }
409
410 ModestProtocolType
411 modest_account_mgr_get_server_account_security (ModestAccountMgr *self, 
412         const gchar* account_name)
413 {
414         ModestProtocolType result = MODEST_PROTOCOLS_CONNECTION_NONE;
415         gchar* value;
416
417         value = modest_account_mgr_get_string (self, account_name, MODEST_ACCOUNT_SECURITY, 
418                                                TRUE /* server account */);
419         if (value) {
420                 ModestProtocolRegistry *protocol_registry;
421                 ModestProtocol *protocol;
422
423                 protocol_registry = modest_runtime_get_protocol_registry ();
424                 protocol = modest_protocol_registry_get_protocol_by_name (protocol_registry,
425                                                                           MODEST_PROTOCOL_REGISTRY_CONNECTION_PROTOCOLS,
426                                                                           value);
427                 g_free (value);
428
429                 if (protocol)
430                         result = modest_protocol_get_type_id (protocol);
431         }
432         
433         return result;
434 }
435
436 void
437 modest_account_mgr_set_server_account_security (ModestAccountMgr *self, 
438                                                 const gchar* account_name, 
439                                                 ModestProtocolType security)
440 {
441         const gchar* str_value;
442         ModestProtocolRegistry *protocol_registry;
443         ModestProtocol *protocol;
444
445         /* Get the conf string for the protocol type: */
446         protocol_registry = modest_runtime_get_protocol_registry ();
447         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, security);
448         str_value = modest_protocol_get_name (protocol);
449         
450         /* Set it in the configuration: */
451         modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY, str_value, TRUE);
452 }
453
454 ModestServerAccountSettings *
455 modest_account_mgr_load_server_settings (ModestAccountMgr *self, const gchar* name, gboolean is_transport_and_not_store)
456 {
457         ModestServerAccountSettings *settings = NULL;
458         ModestProtocol *protocol;
459         ModestProtocolRegistry *registry;
460         gchar *hostname, *username, *pwd, *uri, *proto, *auth, *sec;
461
462         if (!modest_account_mgr_account_exists (self, name, TRUE)) {
463                 g_message ("%s account %s does not exist", __FUNCTION__, name);
464                 return NULL;
465         }
466
467         registry = modest_runtime_get_protocol_registry ();
468         settings = modest_server_account_settings_new ();
469
470         modest_server_account_settings_set_account_name (settings, name);
471
472         proto = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_PROTO, TRUE);
473         if (proto) {
474                 gchar *tag = NULL;
475                 if (is_transport_and_not_store) {
476                         tag = MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS;
477                 } else {
478                         tag = MODEST_PROTOCOL_REGISTRY_STORE_PROTOCOLS;
479                 }
480                 protocol = modest_protocol_registry_get_protocol_by_name (registry, tag, proto);
481
482                 modest_server_account_settings_set_protocol (settings,
483                                                              modest_protocol_get_type_id (protocol));
484                 g_free (proto);
485         } else {
486                 goto on_error;
487         }
488
489         modest_server_account_settings_set_port (settings,
490                                                  modest_account_mgr_get_int (self, name, MODEST_ACCOUNT_PORT, TRUE));
491
492         auth = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_AUTH_MECH, TRUE);
493         if (auth) {
494                 protocol = modest_protocol_registry_get_protocol_by_name (registry, MODEST_PROTOCOL_REGISTRY_AUTH_PROTOCOLS, auth);
495                 modest_server_account_settings_set_auth_protocol (settings,
496                                                                   modest_protocol_get_type_id (protocol));
497                 g_free (auth);
498         } else {
499                 modest_server_account_settings_set_auth_protocol (settings, MODEST_PROTOCOLS_AUTH_NONE);
500         }
501
502         sec = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_SECURITY, TRUE);
503         if (sec) {
504                 protocol = modest_protocol_registry_get_protocol_by_name (registry, MODEST_PROTOCOL_REGISTRY_CONNECTION_PROTOCOLS, sec);
505                 modest_server_account_settings_set_security_protocol (settings,
506                                                                       modest_protocol_get_type_id (protocol));
507                 g_free (sec);
508         } else {
509                 modest_server_account_settings_set_security_protocol (settings,
510                                                                       MODEST_PROTOCOLS_CONNECTION_NONE);
511         }
512
513         /* Username, password and URI. Note that the URI could include
514            the former two, so in this case there is no need to have
515            them */
516         username = modest_account_mgr_get_string (self, name,
517                                                   MODEST_ACCOUNT_USERNAME,TRUE);
518         if (username)
519                 modest_server_account_settings_set_username (settings, username);
520
521         pwd = modest_account_mgr_get_string (self, name,
522                                              MODEST_ACCOUNT_PASSWORD, TRUE);
523         if (pwd) {
524                 modest_server_account_settings_set_password (settings, pwd);
525                 g_free (pwd);
526         }
527
528         uri = modest_account_mgr_get_string (self, name,
529                                              MODEST_ACCOUNT_URI, TRUE);
530         if (uri)
531                 modest_server_account_settings_set_uri (settings, uri);
532
533         hostname = modest_account_mgr_get_string (self, name,
534                                                   MODEST_ACCOUNT_HOSTNAME,TRUE);
535         if (hostname)
536                 modest_server_account_settings_set_hostname (settings, hostname);
537
538         if (!uri) {
539                 if (!username || !hostname) {
540                         g_free (username);
541                         g_free (hostname);
542                         goto on_error;
543                 }
544         }
545
546         g_free (username);
547         g_free (hostname);
548         g_free (uri);
549
550         return settings;
551
552  on_error:
553         if (settings)
554                 g_object_unref (settings);
555         return NULL;
556 }
557
558 gboolean 
559 modest_account_mgr_save_server_settings (ModestAccountMgr *self,
560                                          ModestServerAccountSettings *settings)
561 {
562         gboolean has_errors = FALSE;
563         const gchar *account_name;
564         const gchar *protocol_name;
565         const gchar *uri;
566         ModestProtocolRegistry *protocol_registry;
567         ModestProtocol *protocol;
568         
569         g_return_val_if_fail (MODEST_IS_SERVER_ACCOUNT_SETTINGS (settings), FALSE);
570         protocol_registry = modest_runtime_get_protocol_registry ();
571         account_name = modest_server_account_settings_get_account_name (settings);
572
573         /* if we don't have a valid account name we cannot save */
574         g_return_val_if_fail (account_name, FALSE);
575
576         protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
577                                                                   modest_server_account_settings_get_protocol (settings));
578         protocol_name = modest_protocol_get_name (protocol);
579         uri = modest_server_account_settings_get_uri (settings);
580         if (!uri) {
581                 const gchar *hostname;
582                 const gchar *username;
583                 const gchar *password;
584                 gint port;
585                 const gchar *auth_protocol_name;
586                 const gchar *security_name;
587
588                 hostname = null_means_empty (modest_server_account_settings_get_hostname (settings));
589                 username = null_means_empty (modest_server_account_settings_get_username (settings));
590                 password = null_means_empty (modest_server_account_settings_get_password (settings));
591                 port = modest_server_account_settings_get_port (settings);
592                 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
593                                                                           modest_server_account_settings_get_auth_protocol (settings));
594                 auth_protocol_name = modest_protocol_get_name (protocol);
595                 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry,
596                                                                           modest_server_account_settings_get_security_protocol (settings));
597                 security_name = modest_protocol_get_name (protocol);
598
599                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_HOSTNAME, 
600                                                             hostname, TRUE);
601                 if (!has_errors)
602                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_USERNAME,
603                                                                            username, TRUE));
604                 if (!has_errors)
605                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PASSWORD,
606                                                                            password, TRUE));
607                 if (!has_errors)
608                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
609                                                                            protocol_name, TRUE));
610                 if (!has_errors)
611                         (has_errors = !modest_account_mgr_set_int (self, account_name, MODEST_ACCOUNT_PORT,
612                                                                         port, TRUE));
613                 if (!has_errors)
614                         (has_errors = !modest_account_mgr_set_string (self, account_name, 
615                                                                            MODEST_ACCOUNT_AUTH_MECH,
616                                                                            auth_protocol_name, TRUE));          
617                 if (!has_errors)
618                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_SECURITY,
619                                                                            security_name,
620                                                                            TRUE));
621         } else {
622                 const gchar *uri = modest_server_account_settings_get_uri (settings);
623                 has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_URI,
624                                                             uri, TRUE);
625                 if (!has_errors)
626                         (has_errors = !modest_account_mgr_set_string (self, account_name, MODEST_ACCOUNT_PROTO,
627                                                                            protocol_name, TRUE));
628         }
629
630         return !has_errors;
631
632 }
633
634
635 ModestAccountSettings *
636 modest_account_mgr_load_account_settings (ModestAccountMgr *self, 
637                                           const gchar* name)
638 {
639         ModestAccountSettings *settings;
640         gchar *string;
641         gchar *server_account;
642         gchar *default_account;
643         gboolean use_signature = FALSE;
644         
645         g_return_val_if_fail (self, NULL);
646         g_return_val_if_fail (name, NULL);
647         
648         if (!modest_account_mgr_account_exists (self, name, FALSE)) {
649                 /* For instance, maybe you are mistakenly checking for a server account name? */
650                 g_warning ("%s: Account %s does not exist.", __FUNCTION__, name);
651                 return NULL;
652         }
653         
654         settings = modest_account_settings_new ();
655
656         modest_account_settings_set_account_name (settings, name);
657
658         string = modest_account_mgr_get_string (self, name,
659                                                 MODEST_ACCOUNT_DISPLAY_NAME,
660                                                 FALSE);
661         modest_account_settings_set_display_name (settings, string);
662         g_free (string);
663
664         string = modest_account_mgr_get_string (self, name,
665                                                 MODEST_ACCOUNT_FULLNAME,
666                                                 FALSE);
667         modest_account_settings_set_fullname (settings, string);
668         g_free (string);
669
670         string = modest_account_mgr_get_string (self, name,
671                                                 MODEST_ACCOUNT_EMAIL,
672                                                 FALSE);
673         modest_account_settings_set_email_address (settings, string);
674         g_free (string);
675
676         modest_account_settings_set_enabled (settings, modest_account_mgr_get_enabled (self, name));
677         modest_account_settings_set_retrieve_type (settings, modest_account_mgr_get_retrieve_type (self, name));
678         modest_account_settings_set_retrieve_limit (settings, modest_account_mgr_get_retrieve_limit (self, name));
679
680         default_account    = modest_account_mgr_get_default_account (self);
681         modest_account_settings_set_is_default (settings,
682                                                 (default_account && strcmp (default_account, name) == 0));
683         g_free (default_account);
684
685         string = modest_account_mgr_get_signature (self, name, &use_signature);
686         modest_account_settings_set_use_signature (settings, use_signature);
687         modest_account_settings_set_signature (settings, string);
688         g_free (string);
689
690         modest_account_settings_set_leave_messages_on_server 
691                 (settings, modest_account_mgr_get_leave_on_server (self, name));
692         modest_account_settings_set_use_connection_specific_smtp 
693                 (settings, modest_account_mgr_get_use_connection_specific_smtp (self, name));
694
695         /* store */
696         server_account     = modest_account_mgr_get_string (self, name,
697                                                             MODEST_ACCOUNT_STORE_ACCOUNT,
698                                                             FALSE);
699         if (server_account) {
700                 ModestServerAccountSettings *store_settings;
701                 store_settings = modest_account_mgr_load_server_settings (self, server_account, FALSE);
702                 g_free (server_account);
703
704                 /* It could happen that the account data is corrupted
705                    so it's not loaded properly */
706                 if (store_settings) {
707                         modest_account_settings_set_store_settings (settings,
708                                                                     store_settings);
709                         g_object_unref (store_settings);
710                 } else {
711                         g_message ("%s can not load server settings. Account corrupted?", __FUNCTION__);
712                         g_object_unref (settings);
713                         return NULL;
714                 }
715         }
716
717         /* transport */
718         server_account = modest_account_mgr_get_string (self, name,
719                                                         MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
720                                                         FALSE);
721         if (server_account) {
722                 ModestServerAccountSettings *transport_settings;
723                 transport_settings = modest_account_mgr_load_server_settings (self, server_account, TRUE);
724                 g_free (server_account);
725
726                 if (transport_settings) {
727                         modest_account_settings_set_transport_settings (settings, transport_settings);
728                         g_object_unref (transport_settings);
729                 } else {
730                         g_message ("%s can not load server settings. Account corrupted?", __FUNCTION__);
731                         g_object_unref (settings);
732                         return NULL;
733                 }
734         }
735
736         return settings;
737 }
738
739 void
740 modest_account_mgr_save_account_settings (ModestAccountMgr *mgr,
741                                           ModestAccountSettings *settings)
742 {
743         const gchar *account_name;
744         ModestServerAccountSettings *store_settings;
745         ModestServerAccountSettings *transport_settings;
746
747         g_return_if_fail (MODEST_IS_ACCOUNT_MGR (mgr));
748         g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
749
750         account_name = modest_account_settings_get_account_name (settings);
751         g_return_if_fail (account_name != NULL);
752
753         modest_account_mgr_set_display_name (mgr, account_name,
754                                              modest_account_settings_get_display_name (settings));
755         modest_account_mgr_set_user_fullname (mgr, account_name,
756                                               modest_account_settings_get_fullname (settings));
757         modest_account_mgr_set_user_email (mgr, account_name,
758                                            modest_account_settings_get_email_address (settings));
759         modest_account_mgr_set_retrieve_type (mgr, account_name,
760                                               modest_account_settings_get_retrieve_type (settings));
761         modest_account_mgr_set_retrieve_limit (mgr, account_name,
762                                                modest_account_settings_get_retrieve_limit (settings));
763         modest_account_mgr_set_leave_on_server (mgr, account_name,
764                                                 modest_account_settings_get_leave_messages_on_server (settings));
765         modest_account_mgr_set_signature (mgr, account_name,
766                                           modest_account_settings_get_signature (settings),
767                                           modest_account_settings_get_use_signature (settings));
768         modest_account_mgr_set_use_connection_specific_smtp 
769                 (mgr, account_name,
770                  modest_account_settings_get_use_connection_specific_smtp (settings));
771
772         store_settings = modest_account_settings_get_store_settings (settings);
773         if (store_settings) {
774                 const gchar *store_account_name;
775                 store_account_name = modest_server_account_settings_get_account_name (store_settings);
776                 if (store_account_name)
777                         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_STORE_ACCOUNT, 
778                                                        store_account_name, FALSE);
779                 modest_account_mgr_save_server_settings (mgr, store_settings);
780                 g_object_unref (store_settings);
781         }
782
783         transport_settings = modest_account_settings_get_transport_settings (settings);
784         if (transport_settings) {
785                 const gchar *transport_account_name;
786                 transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
787                 if (transport_account_name)
788                         modest_account_mgr_set_string (mgr, account_name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
789                                                        transport_account_name, FALSE);
790                 modest_account_mgr_save_server_settings (mgr, transport_settings);
791                 g_object_unref (transport_settings);
792         }
793         modest_account_mgr_set_enabled (mgr, account_name, TRUE);
794 }
795
796
797 gint 
798 on_accounts_list_sort_by_title(gconstpointer a, gconstpointer b)
799 {
800         return g_utf8_collate((const gchar*)a, (const gchar*)b);
801 }
802
803 /** Get the first one, alphabetically, by title. */
804 gchar* 
805 modest_account_mgr_get_first_account_name (ModestAccountMgr *self)
806 {
807         const gchar* account_name = NULL;
808         GSList *account_names = modest_account_mgr_account_names (self, TRUE /* only enabled */);
809
810         /* Return TRUE if there is no account */
811         if (!account_names)
812                 return NULL;
813
814         /* Get the first one, alphabetically, by title: */
815         /* gchar *old_default = modest_account_mgr_get_default_account (self); */
816         GSList* list_sorted = g_slist_sort (account_names, on_accounts_list_sort_by_title);
817
818         GSList* iter = list_sorted;
819         gboolean found = FALSE;
820         while (iter && !found) {
821                 account_name = (const gchar*)list_sorted->data;
822
823                 if (account_name)
824                         found = TRUE;
825
826                 if (!found)
827                         iter = g_slist_next (iter);
828         }
829
830         gchar* result = NULL;
831         if (account_name)
832                 result = g_strdup (account_name);
833                 
834         modest_account_mgr_free_account_names (account_names);
835         account_names = NULL;
836
837         return result;
838 }
839
840 gboolean
841 modest_account_mgr_set_first_account_as_default (ModestAccountMgr *self)
842 {
843         gboolean result = FALSE;
844         
845         gchar* account_name = modest_account_mgr_get_first_account_name(self);
846         if (account_name) {
847                 result = modest_account_mgr_set_default_account (self, account_name);
848                 g_free (account_name);
849         }
850         else
851                 result = TRUE; /* If there are no accounts then it's not a failure. */
852
853         return result;
854 }
855
856 gchar*
857 modest_account_mgr_get_from_string (ModestAccountMgr *self, const gchar* name, const gchar *mailbox)
858 {
859         gchar *from;
860         gchar *transport_account;
861         gchar *proto;
862         
863         g_return_val_if_fail (self, NULL);
864         g_return_val_if_fail (name, NULL);
865
866         from = NULL;
867
868         transport_account = modest_account_mgr_get_server_account_name (self,
869                                                                         name,
870                                                                         TNY_ACCOUNT_TYPE_TRANSPORT);
871         if (transport_account) {
872                 proto = modest_account_mgr_get_string (self, transport_account, MODEST_ACCOUNT_PROTO, TRUE);
873                 if (proto != NULL) {
874                         ModestProtocol *protocol = 
875                                 modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
876                                                                                MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
877                                                                                proto);
878                         if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
879                                 from = modest_account_protocol_get_from (MODEST_ACCOUNT_PROTOCOL (protocol),
880                                                                          name,
881                                                                          mailbox);
882                         }
883                         g_free (proto);
884                 }
885         }
886
887         if (from == NULL) {
888                 gchar *fullname, *email;
889
890                 fullname      = modest_account_mgr_get_string (self, name,MODEST_ACCOUNT_FULLNAME,
891                                                                FALSE);
892                 email         = modest_account_mgr_get_string (self, name, MODEST_ACCOUNT_EMAIL,
893                                                                FALSE);
894                 from = g_strdup_printf ("%s <%s>",
895                                         fullname ? fullname : "",
896                                         email    ? email    : "");
897                 g_free (fullname);
898                 g_free (email);
899         }
900
901         return from;
902 }
903
904 /* Add a number to the end of the text, or increment a number that is already there.
905  */
906 static gchar*
907 util_increment_name (const gchar* text)
908 {
909         g_return_val_if_fail (text, NULL);
910
911         /* Get the end character,
912          * also doing a UTF-8 validation which is required for using g_utf8_prev_char().
913          */
914         const gchar* end = NULL;
915         if (!g_utf8_validate (text, -1, &end))
916                 return NULL;
917   
918         if (!end)
919                 return NULL;
920                 
921         --end; /* Go to before the null-termination. */
922                 
923         /* Look at each UTF-8 characer, starting at the end: */
924         const gchar* p = end;
925         const gchar* alpha_end = NULL;
926         while (p)
927         {       
928                 /* Stop when we reach the first character that is not a numeric digit: */
929                 const gunichar ch = g_utf8_get_char (p);
930                 if (!g_unichar_isdigit (ch)) {
931                         alpha_end = p;
932                         break;
933                 }
934                 
935                 p = g_utf8_find_prev_char (text, p);    
936         }
937         
938         if(!alpha_end) {
939                 /* The text must consist completely of numeric digits. */
940                 alpha_end = text;
941         }
942         else
943                 ++alpha_end;
944         
945         /* Intepret and increment the number, if any: */
946         gint num = atol (alpha_end);
947         ++num;
948         
949         /* Get the name part: */
950         gint name_len = alpha_end - text;
951         gchar *name_without_number = g_malloc(name_len + 1);
952         memcpy (name_without_number, text, name_len);
953         name_without_number[name_len] = 0;\
954         
955     /* Concatenate the text part and the new number: */ 
956         gchar *result = g_strdup_printf("%s%d", name_without_number, num);
957         g_free (name_without_number);
958         
959         return result;  
960 }
961
962 gchar*
963 modest_account_mgr_get_unused_account_name (ModestAccountMgr *self, const gchar* starting_name,
964         gboolean server_account)
965 {
966         gchar *account_name = g_strdup (starting_name);
967
968         while (modest_account_mgr_account_exists (self, 
969                 account_name, server_account /*  server_account */)) {
970                         
971                 gchar * account_name2 = util_increment_name (account_name);
972                 g_free (account_name);
973                 account_name = account_name2;
974         }
975         
976         return account_name;
977 }
978
979 gchar*
980 modest_account_mgr_get_unused_account_display_name (ModestAccountMgr *self, const gchar* starting_name)
981 {
982         gchar *account_name = g_strdup (starting_name);
983
984         while (modest_account_mgr_account_with_display_name_exists (self, account_name)) {
985                         
986                 gchar * account_name2 = util_increment_name (account_name);
987                 g_free (account_name);
988                 account_name = account_name2;
989         }
990         
991         return account_name;
992 }
993
994 void 
995 modest_account_mgr_set_leave_on_server (ModestAccountMgr *self, 
996                                         const gchar *account_name, 
997                                         gboolean leave_on_server)
998 {
999         modest_account_mgr_set_bool (self, 
1000                                      account_name,
1001                                      MODEST_ACCOUNT_LEAVE_ON_SERVER, 
1002                                      leave_on_server, 
1003                                      FALSE);
1004 }
1005
1006 gboolean 
1007 modest_account_mgr_get_leave_on_server (ModestAccountMgr *self, 
1008                                         const gchar* account_name)
1009 {
1010         return modest_account_mgr_get_bool (self, 
1011                                             account_name,
1012                                             MODEST_ACCOUNT_LEAVE_ON_SERVER, 
1013                                             FALSE);
1014 }
1015
1016 gint 
1017 modest_account_mgr_get_last_updated (ModestAccountMgr *self, 
1018                                      const gchar* account_name)
1019 {
1020         return modest_account_mgr_get_int (modest_runtime_get_account_mgr (), 
1021                                            account_name, 
1022                                            MODEST_ACCOUNT_LAST_UPDATED, 
1023                                            TRUE);
1024 }
1025
1026 void 
1027 modest_account_mgr_set_last_updated (ModestAccountMgr *self, 
1028                                      const gchar* account_name,
1029                                      gint time)
1030 {
1031         modest_account_mgr_set_int (self, 
1032                                     account_name, 
1033                                     MODEST_ACCOUNT_LAST_UPDATED, 
1034                                     time, 
1035                                     TRUE);
1036
1037         /* TODO: notify about changes */
1038 }
1039
1040 gint  
1041 modest_account_mgr_get_retrieve_limit (ModestAccountMgr *self, 
1042                                        const gchar* account_name)
1043 {
1044         return modest_account_mgr_get_int (self, 
1045                                            account_name,
1046                                            MODEST_ACCOUNT_LIMIT_RETRIEVE, 
1047                                            FALSE);
1048 }
1049
1050 void  
1051 modest_account_mgr_set_retrieve_limit (ModestAccountMgr *self, 
1052                                        const gchar* account_name,
1053                                        gint limit_retrieve)
1054 {
1055         modest_account_mgr_set_int (self, 
1056                                     account_name,
1057                                     MODEST_ACCOUNT_LIMIT_RETRIEVE, 
1058                                     limit_retrieve, 
1059                                     FALSE /* not server account */);
1060 }
1061
1062 gint  
1063 modest_account_mgr_get_server_account_port (ModestAccountMgr *self, 
1064                                             const gchar* account_name)
1065 {
1066         return modest_account_mgr_get_int (self, 
1067                                            account_name,
1068                                            MODEST_ACCOUNT_PORT, 
1069                                            TRUE);
1070 }
1071
1072 void
1073 modest_account_mgr_set_server_account_port (ModestAccountMgr *self, 
1074                                             const gchar *account_name,
1075                                             gint port_num)
1076 {
1077         modest_account_mgr_set_int (self, 
1078                                     account_name,
1079                                     MODEST_ACCOUNT_PORT, 
1080                                     port_num, TRUE /* server account */);
1081 }
1082
1083 gchar* 
1084 modest_account_mgr_get_server_account_name (ModestAccountMgr *self, 
1085                                             const gchar *account_name,
1086                                             TnyAccountType account_type)
1087 {
1088         return modest_account_mgr_get_string (self, 
1089                                               account_name,
1090                                               (account_type == TNY_ACCOUNT_TYPE_STORE) ?
1091                                               MODEST_ACCOUNT_STORE_ACCOUNT :
1092                                               MODEST_ACCOUNT_TRANSPORT_ACCOUNT, 
1093                                               FALSE);
1094 }
1095
1096 static const gchar *
1097 get_retrieve_type_name (ModestAccountRetrieveType retrieve_type)
1098 {
1099         switch(retrieve_type) {
1100         case MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY:
1101                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
1102                 break;
1103         case MODEST_ACCOUNT_RETRIEVE_MESSAGES:
1104                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES;
1105                 break;
1106         case MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS:
1107                 return MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS;
1108                 break;
1109         default:
1110                 return MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY;
1111         };
1112 }
1113
1114 static ModestAccountRetrieveType
1115 get_retrieve_type (const gchar *name)
1116 {
1117         if (!name || name[0] == 0)
1118                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
1119         if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) == 0) {
1120                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES;
1121         } else if (strcmp (name, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS) == 0) {
1122                 return MODEST_ACCOUNT_RETRIEVE_MESSAGES_AND_ATTACHMENTS;
1123         } else {
1124                 /* we fall back to headers only */
1125                 return MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY;
1126         }
1127 }
1128
1129 ModestAccountRetrieveType
1130 modest_account_mgr_get_retrieve_type (ModestAccountMgr *self, 
1131                                       const gchar *account_name)
1132 {
1133         gchar *string;
1134         ModestAccountRetrieveType result;
1135
1136         string =  modest_account_mgr_get_string (self, 
1137                                                  account_name,
1138                                                  MODEST_ACCOUNT_RETRIEVE, 
1139                                                  FALSE /* not server account */);
1140         result = get_retrieve_type (string);
1141         g_free (string);
1142
1143         return result;
1144 }
1145
1146 void 
1147 modest_account_mgr_set_retrieve_type (ModestAccountMgr *self, 
1148                                       const gchar *account_name,
1149                                       ModestAccountRetrieveType retrieve_type)
1150 {
1151         modest_account_mgr_set_string (self, 
1152                                        account_name,
1153                                        MODEST_ACCOUNT_RETRIEVE, 
1154                                        get_retrieve_type_name (retrieve_type), 
1155                                        FALSE /* not server account */);
1156 }
1157
1158
1159 void
1160 modest_account_mgr_set_user_fullname (ModestAccountMgr *self, 
1161                                       const gchar *account_name,
1162                                       const gchar *fullname)
1163 {
1164         modest_account_mgr_set_string (self, 
1165                                        account_name,
1166                                        MODEST_ACCOUNT_FULLNAME, 
1167                                        fullname, 
1168                                        FALSE /* not server account */);
1169 }
1170
1171 void
1172 modest_account_mgr_set_user_email (ModestAccountMgr *self, 
1173                                    const gchar *account_name,
1174                                    const gchar *email)
1175 {
1176         modest_account_mgr_set_string (self, 
1177                                        account_name,
1178                                        MODEST_ACCOUNT_EMAIL, 
1179                                        email, 
1180                                        FALSE /* not server account */);
1181 }
1182
1183 gboolean 
1184 modest_account_mgr_account_is_multimailbox (ModestAccountMgr *mgr,
1185                                             const gchar *account_name, 
1186                                             ModestProtocol **mmb_protocol)
1187 {
1188         gchar *transport_account;
1189         gboolean result = FALSE;
1190
1191         if (mmb_protocol)
1192                 *mmb_protocol = NULL;
1193
1194         transport_account = modest_account_mgr_get_server_account_name (mgr,
1195                                                                         account_name,
1196                                                                         TNY_ACCOUNT_TYPE_TRANSPORT);
1197         if (transport_account) {
1198                 gchar *proto;
1199                 ModestProtocolRegistry *registry;
1200
1201                 registry = modest_runtime_get_protocol_registry ();
1202
1203                 proto = modest_account_mgr_get_string (mgr, transport_account, 
1204                                                        MODEST_ACCOUNT_PROTO, TRUE);
1205                 if (proto != NULL) {
1206                         ModestProtocol *protocol = 
1207                                 modest_protocol_registry_get_protocol_by_name (registry,
1208                                                                                MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
1209                                                                                proto);
1210                         if (protocol &&
1211                             modest_protocol_registry_protocol_type_has_tag 
1212                             (registry,
1213                              modest_protocol_get_type_id (protocol),
1214                              MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS)) {
1215                                 if (mmb_protocol)
1216                                         *mmb_protocol = protocol;
1217                                 result = TRUE;
1218                         }
1219                         
1220                 }
1221         }
1222
1223         return result;
1224 }
1225
1226 gchar *
1227 modest_account_mgr_get_signature_from_recipient (ModestAccountMgr *mgr, 
1228                                                  const gchar *current_recipient, 
1229                                                  gboolean *has_signature)
1230 {
1231         gchar *result = NULL;
1232         gchar *mailbox = NULL;
1233         gchar *account_name;
1234         ModestProtocol *protocol = NULL;
1235
1236         *has_signature = FALSE;
1237
1238         account_name = modest_utils_get_account_name_from_recipient (current_recipient, &mailbox);
1239         if (modest_account_mgr_account_is_multimailbox (mgr, account_name, &protocol)) {
1240                 if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
1241                         result = modest_account_protocol_get_signature (MODEST_ACCOUNT_PROTOCOL (protocol),
1242                                                                         account_name, mailbox, 
1243                                                                         has_signature);
1244                 }
1245         }
1246
1247         if (result == NULL) {
1248                 result = modest_account_mgr_get_signature (mgr, 
1249                                                            account_name, has_signature);
1250         }
1251         return result;
1252 }
1253