1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
31 #include <modest-marshal.h>
32 #include <modest-account-mgr.h>
33 #include <modest-account-mgr-priv.h>
34 #include <modest-account-mgr-helpers.h>
36 /* 'private'/'protected' functions */
37 static void modest_account_mgr_class_init (ModestAccountMgrClass * klass);
38 static void modest_account_mgr_init (ModestAccountMgr * obj);
39 static void modest_account_mgr_finalize (GObject * obj);
40 static void modest_account_mgr_base_init (gpointer g_class);
44 ACCOUNT_INSERTED_SIGNAL,
45 ACCOUNT_CHANGED_SIGNAL,
46 ACCOUNT_REMOVED_SIGNAL,
52 static GObjectClass *parent_class = NULL;
53 static guint signals[LAST_SIGNAL] = {0};
55 /* /\* We signal key changes in batches, every X seconds: *\/ */
57 /* on_timeout_notify_changes (gpointer data) */
59 /* ModestAccountMgr *self = MODEST_ACCOUNT_MGR (data); */
60 /* ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self); */
62 /* /\* TODO: Also store the account names, and notify one list for each account, */
63 /* * if anything uses the account names. *\/ */
65 /* if (priv->changed_conf_keys) { */
66 /* gchar *default_account = */
67 /* modest_account_mgr_get_default_account (self); */
69 /* /\* printf ("DEBUG: %s: priv->changed_conf_key length=%d\n", */
70 /* __FUNCTION__, g_slist_length (priv->changed_conf_keys)); *\/ */
71 /* g_signal_emit (G_OBJECT(self), signals[ACCOUNT_CHANGED_SIGNAL], 0, */
72 /* default_account, priv->changed_conf_keys, FALSE); */
74 /* g_free (default_account); */
76 /* g_slist_foreach (priv->changed_conf_keys, (GFunc) g_free, NULL); */
77 /* g_slist_free (priv->changed_conf_keys); */
78 /* priv->changed_conf_keys = NULL; */
81 /* return TRUE; /\* Call this again later. *\/ */
85 on_key_change (ModestConf *conf, const gchar *key, ModestConfEvent event,
86 ModestConfNotificationId id, gpointer user_data)
88 ModestAccountMgr *self = MODEST_ACCOUNT_MGR (user_data);
89 gboolean is_account_key;
90 gboolean is_server_account;
91 gchar* account = NULL;
93 /* there is only one not-really-account key which will still emit
94 * a signal: a change in MODEST_CONF_DEFAULT_ACCOUNT */
95 if (key && strcmp (key, MODEST_CONF_DEFAULT_ACCOUNT) == 0) {
96 /* Get the default account instead. */
97 gchar *default_account = modest_account_mgr_get_default_account (self);
98 if (!default_account) {
99 g_warning ("BUG: cannot find default account");
102 g_signal_emit (G_OBJECT(self), signals[ACCOUNT_CHANGED_SIGNAL], 0,
103 default_account, key, FALSE);
104 g_free(default_account);
109 is_account_key = FALSE;
110 is_server_account = FALSE;
111 account = _modest_account_mgr_account_from_key (key, &is_account_key,
114 /* if this is not an account-related key change, ignore */
118 /* account was removed. Do not emit an account removed signal
119 because it was already being done in the remove_account
120 method. Do not notify also the removal of the server
121 account keys for the same reason */
122 if ((is_account_key || is_server_account) &&
123 event == MODEST_CONF_EVENT_KEY_UNSET) {
128 /* is this account enabled? */
129 gboolean enabled = FALSE;
130 if (is_server_account)
133 enabled = modest_account_mgr_get_enabled (self, account);
135 /* Notify is server account was changed, default account was changed
136 * or when enabled/disabled changes:
139 g_str_has_suffix (key, MODEST_ACCOUNT_ENABLED) ||
140 strcmp (key, MODEST_CONF_DEFAULT_ACCOUNT) == 0) {
141 g_signal_emit (G_OBJECT(self), signals[ACCOUNT_CHANGED_SIGNAL], 0,
142 account, key, is_server_account);
143 /* Store the key for later notification in our timeout callback.
144 * Notifying for every key change would cause unnecessary work: */
151 modest_account_mgr_get_type (void)
153 static GType my_type = 0;
156 static const GTypeInfo my_info = {
157 sizeof (ModestAccountMgrClass),
158 modest_account_mgr_base_init, /* base init */
159 NULL, /* base finalize */
160 (GClassInitFunc) modest_account_mgr_class_init,
161 NULL, /* class finalize */
162 NULL, /* class data */
163 sizeof (ModestAccountMgr),
165 (GInstanceInitFunc) modest_account_mgr_init,
169 my_type = g_type_register_static (G_TYPE_OBJECT,
177 modest_account_mgr_base_init (gpointer g_class)
179 static gboolean modest_account_mgr_initialized = FALSE;
181 if (!modest_account_mgr_initialized) {
182 /* signal definitions */
183 signals[ACCOUNT_INSERTED_SIGNAL] =
184 g_signal_new ("account_inserted",
185 MODEST_TYPE_ACCOUNT_MGR,
187 G_STRUCT_OFFSET(ModestAccountMgrClass,account_inserted),
189 g_cclosure_marshal_VOID__STRING,
190 G_TYPE_NONE, 1, G_TYPE_STRING);
192 signals[ACCOUNT_REMOVED_SIGNAL] =
193 g_signal_new ("account_removed",
194 MODEST_TYPE_ACCOUNT_MGR,
196 G_STRUCT_OFFSET(ModestAccountMgrClass,account_removed),
198 g_cclosure_marshal_VOID__STRING,
199 G_TYPE_NONE, 1, G_TYPE_STRING);
201 signals[ACCOUNT_CHANGED_SIGNAL] =
202 g_signal_new ("account_changed",
203 MODEST_TYPE_ACCOUNT_MGR,
205 G_STRUCT_OFFSET(ModestAccountMgrClass,account_changed),
207 modest_marshal_VOID__STRING_STRING_BOOLEAN,
208 G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
210 signals[ACCOUNT_BUSY_SIGNAL] =
211 g_signal_new ("account_busy_changed",
212 MODEST_TYPE_ACCOUNT_MGR,
214 G_STRUCT_OFFSET(ModestAccountMgrClass,account_busy_changed),
216 modest_marshal_VOID__STRING_BOOLEAN,
217 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN);
219 modest_account_mgr_initialized = TRUE;
224 modest_account_mgr_class_init (ModestAccountMgrClass * klass)
226 GObjectClass *gobject_class;
227 gobject_class = (GObjectClass *) klass;
229 parent_class = g_type_class_peek_parent (klass);
230 gobject_class->finalize = modest_account_mgr_finalize;
232 g_type_class_add_private (gobject_class,
233 sizeof (ModestAccountMgrPrivate));
238 modest_account_mgr_init (ModestAccountMgr * obj)
240 ModestAccountMgrPrivate *priv =
241 MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
243 priv->modest_conf = NULL;
244 priv->busy_accounts = NULL;
246 priv->notification_id_accounts = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free);
250 modest_account_mgr_finalize (GObject * obj)
252 ModestAccountMgrPrivate *priv =
253 MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
255 if (priv->notification_id_accounts) {
256 /* TODO: forget dirs */
258 g_hash_table_destroy (priv->notification_id_accounts);
261 if (priv->key_changed_handler_uid) {
262 g_signal_handler_disconnect (priv->modest_conf,
263 priv->key_changed_handler_uid);
264 priv->key_changed_handler_uid = 0;
267 if (priv->modest_conf) {
268 g_object_unref (G_OBJECT(priv->modest_conf));
269 priv->modest_conf = NULL;
272 /* if (priv->timeout) */
273 /* g_source_remove (priv->timeout); */
275 /* if (priv->changed_conf_keys) { */
276 /* g_slist_foreach (priv->changed_conf_keys, (GFunc) g_free, NULL); */
277 /* g_slist_free (priv->changed_conf_keys); */
280 G_OBJECT_CLASS(parent_class)->finalize (obj);
285 modest_account_mgr_new (ModestConf *conf)
288 ModestAccountMgrPrivate *priv;
290 g_return_val_if_fail (conf, NULL);
292 obj = G_OBJECT (g_object_new (MODEST_TYPE_ACCOUNT_MGR, NULL));
293 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
295 g_object_ref (G_OBJECT(conf));
296 priv->modest_conf = conf;
298 priv->key_changed_handler_uid =
299 g_signal_connect (G_OBJECT (conf), "key_changed",
300 G_CALLBACK (on_key_change),
303 return MODEST_ACCOUNT_MGR (obj);
308 null_means_empty (const gchar * str)
310 return str ? str : "";
315 modest_account_mgr_add_account (ModestAccountMgr *self,
317 const gchar *store_account,
318 const gchar *transport_account,
321 ModestAccountMgrPrivate *priv;
324 gchar *default_account;
327 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
328 g_return_val_if_fail (name, FALSE);
329 g_return_val_if_fail (strchr(name, '/') == NULL, FALSE);
331 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
334 * we create the account by adding an account 'dir', with the name <name>,
335 * and in that the 'display_name' string key
337 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_DISPLAY_NAME, FALSE);
338 if (modest_account_mgr_account_exists (self, key, FALSE)) {
339 g_printerr ("modest: account already exists\n");
344 ok = modest_conf_set_string (priv->modest_conf, key, name, &err);
347 g_printerr ("modest: cannot set display name\n");
349 g_printerr ("modest: Error adding account conf: %s\n", err->message);
356 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_STORE_ACCOUNT, FALSE);
357 ok = modest_conf_set_string (priv->modest_conf, key, store_account, &err);
360 g_printerr ("modest: failed to set store account '%s'\n",
363 g_printerr ("modest: Error adding store account conf: %s\n", err->message);
370 if (transport_account) {
371 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
373 ok = modest_conf_set_string (priv->modest_conf, key, transport_account, &err);
376 g_printerr ("modest: failed to set transport account '%s'\n",
379 g_printerr ("modest: Error adding transport account conf: %s\n", err->message);
386 /* Make sure that leave-messages-on-server is enabled by default,
387 * as per the UI spec, though it is only meaningful for accounts using POP.
388 * (possibly this gconf key should be under the server account): */
389 modest_account_mgr_set_bool (self, name,
390 MODEST_ACCOUNT_LEAVE_ON_SERVER, TRUE, FALSE /* not server account */);
393 modest_account_mgr_set_enabled (self, name, enabled);
395 /* Notify the observers */
396 g_signal_emit (self, signals[ACCOUNT_INSERTED_SIGNAL], 0, name);
398 /* if no default account has been defined yet, do so now */
399 default_account = modest_account_mgr_get_default_account (self);
400 if (!default_account)
401 modest_account_mgr_set_default_account (self, name);
402 g_free (default_account);
409 modest_account_mgr_add_server_account (ModestAccountMgr * self,
410 const gchar * name, const gchar *hostname,
412 const gchar * username, const gchar * password,
413 ModestTransportStoreProtocol proto,
414 ModestConnectionProtocol security,
415 ModestAuthProtocol auth)
417 ModestAccountMgrPrivate *priv;
422 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
423 g_return_val_if_fail (name, FALSE);
424 g_return_val_if_fail (strchr(name, '/') == NULL, FALSE);
426 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
429 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_HOSTNAME, TRUE);
430 if (modest_conf_key_exists (priv->modest_conf, key, &err)) {
431 g_printerr ("modest: server account '%s' already exists\n", name);
438 modest_conf_set_string (priv->modest_conf, key, null_means_empty(hostname), &err);
440 g_printerr ("modest: failed to set %s: %s\n", key, err->message);
449 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_USERNAME, TRUE);
450 ok = modest_conf_set_string (priv->modest_conf, key, null_means_empty (username), &err);
452 g_printerr ("modest: failed to set %s: %s\n", key, err->message);
462 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_PASSWORD, TRUE);
463 ok = modest_conf_set_string (priv->modest_conf, key, null_means_empty (password), &err);
465 g_printerr ("modest: failed to set %s: %s\n", key, err->message);
474 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_PROTO, TRUE);
475 ok = modest_conf_set_string (priv->modest_conf, key,
476 modest_protocol_info_get_transport_store_protocol_name(proto),
479 g_printerr ("modest: failed to set %s: %s\n", key, err->message);
489 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_PORT, TRUE);
490 ok = modest_conf_set_int (priv->modest_conf, key, portnumber, &err);
492 g_printerr ("modest: failed to set %s: %s\n", key, err->message);
502 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_AUTH_MECH, TRUE);
503 ok = modest_conf_set_string (priv->modest_conf, key,
504 modest_protocol_info_get_auth_protocol_name (auth),
507 g_printerr ("modest: failed to set %s: %s\n", key, err->message);
515 /* Add the security settings: */
516 modest_server_account_set_security (self, name, security);
520 g_printerr ("modest: failed to add server account\n");
527 /** modest_account_mgr_add_server_account_uri:
528 * Only used for mbox and maildir accounts.
531 modest_account_mgr_add_server_account_uri (ModestAccountMgr * self,
532 const gchar *name, ModestTransportStoreProtocol proto,
535 ModestAccountMgrPrivate *priv;
539 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
540 g_return_val_if_fail (name, FALSE);
541 g_return_val_if_fail (strchr(name, '/') == NULL, FALSE);
542 g_return_val_if_fail (uri, FALSE);
544 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
548 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_PROTO, TRUE);
549 ok = modest_conf_set_string (priv->modest_conf, key,
550 modest_protocol_info_get_transport_store_protocol_name(proto),
555 g_printerr ("modest: failed to set proto\n");
560 key = _modest_account_mgr_get_account_keyname (name, MODEST_ACCOUNT_URI, TRUE);
561 ok = modest_conf_set_string (priv->modest_conf, key, uri, NULL);
565 g_printerr ("modest: failed to set uri\n");
572 * Utility function used by modest_account_mgr_remove_account
575 real_remove_account (ModestConf *conf,
576 const gchar *acc_name,
577 gboolean server_account)
582 key = _modest_account_mgr_get_account_keyname (acc_name, NULL, server_account);
583 modest_conf_remove_key (conf, key, &err);
587 g_printerr ("modest: error removing key: %s\n", err->message);
593 modest_account_mgr_remove_account (ModestAccountMgr * self,
596 ModestAccountMgrPrivate *priv;
597 gchar *default_account_name, *store_acc_name, *transport_acc_name;
598 gboolean default_account_deleted;
600 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
601 g_return_val_if_fail (name, FALSE);
603 if (!modest_account_mgr_account_exists (self, name, FALSE)) {
604 g_printerr ("modest: %s: account '%s' does not exist\n", __FUNCTION__, name);
608 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
609 default_account_deleted = FALSE;
611 /* If this was the default, then remove that setting: */
612 default_account_name = modest_account_mgr_get_default_account (self);
613 if (default_account_name && (strcmp (default_account_name, name) == 0)) {
614 modest_account_mgr_unset_default_account (self);
615 default_account_deleted = TRUE;
617 g_free (default_account_name);
619 /* Delete transport and store accounts */
620 store_acc_name = modest_account_mgr_get_string (self, name,
621 MODEST_ACCOUNT_STORE_ACCOUNT, FALSE);
623 real_remove_account (priv->modest_conf, store_acc_name, TRUE);
625 transport_acc_name = modest_account_mgr_get_string (self, name,
626 MODEST_ACCOUNT_TRANSPORT_ACCOUNT, FALSE);
627 if (transport_acc_name)
628 real_remove_account (priv->modest_conf, transport_acc_name, TRUE);
630 /* Remove the modest account */
631 real_remove_account (priv->modest_conf, name, FALSE);
633 if (default_account_deleted) {
634 /* pick another one as the new default account. We do
635 this *after* deleting the keys, because otherwise a
636 call to account_names will retrieve also the
638 modest_account_mgr_set_first_account_as_default (self);
641 /* Notify the observers. We do this *after* deleting
642 the keys, because otherwise a call to account_names
643 will retrieve also the deleted account */
644 g_signal_emit (G_OBJECT(self), signals[ACCOUNT_REMOVED_SIGNAL], 0, name);
651 /* strip the first /n/ character from each element
652 * caller must make sure all elements are strings with
653 * length >= n, and also that data can be freed.
657 strip_prefix_from_elements (GSList * lst, guint n)
660 memmove (lst->data, lst->data + n,
661 strlen(lst->data) - n + 1);
668 modest_account_mgr_account_names (ModestAccountMgr * self, gboolean only_enabled)
671 ModestAccountMgrPrivate *priv;
674 const size_t prefix_len = strlen (MODEST_ACCOUNT_NAMESPACE "/");
676 g_return_val_if_fail (self, NULL);
678 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
679 accounts = modest_conf_list_subkeys (priv->modest_conf,
680 MODEST_ACCOUNT_NAMESPACE, &err);
683 g_printerr ("modest: failed to get subkeys (%s): %s\n",
684 MODEST_ACCOUNT_NAMESPACE, err->message);
686 return NULL; /* assume accounts did not get value when err is set...*/
689 strip_prefix_from_elements (accounts, prefix_len);
691 GSList *result = NULL;
693 /* Unescape the keys to get the account names: */
694 GSList *iter = accounts;
699 const gchar* account_name_key = (const gchar*)iter->data;
700 gchar* unescaped_name = account_name_key ?
701 modest_conf_key_unescape (account_name_key)
706 if (unescaped_name &&
707 !modest_account_mgr_get_enabled (self, unescaped_name)) {
712 /* Ignore modest accounts whose server accounts don't exist:
713 * (We could be getting this list while the account is being deleted,
714 * while the child server accounts have already been deleted, but the
715 * parent modest account already exists.
718 gchar* server_account_name = modest_account_mgr_get_string (self, account_name_key, MODEST_ACCOUNT_STORE_ACCOUNT,
720 if (server_account_name) {
721 if (!modest_account_mgr_account_exists (self, server_account_name, TRUE))
723 g_free (server_account_name);
728 gchar* server_account_name = modest_account_mgr_get_string (self, account_name_key, MODEST_ACCOUNT_TRANSPORT_ACCOUNT,
730 if (server_account_name) {
731 if (!modest_account_mgr_account_exists (self, server_account_name, TRUE))
733 g_free (server_account_name);
738 result = g_slist_append (result, unescaped_name);
740 g_free (unescaped_name);
745 iter = g_slist_next (iter);
749 /* we already freed the strings in the loop */
750 g_slist_free (accounts);
758 modest_account_mgr_free_account_names (GSList *account_names)
760 g_slist_foreach (account_names, (GFunc)g_free, NULL);
761 g_slist_free (account_names);
767 modest_account_mgr_get_string (ModestAccountMgr *self, const gchar *name,
768 const gchar *key, gboolean server_account) {
770 ModestAccountMgrPrivate *priv;
776 g_return_val_if_fail (self, NULL);
777 g_return_val_if_fail (name, NULL);
778 g_return_val_if_fail (key, NULL);
780 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
782 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
783 retval = modest_conf_get_string (priv->modest_conf, keyname, &err);
785 g_printerr ("modest: error getting string '%s': %s\n", keyname, err->message);
796 modest_account_mgr_get_password (ModestAccountMgr *self, const gchar *name,
797 const gchar *key, gboolean server_account)
799 return modest_account_mgr_get_string (self, name, key, server_account);
806 modest_account_mgr_get_int (ModestAccountMgr *self, const gchar *name, const gchar *key,
807 gboolean server_account)
809 ModestAccountMgrPrivate *priv;
815 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), -1);
816 g_return_val_if_fail (name, -1);
817 g_return_val_if_fail (key, -1);
819 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
821 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
822 retval = modest_conf_get_int (priv->modest_conf, keyname, &err);
824 g_printerr ("modest: error getting int '%s': %s\n", keyname, err->message);
836 modest_account_mgr_get_bool (ModestAccountMgr * self, const gchar *account,
837 const gchar * key, gboolean server_account)
839 ModestAccountMgrPrivate *priv;
845 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
846 g_return_val_if_fail (account, FALSE);
847 g_return_val_if_fail (key, FALSE);
849 keyname = _modest_account_mgr_get_account_keyname (account, key, server_account);
851 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
852 retval = modest_conf_get_bool (priv->modest_conf, keyname, &err);
854 g_printerr ("modest: error getting bool '%s': %s\n", keyname, err->message);
866 modest_account_mgr_get_list (ModestAccountMgr *self, const gchar *name,
867 const gchar *key, ModestConfValueType list_type,
868 gboolean server_account)
870 ModestAccountMgrPrivate *priv;
876 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), NULL);
877 g_return_val_if_fail (name, NULL);
878 g_return_val_if_fail (key, NULL);
880 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
882 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
883 retval = modest_conf_get_list (priv->modest_conf, keyname, list_type, &err);
885 g_printerr ("modest: error getting list '%s': %s\n", keyname,
897 modest_account_mgr_set_string (ModestAccountMgr * self, const gchar * name,
898 const gchar * key, const gchar * val, gboolean server_account)
900 ModestAccountMgrPrivate *priv;
906 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
907 g_return_val_if_fail (name, FALSE);
908 g_return_val_if_fail (key, FALSE);
910 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
912 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
914 retval = modest_conf_set_string (priv->modest_conf, keyname, val, &err);
916 g_printerr ("modest: error setting string '%s': %s\n", keyname, err->message);
926 modest_account_mgr_set_password (ModestAccountMgr * self, const gchar * name,
927 const gchar * key, const gchar * val, gboolean server_account)
929 return modest_account_mgr_set_password (self, name, key, val, server_account);
935 modest_account_mgr_set_int (ModestAccountMgr * self, const gchar * name,
936 const gchar * key, int val, gboolean server_account)
938 ModestAccountMgrPrivate *priv;
944 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
945 g_return_val_if_fail (name, FALSE);
946 g_return_val_if_fail (key, FALSE);
948 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
950 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
952 retval = modest_conf_set_int (priv->modest_conf, keyname, val, &err);
954 g_printerr ("modest: error setting int '%s': %s\n", keyname, err->message);
965 modest_account_mgr_set_bool (ModestAccountMgr * self, const gchar * name,
966 const gchar * key, gboolean val, gboolean server_account)
968 ModestAccountMgrPrivate *priv;
974 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
975 g_return_val_if_fail (name, FALSE);
976 g_return_val_if_fail (key, FALSE);
978 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
980 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
982 retval = modest_conf_set_bool (priv->modest_conf, keyname, val, &err);
984 g_printerr ("modest: error setting bool '%s': %s\n", keyname, err->message);
994 modest_account_mgr_set_list (ModestAccountMgr *self,
998 ModestConfValueType list_type,
999 gboolean server_account)
1001 ModestAccountMgrPrivate *priv;
1006 g_return_val_if_fail (self, FALSE);
1007 g_return_val_if_fail (name, FALSE);
1008 g_return_val_if_fail (key, FALSE);
1009 g_return_val_if_fail (val, FALSE);
1011 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
1013 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
1014 retval = modest_conf_set_list (priv->modest_conf, keyname, val, list_type, &err);
1016 g_printerr ("modest: error setting list '%s': %s\n", keyname, err->message);
1026 modest_account_mgr_account_exists (ModestAccountMgr * self, const gchar * name,
1027 gboolean server_account)
1029 ModestAccountMgrPrivate *priv;
1035 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
1036 g_return_val_if_fail (name, FALSE);
1038 keyname = _modest_account_mgr_get_account_keyname (name, NULL, server_account);
1039 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
1040 retval = modest_conf_key_exists (priv->modest_conf, keyname, &err);
1042 g_printerr ("modest: error determining existance of '%s': %s\n", keyname,
1052 modest_account_mgr_account_with_display_name_exists (ModestAccountMgr *self, const gchar *display_name)
1054 GSList *account_names = NULL;
1055 GSList *cursor = NULL;
1057 cursor = account_names = modest_account_mgr_account_names (self,
1058 TRUE /* enabled accounts, because disabled accounts are not user visible. */);
1060 gboolean found = FALSE;
1062 /* Look at each non-server account to check their display names; */
1064 const gchar * account_name = (gchar*)cursor->data;
1066 ModestAccountData *account_data = modest_account_mgr_get_account_data (self, account_name);
1067 if (!account_data) {
1068 g_printerr ("modest: failed to get account data for %s\n", account_name);
1072 if(account_data->display_name && (strcmp (account_data->display_name, display_name) == 0)) {
1077 modest_account_mgr_free_account_data (self, account_data);
1078 cursor = cursor->next;
1080 modest_account_mgr_free_account_names (account_names);
1081 account_names = NULL;
1090 modest_account_mgr_unset (ModestAccountMgr *self, const gchar *name,
1091 const gchar *key, gboolean server_account)
1093 ModestAccountMgrPrivate *priv;
1099 g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
1100 g_return_val_if_fail (name, FALSE);
1101 g_return_val_if_fail (key, FALSE);
1103 keyname = _modest_account_mgr_get_account_keyname (name, key, server_account);
1105 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
1106 retval = modest_conf_remove_key (priv->modest_conf, keyname, &err);
1108 g_printerr ("modest: error unsetting'%s': %s\n", keyname,
1118 _modest_account_mgr_account_from_key (const gchar *key, gboolean *is_account_key, gboolean *is_server_account)
1120 /* Initialize input parameters: */
1122 *is_account_key = FALSE;
1124 if (is_server_account)
1125 *is_server_account = FALSE;
1127 const gchar* account_ns = MODEST_ACCOUNT_NAMESPACE "/";
1128 const gchar* server_account_ns = MODEST_SERVER_ACCOUNT_NAMESPACE "/";
1130 gchar *account = NULL;
1132 /* determine whether it's an account or a server account,
1133 * based on the prefix */
1134 if (g_str_has_prefix (key, account_ns)) {
1136 if (is_server_account)
1137 *is_server_account = FALSE;
1139 account = g_strdup (key + strlen (account_ns));
1141 } else if (g_str_has_prefix (key, server_account_ns)) {
1143 if (is_server_account)
1144 *is_server_account = TRUE;
1146 account = g_strdup (key + strlen (server_account_ns));
1150 /* if there are any slashes left in the key, it's not
1151 * the toplevel entry for an account
1153 cursor = strstr(account, "/");
1155 if (is_account_key && cursor)
1156 *is_account_key = TRUE;
1158 /* put a NULL where the first slash was */
1163 /* The key is an escaped string, so unescape it to get the actual account name: */
1164 gchar *unescaped_name = modest_conf_key_unescape (account);
1166 return unescaped_name;
1173 /* must be freed by caller */
1175 _modest_account_mgr_get_account_keyname (const gchar *account_name, const gchar * name, gboolean server_account)
1177 gchar *retval = NULL;
1179 gchar *namespace = server_account ? MODEST_SERVER_ACCOUNT_NAMESPACE : MODEST_ACCOUNT_NAMESPACE;
1182 return g_strdup (namespace);
1184 /* Always escape the conf keys, so that it is acceptable to gconf: */
1185 gchar *escaped_account_name = account_name ? modest_conf_key_escape (account_name) : NULL;
1186 gchar *escaped_name = name ? modest_conf_key_escape (name) : NULL;
1188 if (escaped_account_name && escaped_name)
1189 retval = g_strconcat (namespace, "/", escaped_account_name, "/", escaped_name, NULL);
1190 else if (escaped_account_name)
1191 retval = g_strconcat (namespace, "/", escaped_account_name, NULL);
1194 if (!modest_conf_key_is_valid (retval)) {
1195 g_warning ("%s: Generated conf key was invalid: %s", __FUNCTION__, retval);
1200 g_free (escaped_name);
1201 g_free (escaped_account_name);
1207 modest_account_mgr_has_accounts (ModestAccountMgr* self, gboolean enabled)
1209 /* Check that at least one account exists: */
1210 GSList *account_names = modest_account_mgr_account_names (self,
1212 gboolean accounts_exist = account_names != NULL;
1214 modest_account_mgr_free_account_names (account_names);
1215 account_names = NULL;
1217 return accounts_exist;
1221 compare_account_name(gconstpointer a, gconstpointer b)
1223 const gchar* account_name = (const gchar*) a;
1224 const gchar* account_name2 = (const gchar*) b;
1225 return strcmp(account_name, account_name2);
1229 modest_account_mgr_set_account_busy(ModestAccountMgr* self, const gchar* account_name,
1232 ModestAccountMgrPrivate* priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
1235 GSList *account_names = modest_account_mgr_account_names (self,
1238 g_slist_find_custom(account_names, account_name, (GCompareFunc) compare_account_name);
1239 if (account && !modest_account_mgr_account_is_busy(self, account_name))
1241 priv->busy_accounts = g_slist_append(priv->busy_accounts, g_strdup(account_name));
1242 g_signal_emit_by_name(G_OBJECT(self), "account-busy-changed", account_name, TRUE);
1244 modest_account_mgr_free_account_names (account_names);
1245 account_names = NULL;
1248 g_slist_find_custom(priv->busy_accounts, account_name, (GCompareFunc) compare_account_name);
1251 g_free(account->data);
1252 priv->busy_accounts = g_slist_delete_link(priv->busy_accounts, account);
1253 g_signal_emit_by_name(G_OBJECT(self), "account-busy-changed", account_name, FALSE);
1259 modest_account_mgr_account_is_busy(ModestAccountMgr* self, const gchar* account_name)
1261 ModestAccountMgrPrivate* priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
1262 return (g_slist_find_custom(priv->busy_accounts, account_name, (GCompareFunc) compare_account_name)