1 /* modest-account-mgr.c */
3 /* insert (c)/licensing information) */
6 #include "modest-marshal.h"
7 #include "modest-account-keys.h"
8 #include "modest-account-mgr.h"
10 /* 'private'/'protected' functions */
11 static void modest_account_mgr_class_init (ModestAccountMgrClass * klass);
12 static void modest_account_mgr_init (ModestAccountMgr * obj);
13 static void modest_account_mgr_finalize (GObject * obj);
15 static gchar *get_account_keyname (const gchar * accname, const gchar * name);
16 static gchar *get_server_account_keyname (const gchar * accname,
21 ACCOUNT_CHANGE_SIGNAL,
22 ACCOUNT_REMOVE_SIGNAL,
27 typedef struct _ModestAccountMgrPrivate ModestAccountMgrPrivate;
28 struct _ModestAccountMgrPrivate {
29 ModestConf *modest_conf;
30 GSList *current_accounts;
33 #define MODEST_ACCOUNT_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
34 MODEST_TYPE_ACCOUNT_MGR, \
35 ModestAccountMgrPrivate))
37 static GObjectClass *parent_class = NULL;
39 static guint signals[LAST_SIGNAL] = {0};
43 delete_account_from_list (GSList *list, const gchar *name)
45 GSList *iter, *result;
50 if (!strcmp (name, iter->data)) {
51 result = g_slist_delete_link (list, iter);
55 iter = g_slist_next (iter);
61 find_account_in_list (GSList *list, const gchar *name)
63 GSList *iter, *result;
68 if (!strcmp (name, iter->data)) {
73 iter = g_slist_next (iter);
78 /* Map configuration changes to account changes.
79 * Doing this here makes sure all changes are available and external changes
80 * are covered as well. */
83 modest_account_mgr_check_change (ModestConf *conf, const gchar *key,
84 const gchar *new_value, gpointer user_data)
86 ModestAccountMgr *amgr = user_data;
87 ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (amgr);
89 if ((strlen (key) > strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/")
90 && g_str_has_prefix (key, MODEST_SERVER_ACCOUNT_NAMESPACE))) {
91 gchar *subkey = g_strdup(key + strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/"));
93 if (! strstr (subkey, "/")) { /* no more '/' means an account was modified */
95 priv->current_accounts =
96 delete_account_from_list (priv->current_accounts, subkey);
98 g_signal_emit (amgr, signals[ACCOUNT_REMOVE_SIGNAL], 0, subkey);
104 param = strstr (subkey, "/");
108 /* that's the second case for a new account */
109 if (!find_account_in_list (priv->current_accounts, subkey) && strstr (param, MODEST_ACCOUNT_PROTO)) {
110 priv->current_accounts =
111 g_slist_prepend (priv->current_accounts, g_strdup (subkey));
112 g_signal_emit (amgr, signals[ACCOUNT_ADD_SIGNAL], 0, subkey);
115 g_signal_emit (amgr, signals[ACCOUNT_CHANGE_SIGNAL], 0, subkey, param, new_value);
124 modest_account_mgr_get_type (void)
126 static GType my_type = 0;
129 static const GTypeInfo my_info = {
130 sizeof (ModestAccountMgrClass),
131 NULL, /* base init */
132 NULL, /* base finalize */
133 (GClassInitFunc) modest_account_mgr_class_init,
134 NULL, /* class finalize */
135 NULL, /* class data */
136 sizeof (ModestAccountMgr),
138 (GInstanceInitFunc) modest_account_mgr_init,
141 my_type = g_type_register_static (G_TYPE_OBJECT,
149 modest_account_mgr_class_init (ModestAccountMgrClass * klass)
151 GObjectClass *gobject_class;
152 GType paramtypes[3] = {G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER};
154 gobject_class = (GObjectClass *) klass;
156 parent_class = g_type_class_peek_parent (klass);
157 gobject_class->finalize = modest_account_mgr_finalize;
159 g_type_class_add_private (gobject_class,
160 sizeof (ModestAccountMgrPrivate));
162 /* signal definitions */
163 signals[ACCOUNT_ADD_SIGNAL] =
164 g_signal_newv ("account-add",
165 G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
167 g_cclosure_marshal_VOID__POINTER,
168 G_TYPE_NONE, 1, paramtypes);
170 signals[ACCOUNT_REMOVE_SIGNAL] =
171 g_signal_newv ("account-remove",
172 G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
174 g_cclosure_marshal_VOID__POINTER,
175 G_TYPE_NONE, 1, paramtypes);
176 signals[ACCOUNT_CHANGE_SIGNAL] =
177 g_signal_newv ("account-change",
178 G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
180 modest_marshal_VOID__POINTER_POINTER_POINTER,
181 G_TYPE_NONE, 3, paramtypes);
186 modest_account_mgr_init (ModestAccountMgr * obj)
188 ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
190 priv->modest_conf = NULL;
194 modest_account_mgr_finalize (GObject * obj)
196 ModestAccountMgr *self = MODEST_ACCOUNT_MGR (obj);
197 ModestAccountMgrPrivate *priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
199 if (priv->modest_conf) {
200 g_object_unref (G_OBJECT(priv->modest_conf));
201 priv->modest_conf = NULL;
206 modest_account_mgr_new (ModestConf * conf)
209 ModestAccountMgrPrivate *priv;
211 g_return_val_if_fail (conf, NULL);
213 obj = G_OBJECT (g_object_new (MODEST_TYPE_ACCOUNT_MGR, NULL));
214 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (obj);
217 * increase the ref count on the modest_conf. Normally, the
218 * ModestConf should outlive the ModestAccountMgr though
220 g_object_ref (G_OBJECT (priv->modest_conf = conf));
222 priv->current_accounts = modest_account_mgr_account_names (MODEST_ACCOUNT_MGR(obj), NULL);
224 g_signal_connect (G_OBJECT (conf), "key-changed",
225 G_CALLBACK (modest_account_mgr_check_change), obj);
231 modest_account_mgr_add_account (ModestAccountMgr * self, const gchar * name,
232 const gchar * store_account,
233 const gchar * transport_account,
236 ModestAccountMgrPrivate *priv;
239 g_return_val_if_fail (self, FALSE);
240 g_return_val_if_fail (name, FALSE);
242 if (modest_account_mgr_account_exists (self, name, err)) {
243 g_warning ("account already exists");
247 * we create the account by adding an account 'dir', with the name <name>,
248 * and in that the 'display_name' string key
250 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
252 key = get_account_keyname (name, MODEST_ACCOUNT_DISPLAY_NAME);
253 modest_conf_set_string (priv->modest_conf, key, name, err);
257 key = get_account_keyname (name,
258 MODEST_ACCOUNT_STORE_ACCOUNT);
259 modest_conf_set_string (priv->modest_conf, key, store_account,
264 if (transport_account) {
265 key = get_account_keyname (name,
266 MODEST_ACCOUNT_TRANSPORT_ACCOUNT);
267 modest_conf_set_string (priv->modest_conf, key,
268 transport_account, err);
272 return TRUE; /* TODO: error handling */
277 modest_account_mgr_remove_account (ModestAccountMgr * self,
278 const gchar * name, GError ** err)
280 ModestAccountMgrPrivate *priv;
284 g_return_val_if_fail (self, FALSE);
285 g_return_val_if_fail (name, FALSE);
287 if (!modest_account_mgr_account_exists (self, name, err)) {
288 g_warning ("account doest not exist");
292 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
293 key = get_account_keyname (name, NULL);
295 retval = modest_conf_remove_key (priv->modest_conf, key, NULL);
303 null_means_empty (const gchar * str)
305 return str ? str : "";
310 modest_account_mgr_add_server_account (ModestAccountMgr * self,
312 const gchar * hostname,
313 const gchar * username,
314 const gchar * password,
317 ModestAccountMgrPrivate *priv;
320 g_return_val_if_fail (self, FALSE);
321 g_return_val_if_fail (name, FALSE);
323 /* TODO: check already exists */
325 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
326 acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
329 if (modest_conf_key_exists (priv->modest_conf, acckey, NULL)) {
330 g_warning ("server account %s already exists", name);
336 key = g_strconcat (acckey, "/", MODEST_ACCOUNT_HOSTNAME, NULL);
337 modest_conf_set_string (priv->modest_conf, key,
338 null_means_empty (hostname), NULL);
342 key = g_strconcat (acckey, "/", MODEST_ACCOUNT_USERNAME, NULL);
343 modest_conf_set_string (priv->modest_conf, key,
344 null_means_empty (username), NULL);
349 key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PASSWORD,
351 modest_conf_set_string (priv->modest_conf, key,
352 null_means_empty (password), NULL);
357 key = g_strconcat (acckey, "/", MODEST_ACCOUNT_PROTO, NULL);
358 modest_conf_set_string (priv->modest_conf, key,
359 null_means_empty (proto), NULL);
363 return TRUE; /* FIXME: better error checking */
367 modest_account_mgr_remove_server_account (ModestAccountMgr * self,
368 const gchar * name, GError ** err)
370 ModestAccountMgrPrivate *priv;
374 g_return_val_if_fail (self, FALSE);
375 g_return_val_if_fail (name, FALSE);
377 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
379 acckey = g_strconcat (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
382 if (!modest_conf_key_exists (priv->modest_conf, acckey, NULL)) {
383 g_warning ("server account %s does not exist exist", name);
388 retval = modest_conf_remove_key (priv->modest_conf, acckey, NULL);
395 /* strip the first /n/ character from each element */
396 /* caller must make sure all elements are strings with
397 * length >= n, and also that data can be freed.
400 strip_prefix_from_elements (GSList * lst, guint n)
402 GSList *cursor = lst;
405 gchar *str = (gchar *) cursor->data;
407 cursor->data = g_strdup (str + n);
409 cursor = cursor->next;
416 modest_account_mgr_server_account_names (ModestAccountMgr * self,
417 const gchar * account_name,
418 ModestProtoType type,
420 gboolean only_enabled)
424 ModestAccountMgrPrivate *priv;
425 const size_t prefix_len =
426 strlen (MODEST_SERVER_ACCOUNT_NAMESPACE "/");
428 g_return_val_if_fail (self, NULL);
430 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
431 accounts = modest_conf_list_subkeys (priv->modest_conf,
432 MODEST_SERVER_ACCOUNT_NAMESPACE,
435 /* no restrictions, return everything */
436 if (type == MODEST_PROTO_TYPE_ANY && !proto)
437 return strip_prefix_from_elements (accounts, prefix_len);
439 /* otherwise, filter out the none-matching ones */
442 gchar *keyspace, *proto_key, *acc_proto;
444 keyspace = (gchar *) cursor->data;
446 g_strconcat (keyspace, "/", MODEST_ACCOUNT_PROTO,
449 modest_conf_get_string (priv->modest_conf, proto_key,
453 if ((!acc_proto) || /* proto not defined? */
454 (type != MODEST_PROTO_TYPE_ANY && /* proto type ... */
455 modest_proto_type (acc_proto) != type) || /* ... matches? */
456 (proto && strcmp (proto, acc_proto) != 0)) { /* proto matches? */
457 /* no match: remove from the list */
458 GSList *nxt = cursor->next;
461 accounts = g_slist_delete_link (accounts, cursor);
464 cursor = cursor->next;
467 return strip_prefix_from_elements (accounts, prefix_len);
472 modest_account_mgr_account_names (ModestAccountMgr * self, GError ** err)
475 ModestAccountMgrPrivate *priv;
476 const size_t prefix_len = strlen (MODEST_ACCOUNT_NAMESPACE "/");
479 g_return_val_if_fail (self, NULL);
481 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
483 accounts = modest_conf_list_subkeys (priv->modest_conf,
484 MODEST_ACCOUNT_NAMESPACE, err);
485 return strip_prefix_from_elements (accounts, prefix_len);
490 get_account_string (ModestAccountMgr * self, const gchar * name,
491 const gchar * key, gboolean server_account, GError ** err) {
493 ModestAccountMgrPrivate *priv;
498 g_return_val_if_fail (self, NULL);
499 g_return_val_if_fail (name, NULL);
500 g_return_val_if_fail (key, NULL);
503 keyname = get_server_account_keyname (name, key);
505 keyname = get_account_keyname (name, key);
507 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
508 retval = modest_conf_get_string (priv->modest_conf, keyname, err);
516 modest_account_mgr_get_server_account_string (ModestAccountMgr * self,
521 return get_account_string (self, name, key, TRUE, err);
526 modest_account_mgr_get_account_string (ModestAccountMgr * self,
527 const gchar * name, const gchar * key,
530 return get_account_string (self, name, key, FALSE, err);
535 get_account_int (ModestAccountMgr * self, const gchar * name,
536 const gchar * key, gboolean server_account, GError ** err)
538 ModestAccountMgrPrivate *priv;
543 g_return_val_if_fail (self, -1);
544 g_return_val_if_fail (name, -1);
545 g_return_val_if_fail (key, -1);
548 keyname = get_server_account_keyname (name, key);
550 keyname = get_account_keyname (name, key);
552 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
553 retval = modest_conf_get_int (priv->modest_conf, keyname, err);
561 modest_account_mgr_get_server_account_int (ModestAccountMgr * self,
563 const gchar * key, GError ** err)
565 return get_account_int (self, name, key, TRUE, err);
570 modest_account_mgr_get_account_int (ModestAccountMgr * self,
571 const gchar * name, const gchar * key,
574 return get_account_int (self, name, key, FALSE, err);
579 get_account_bool (ModestAccountMgr * self, const gchar * name,
580 const gchar * key, gboolean server_account, GError ** err)
582 ModestAccountMgrPrivate *priv;
587 g_return_val_if_fail (self, FALSE);
588 g_return_val_if_fail (name, FALSE);
589 g_return_val_if_fail (key, FALSE);
592 keyname = get_server_account_keyname (name, key);
594 keyname = get_account_keyname (name, key);
596 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
597 retval = modest_conf_get_bool (priv->modest_conf, keyname, err);
605 modest_account_mgr_get_server_account_bool (ModestAccountMgr * self,
607 const gchar * key, GError ** err)
609 return get_account_bool (self, name, key, TRUE, err);
614 modest_account_mgr_get_account_bool (ModestAccountMgr * self,
615 const gchar * name, const gchar * key,
618 return get_account_bool (self, name, key, FALSE, err);
623 set_account_string (ModestAccountMgr * self, const gchar * name,
624 const gchar * key, const gchar * val,
625 gboolean server_account, GError ** err)
627 ModestAccountMgrPrivate *priv;
632 g_return_val_if_fail (self, FALSE);
633 g_return_val_if_fail (name, FALSE);
634 g_return_val_if_fail (key, FALSE);
637 keyname = get_server_account_keyname (name, key);
639 keyname = get_account_keyname (name, key);
641 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
643 retval = modest_conf_set_string (priv->modest_conf, keyname, val,
652 modest_account_mgr_set_server_account_string (ModestAccountMgr * self,
658 return set_account_string (self, name, key, val, TRUE, err);
663 modest_account_mgr_set_account_string (ModestAccountMgr * self,
664 const gchar * name, const gchar * key,
665 const gchar * val, GError ** err)
667 return set_account_string (self, name, key, val, FALSE, err);
672 set_account_int (ModestAccountMgr * self, const gchar * name,
673 const gchar * key, gboolean server_account, int val,
676 ModestAccountMgrPrivate *priv;
681 g_return_val_if_fail (self, FALSE);
682 g_return_val_if_fail (name, FALSE);
683 g_return_val_if_fail (key, FALSE);
686 keyname = get_server_account_keyname (name, key);
688 keyname = get_account_keyname (name, key);
690 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
692 retval = modest_conf_set_int (priv->modest_conf, keyname, val, err);
700 modest_account_mgr_set_server_account_int (ModestAccountMgr * self,
702 const gchar * key, int val,
705 return set_account_int (self, name, key, val, TRUE, err);
710 modest_account_mgr_set_account_int (ModestAccountMgr * self,
711 const gchar * name, const gchar * key,
712 int val, GError ** err)
714 return set_account_int (self, name, key, val, FALSE, err);
719 set_account_bool (ModestAccountMgr * self, const gchar * name,
720 const gchar * key, gboolean server_account, gboolean val,
723 ModestAccountMgrPrivate *priv;
728 g_return_val_if_fail (self, FALSE);
729 g_return_val_if_fail (name, FALSE);
730 g_return_val_if_fail (key, FALSE);
733 keyname = get_server_account_keyname (name, key);
735 keyname = get_account_keyname (name, key);
737 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
739 retval = modest_conf_set_bool (priv->modest_conf, keyname, val, err);
747 modest_account_mgr_set_server_account_bool (ModestAccountMgr * self,
749 const gchar * key, gboolean val,
752 return set_account_bool (self, name, key, val, TRUE, err);
757 modest_account_mgr_set_account_bool (ModestAccountMgr * self,
758 const gchar * name, const gchar * key,
759 gboolean val, GError ** err)
761 return set_account_bool (self, name, key, val, FALSE, err);
766 account_exists (ModestAccountMgr * self, const gchar * name,
767 gboolean server_account, GError ** err)
769 ModestAccountMgrPrivate *priv;
774 g_return_val_if_fail (self, FALSE);
775 g_return_val_if_fail (name, FALSE);
778 keyname = get_server_account_keyname (name, NULL);
780 keyname = get_account_keyname (name, NULL);
782 priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
783 retval = modest_conf_key_exists (priv->modest_conf, keyname, err);
791 modest_account_mgr_server_account_exists (ModestAccountMgr * self,
792 const gchar * name, GError ** err)
794 return account_exists (self, name, TRUE, err);
799 modest_account_mgr_account_exists (ModestAccountMgr * self,
800 const gchar * name, GError ** err)
802 return account_exists (self, name, FALSE, err);
806 /* must be freed by caller */
808 get_account_keyname (const gchar * accname, const gchar * name)
812 (MODEST_ACCOUNT_NAMESPACE, "/",
813 accname, "/", name, NULL);
816 (MODEST_ACCOUNT_NAMESPACE, "/", accname, NULL);
820 /* must be freed by caller */
822 get_server_account_keyname (const gchar * accname, const gchar * name)
826 (MODEST_SERVER_ACCOUNT_NAMESPACE, "/",
827 accname, "/", name, NULL);
830 (MODEST_SERVER_ACCOUNT_NAMESPACE, "/", accname, NULL);