+ return retval;
+}
+
+static const gchar *
+_modest_account_mgr_get_account_keyname_cached (ModestAccountMgrPrivate *priv,
+ const gchar* account_name,
+ const gchar *name,
+ gboolean is_server)
+{
+ GHashTable *hash = is_server ? priv->server_account_key_hash : priv->account_key_hash;
+ GHashTable *account_hash;
+ gchar *key = NULL;
+ const gchar *search_name;
+
+ if (!account_name)
+ return is_server ? MODEST_SERVER_ACCOUNT_NAMESPACE : MODEST_ACCOUNT_NAMESPACE;
+
+ search_name = name ? name : "<dummy>";
+
+ account_hash = g_hash_table_lookup (hash, account_name);
+ if (!account_hash) { /* no hash for this account yet? create it */
+ account_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ key = _modest_account_mgr_get_account_keyname (account_name, name, is_server);
+ g_hash_table_insert (account_hash, g_strdup(search_name), key);
+ g_hash_table_insert (hash, g_strdup(account_name), account_hash);
+ return key;
+ }
+
+ /* we have a hash for this account, but do we have the key? */
+ key = g_hash_table_lookup (account_hash, search_name);
+ if (!key) {
+ key = _modest_account_mgr_get_account_keyname (account_name, name, is_server);
+ g_hash_table_insert (account_hash, g_strdup(search_name), key);
+ }
+
+ return key;
+}
+
+
+gboolean
+modest_account_mgr_has_accounts (ModestAccountMgr* self, gboolean enabled)
+{
+ ModestAccountMgrPrivate* priv;
+ GSList *account_names;
+ gboolean accounts_exist;
+
+ g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
+
+ priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
+
+ if (enabled && priv->has_enabled_accounts)
+ return TRUE;
+ else if (priv->has_accounts)
+ return TRUE;
+
+ /* Check that at least one account exists: */
+ account_names = modest_account_mgr_account_names (self,enabled);
+ accounts_exist = account_names != NULL;
+ modest_account_mgr_free_account_names (account_names);
+ account_names = NULL;
+
+ /* cache it. */
+ if (enabled)
+ priv->has_enabled_accounts = accounts_exist;
+ else
+ priv->has_accounts = accounts_exist;
+
+ return accounts_exist;
+}
+
+static int
+compare_account_name(gconstpointer a, gconstpointer b)
+{
+ const gchar* account_name = (const gchar*) a;
+ const gchar* account_name2 = (const gchar*) b;
+ return strcmp(account_name, account_name2);
+}
+
+void
+modest_account_mgr_set_account_busy(ModestAccountMgr* self,
+ const gchar* account_name,
+ gboolean busy)
+{
+ ModestAccountMgrPrivate* priv;
+
+ g_return_if_fail (MODEST_IS_ACCOUNT_MGR(self));
+ g_return_if_fail (account_name);
+
+ priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
+ if (busy) {
+ GSList *account_names = modest_account_mgr_account_names (self, TRUE);
+ GSList* account = g_slist_find_custom(account_names, account_name,
+ (GCompareFunc) compare_account_name);
+
+ if (account && !modest_account_mgr_account_is_busy(self, account_name)) {
+ priv->busy_accounts = g_slist_append(priv->busy_accounts, g_strdup(account_name));
+ g_signal_emit (G_OBJECT(self), signals[ACCOUNT_BUSY_SIGNAL],
+ 0, account_name, TRUE);
+ }
+ modest_account_mgr_free_account_names (account_names);
+ account_names = NULL;
+ } else {
+ GSList* account =
+ g_slist_find_custom(priv->busy_accounts, account_name, (GCompareFunc) compare_account_name);
+
+ if (account) {
+ g_free(account->data);
+ priv->busy_accounts = g_slist_delete_link(priv->busy_accounts, account);
+ g_signal_emit (G_OBJECT(self), signals[ACCOUNT_BUSY_SIGNAL],
+ 0, account_name, FALSE);
+ }
+ }
+}
+
+gboolean
+modest_account_mgr_account_is_busy (ModestAccountMgr* self, const gchar* account_name)
+{
+ ModestAccountMgrPrivate* priv;
+
+ g_return_val_if_fail (MODEST_IS_ACCOUNT_MGR(self), FALSE);
+ g_return_val_if_fail (account_name, FALSE);
+
+ priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
+
+ return (g_slist_find_custom(priv->busy_accounts, account_name, (GCompareFunc) compare_account_name)
+ != NULL);
+}
+
+void
+modest_account_mgr_notify_account_update (ModestAccountMgr* self,
+ const gchar *server_account_name)
+{
+ ModestTransportStoreProtocol proto;
+ ModestAccountMgrPrivate* priv;
+ gchar *proto_name = NULL;
+
+ g_return_if_fail (self);
+ g_return_if_fail (server_account_name);
+
+ priv = MODEST_ACCOUNT_MGR_GET_PRIVATE (self);
+
+ /* Get protocol */
+ proto_name = modest_account_mgr_get_string (self, server_account_name,
+ MODEST_ACCOUNT_PROTO, TRUE);
+ if (!proto_name) {
+ g_free (proto_name);
+ g_return_if_reached ();
+ }
+ proto = modest_protocol_info_get_transport_store_protocol (proto_name);
+ g_free (proto_name);
+
+ /* there is some update in the account, so we can't
+ * be sure about whether there are still enabled accounts...
+ */
+ priv->has_enabled_accounts = FALSE;
+ priv->has_accounts = FALSE;
+
+ /* Emit "update-account" */
+ g_signal_emit (G_OBJECT(self),
+ signals[ACCOUNT_CHANGED_SIGNAL], 0,
+ server_account_name,
+ (modest_protocol_info_protocol_is_store (proto)) ?
+ TNY_ACCOUNT_TYPE_STORE :
+ TNY_ACCOUNT_TYPE_TRANSPORT);
+}
+
+
+gboolean
+modest_account_mgr_set_default_account (ModestAccountMgr *self, const gchar* account)
+{
+ ModestConf *conf;
+ gboolean retval;
+
+ g_return_val_if_fail (self, FALSE);
+ g_return_val_if_fail (account, FALSE);
+ g_return_val_if_fail (modest_account_mgr_account_exists (self, account, FALSE),
+ FALSE);
+
+ conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
+
+ /* Change the default account and notify */
+ retval = modest_conf_set_string (conf, MODEST_CONF_DEFAULT_ACCOUNT, account, NULL);
+ if (retval)
+ g_signal_emit (G_OBJECT(self), signals[DEFAULT_ACCOUNT_CHANGED_SIGNAL], 0);
+
+ return retval;
+}
+
+
+gchar*
+modest_account_mgr_get_default_account (ModestAccountMgr *self)
+{
+ gchar *account;
+ ModestConf *conf;
+ GError *err = NULL;
+
+ g_return_val_if_fail (self, NULL);
+
+ conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
+ account = modest_conf_get_string (conf, MODEST_CONF_DEFAULT_ACCOUNT, &err);
+
+ if (err) {
+ g_printerr ("modest: failed to get '%s': %s\n",
+ MODEST_CONF_DEFAULT_ACCOUNT, err->message);
+ g_error_free (err);
+ g_free (account);
+ return NULL;
+ }
+
+ /* sanity check */
+ if (account && !modest_account_mgr_account_exists (self, account, FALSE)) {
+ g_printerr ("modest: default account does not exist\n");
+ g_free (account);
+ return NULL;
+ }
+
+ return account;
+}
+
+static gboolean
+modest_account_mgr_unset_default_account (ModestAccountMgr *self)
+{
+ ModestConf *conf;
+ gboolean retval;
+
+ g_return_val_if_fail (self, FALSE);
+
+ conf = MODEST_ACCOUNT_MGR_GET_PRIVATE (self)->modest_conf;
+
+ retval = modest_conf_remove_key (conf, MODEST_CONF_DEFAULT_ACCOUNT, NULL /* err */);
+
+ if (retval)
+ g_signal_emit (G_OBJECT(self), signals[DEFAULT_ACCOUNT_CHANGED_SIGNAL], 0);