diff options
Diffstat (limited to 'libempathy')
-rw-r--r-- | libempathy/empathy-account-manager.c | 146 | ||||
-rw-r--r-- | libempathy/empathy-account-settings.c | 123 | ||||
-rw-r--r-- | libempathy/empathy-account-settings.h | 6 | ||||
-rw-r--r-- | libempathy/empathy-account.c | 59 | ||||
-rw-r--r-- | libempathy/empathy-account.h | 7 | ||||
-rw-r--r-- | libempathy/empathy-connection-managers.c | 12 | ||||
-rw-r--r-- | libempathy/empathy-connection-managers.h | 2 |
7 files changed, 313 insertions, 42 deletions
diff --git a/libempathy/empathy-account-manager.c b/libempathy/empathy-account-manager.c index 727eb7eaf..18eff355f 100644 --- a/libempathy/empathy-account-manager.c +++ b/libempathy/empathy-account-manager.c @@ -55,6 +55,15 @@ typedef struct { TpConnectionPresenceType global_presence; gchar *global_status; gchar *global_status_message; + + /* desired global presence, could be different + * from the actual global one. + */ + TpConnectionPresenceType desired_presence; + gchar *desired_status; + gchar *desired_status_message; + + GHashTable *create_results; } EmpathyAccountManagerPriv; enum { @@ -97,8 +106,16 @@ emp_account_enabled_cb (EmpathyAccount *account, GParamSpec *spec, gpointer manager) { + EmpathyAccountManagerPriv *priv = GET_PRIV (manager); + if (empathy_account_is_enabled (account)) - g_signal_emit (manager, signals[ACCOUNT_ENABLED], 0, account); + { + g_signal_emit (manager, signals[ACCOUNT_ENABLED], 0, account); + + /* set the desired global presence on the account */ + empathy_account_request_presence (account, priv->desired_presence, + priv->desired_status, priv->desired_status_message); + } else g_signal_emit (manager, signals[ACCOUNT_DISABLED], 0, account); } @@ -264,10 +281,14 @@ empathy_account_manager_check_ready (EmpathyAccountManager *manager) } static void -emp_account_ready_cb (GObject *obj, GParamSpec *spec, gpointer user_data) +account_manager_account_ready_cb (GObject *obj, + GParamSpec *spec, + gpointer user_data) { EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (user_data); + EmpathyAccountManagerPriv *priv = GET_PRIV (manager); EmpathyAccount *account = EMPATHY_ACCOUNT (obj); + GSimpleAsyncResult *result; gboolean ready; g_object_get (account, "ready", &ready, NULL); @@ -275,6 +296,19 @@ emp_account_ready_cb (GObject *obj, GParamSpec *spec, gpointer user_data) if (!ready) return; + /* see if there's any pending callbacks for this account */ + result = g_hash_table_lookup (priv->create_results, account); + if (result != NULL) + { + g_simple_async_result_set_op_res_gpointer ( + G_SIMPLE_ASYNC_RESULT (result), account, NULL); + + g_simple_async_result_complete (result); + + g_hash_table_remove (priv->create_results, account); + g_object_unref (result); + } + g_signal_emit (manager, signals[ACCOUNT_CREATED], 0, account); g_signal_connect (account, "notify::connection", @@ -310,7 +344,7 @@ account_manager_add_account (EmpathyAccountManager *manager, g_hash_table_insert (priv->accounts, g_strdup (path), account); g_signal_connect (account, "notify::ready", - G_CALLBACK (emp_account_ready_cb), manager); + G_CALLBACK (account_manager_account_ready_cb), manager); return account; } @@ -406,6 +440,8 @@ empathy_account_manager_init (EmpathyAccountManager *manager) priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + priv->create_results = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->dbus = tp_dbus_daemon_dup (NULL); tp_dbus_daemon_watch_name_owner (priv->dbus, @@ -433,8 +469,15 @@ do_finalize (GObject *obj) EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (obj); EmpathyAccountManagerPriv *priv = GET_PRIV (manager); + g_hash_table_destroy (priv->create_results); g_hash_table_destroy (priv->accounts); + g_free (priv->global_status); + g_free (priv->global_status_message); + + g_free (priv->desired_status); + g_free (priv->desired_status_message); + G_OBJECT_CLASS (empathy_account_manager_parent_class)->finalize (obj); } @@ -449,12 +492,35 @@ do_dispose (GObject *obj) priv->dispose_run = TRUE; + if (priv->create_results != NULL && + g_hash_table_size (priv->create_results) > 0) + { + /* the manager is being destroyed while there are account creation + * processes pending; this should not happen, but emit the callbacks + * with an error anyway. + */ + GHashTableIter iter; + GSimpleAsyncResult *result; + + g_hash_table_iter_init (&iter, priv->create_results); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &result)) + { + g_simple_async_result_set_error (result, G_IO_ERROR, + G_IO_ERROR_CANCELLED, "The account manager was disposed while " + "creating the account"); + g_simple_async_result_complete (result); + g_object_unref (result); + } + } + tp_dbus_daemon_cancel_name_owner_watch (priv->dbus, TP_ACCOUNT_MANAGER_BUS_NAME, account_manager_name_owner_cb, manager); - if (priv->dbus == NULL) - g_object_unref (priv->dbus); - priv->dbus = NULL; + if (priv->dbus != NULL) + { + g_object_unref (priv->dbus); + priv->dbus = NULL; + } G_OBJECT_CLASS (empathy_account_manager_parent_class)->dispose (obj); } @@ -767,8 +833,6 @@ empathy_account_manager_request_global_presence ( const gchar *status, const gchar *message) { - /* FIXME should remember requested presence and set it on new accounts - as well */ EmpathyAccountManagerPriv *priv = GET_PRIV (manager); GHashTableIter iter; gpointer value; @@ -784,6 +848,23 @@ empathy_account_manager_request_global_presence ( if (ready) empathy_account_request_presence (account, type, status, message); } + + /* save the requested global presence, to use it in case we create + * new accounts. + */ + priv->desired_presence = type; + + if (tp_strdiff (priv->desired_status, status)) + { + g_free (priv->desired_status); + priv->desired_status = g_strdup (status); + } + + if (tp_strdiff (priv->desired_status_message, message)) + { + g_free (priv->desired_status_message); + priv->desired_status_message = g_strdup (message); + } } TpConnectionPresenceType @@ -803,22 +884,6 @@ empathy_account_manager_get_global_presence ( } static void -empathy_account_manager_created_ready_cb (EmpathyAccount *account, - GParamSpec *spec, gpointer user_data) -{ - GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); - - if (!empathy_account_is_ready (account)) - return; - - g_simple_async_result_set_op_res_gpointer ( - G_SIMPLE_ASYNC_RESULT (result), account, NULL); - - g_simple_async_result_complete (result); - g_object_unref (G_OBJECT (result)); -} - -static void empathy_account_manager_created_cb (TpAccountManager *proxy, const gchar *account_path, const GError *error, @@ -826,23 +891,23 @@ empathy_account_manager_created_cb (TpAccountManager *proxy, GObject *weak_object) { EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (weak_object); - GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); + EmpathyAccountManagerPriv *priv = GET_PRIV (manager); + GSimpleAsyncResult *my_res = user_data; EmpathyAccount *account; if (error != NULL) { - g_simple_async_result_set_from_error (result, (GError *) error); - g_simple_async_result_complete (result); - g_object_unref (G_OBJECT (result)); + g_simple_async_result_set_from_error (my_res, + (GError *) error); + g_simple_async_result_complete (my_res); + g_object_unref (my_res); + return; } account = account_manager_add_account (manager, account_path); - if (empathy_account_is_ready (account)) - empathy_account_manager_created_ready_cb (account, NULL, result); - else - g_signal_connect (account, "notify::ready", - G_CALLBACK (empathy_account_manager_created_ready_cb), result); + + g_hash_table_insert (priv->create_results, account, my_res); } void @@ -856,8 +921,11 @@ empathy_account_manager_create_account_async (EmpathyAccountManager *manager, gpointer user_data) { EmpathyAccountManagerPriv *priv = GET_PRIV (manager); - GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (manager), - callback, user_data, empathy_account_manager_create_account_finish); + GSimpleAsyncResult *res; + + res = g_simple_async_result_new + (G_OBJECT (manager), callback, user_data, + empathy_account_manager_create_account_finish); tp_cli_account_manager_call_create_account (priv->tp_manager, -1, @@ -867,7 +935,7 @@ empathy_account_manager_create_account_async (EmpathyAccountManager *manager, parameters, properties, empathy_account_manager_created_cb, - result, + res, NULL, G_OBJECT (manager)); } @@ -876,6 +944,8 @@ EmpathyAccount * empathy_account_manager_create_account_finish ( EmpathyAccountManager *manager, GAsyncResult *result, GError **error) { + EmpathyAccount *retval; + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) return NULL; @@ -883,7 +953,9 @@ empathy_account_manager_create_account_finish ( g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), empathy_account_manager_create_account_finish), NULL); - return EMPATHY_ACCOUNT (g_simple_async_result_get_op_res_gpointer ( + retval = EMPATHY_ACCOUNT (g_simple_async_result_get_op_res_gpointer ( G_SIMPLE_ASYNC_RESULT (result))); + + return retval; } diff --git a/libempathy/empathy-account-settings.c b/libempathy/empathy-account-settings.c index 0b92ec1b1..df99ea1c5 100644 --- a/libempathy/empathy-account-settings.c +++ b/libempathy/empathy-account-settings.c @@ -72,6 +72,7 @@ struct _EmpathyAccountSettingsPriv GHashTable *parameters; GArray *unset_parameters; + GArray *required_params; gulong managers_ready_id; gulong account_ready_id; @@ -360,6 +361,23 @@ empathy_account_settings_check_readyness (EmpathyAccountSettings *self) return; } + if (priv->required_params == NULL) + { + TpConnectionManagerParam *cur; + char *val; + + priv->required_params = g_array_new (TRUE, FALSE, sizeof (gchar *)); + + for (cur = priv->tp_protocol->params; cur->name != NULL; cur++) + { + if (tp_connection_manager_param_is_required (cur)) + { + val = g_strdup (cur->name); + g_array_append_val (priv->required_params, val); + } + } + } + g_object_ref (priv->manager); priv->ready = TRUE; @@ -430,13 +448,16 @@ empathy_account_settings_get_protocol (EmpathyAccountSettings *settings) return priv->protocol; } -const gchar * +gchar * empathy_account_settings_get_icon_name (EmpathyAccountSettings *settings) { EmpathyAccountSettingsPriv *priv = GET_PRIV (settings); if (priv->account != NULL) - return empathy_account_get_icon_name (priv->account); + return g_strdup (empathy_account_get_icon_name (priv->account)); + + if (priv->tp_protocol != NULL) + return g_strdup_printf ("im-%s", priv->tp_protocol->name); return NULL; } @@ -800,6 +821,26 @@ empathy_account_settings_set_boolean (EmpathyAccountSettings *settings, tp_asv_set_boolean (priv->parameters, param, value); } +static void +account_settings_display_name_set_cb (GObject *src, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + EmpathyAccount *account = EMPATHY_ACCOUNT (src); + GSimpleAsyncResult *set_result = user_data; + + empathy_account_set_display_name_finish (account, res, &error); + + if (error != NULL) + { + g_simple_async_result_set_from_error (set_result, error); + g_error_free (error); + } + + g_simple_async_result_complete (set_result); + g_object_unref (set_result); +} void empathy_account_settings_set_display_name_async ( @@ -808,6 +849,26 @@ empathy_account_settings_set_display_name_async ( GAsyncReadyCallback callback, gpointer user_data) { + EmpathyAccountSettingsPriv *priv = GET_PRIV (settings); + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (G_OBJECT (settings), + callback, user_data, empathy_account_settings_set_display_name_finish); + + if (priv->account == NULL) + { + if (priv->display_name != NULL) + g_free (priv->display_name); + + priv->display_name = g_strdup (name); + + g_simple_async_result_complete_in_idle (result); + + return; + } + + empathy_account_set_display_name_async (priv->account, name, + account_settings_display_name_set_cb, result); } gboolean @@ -816,6 +877,12 @@ empathy_account_settings_set_display_name_finish ( GAsyncResult *result, GError **error) { + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error)) + return FALSE; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (settings), empathy_account_settings_set_display_name_finish), FALSE); return TRUE; } @@ -965,3 +1032,55 @@ empathy_account_settings_apply_finish (EmpathyAccountSettings *settings, return TRUE; } + +gboolean +empathy_account_settings_has_account (EmpathyAccountSettings *settings, + EmpathyAccount *account) +{ + EmpathyAccountSettingsPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE); + g_return_val_if_fail (EMPATHY_IS_ACCOUNT (account), FALSE); + + priv = GET_PRIV (settings); + + return (account == priv->account); +} + +gboolean +empathy_account_settings_is_valid (EmpathyAccountSettings *settings) +{ + EmpathyAccountSettingsPriv *priv; + int idx; + gchar *current; + gboolean missed = FALSE; + + g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE); + + priv = GET_PRIV (settings); + + for (idx = 0; idx < priv->required_params->len; idx++) + { + current = g_array_index (priv->required_params, gchar *, idx); + + /* first, look if it's set in our own parameters */ + if (tp_asv_lookup (priv->parameters, current)) + continue; + + /* if we did not unset the parameter, look if it's in the account */ + if (priv->account != NULL && + !empathy_account_settings_is_unset (settings, current)) + { + const GHashTable *account_params; + + account_params = empathy_account_get_parameters (priv->account); + if (tp_asv_lookup (account_params, current)) + continue; + } + + missed = TRUE; + break; + } + + return !missed; +} diff --git a/libempathy/empathy-account-settings.h b/libempathy/empathy-account-settings.h index d9231a50a..8ae692212 100644 --- a/libempathy/empathy-account-settings.h +++ b/libempathy/empathy-account-settings.h @@ -77,6 +77,9 @@ const gchar *empathy_account_settings_get_protocol ( EmpathyAccount *empathy_account_settings_get_account ( EmpathyAccountSettings *settings); +gboolean empathy_account_settings_has_account ( + EmpathyAccountSettings *settings, EmpathyAccount *account); + TpConnectionManagerParam *empathy_account_settings_get_tp_params ( EmpathyAccountSettings *settings); @@ -124,7 +127,7 @@ void empathy_account_settings_set_uint64 (EmpathyAccountSettings *settings, void empathy_account_settings_set_boolean (EmpathyAccountSettings *settings, const gchar *param, gboolean value); -const gchar *empathy_account_settings_get_icon_name ( +gchar *empathy_account_settings_get_icon_name ( EmpathyAccountSettings *settings); const gchar *empathy_account_settings_get_display_name ( @@ -150,6 +153,7 @@ gboolean empathy_account_settings_apply_finish ( GAsyncResult *result, GError **error); +gboolean empathy_account_settings_is_valid (EmpathyAccountSettings *settings); G_END_DECLS diff --git a/libempathy/empathy-account.c b/libempathy/empathy-account.c index df948b69c..ffb6e6786 100644 --- a/libempathy/empathy-account.c +++ b/libempathy/empathy-account.c @@ -32,6 +32,8 @@ #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT #include <libempathy/empathy-debug.h> +#include <glib/gi18n-lib.h> + #include "empathy-account.h" #include "empathy-utils.h" #include "empathy-marshal.h" @@ -998,6 +1000,63 @@ empathy_account_update_settings_finish (EmpathyAccount *account, } static void +account_display_name_set_cb (TpProxy *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + GSimpleAsyncResult *result = user_data; + + if (error != NULL) + g_simple_async_result_set_from_error (result, (GError *) error); + + g_simple_async_result_complete (result); + g_object_unref (result); +} + +void +empathy_account_set_display_name_async (EmpathyAccount *account, + const char *display_name, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + GValue value = {0, }; + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (display_name == NULL) + { + g_simple_async_report_error_in_idle (G_OBJECT (account), + callback, user_data, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Can't set an empty display name")); + return; + } + + result = g_simple_async_result_new (G_OBJECT (account), callback, + user_data, empathy_account_set_display_name_finish); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, display_name); + + tp_cli_dbus_properties_call_set (priv->account, -1, TP_IFACE_ACCOUNT, + "DisplayName", &value, account_display_name_set_cb, result, NULL, + G_OBJECT (account)); +} + +gboolean +empathy_account_set_display_name_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error) || + !g_simple_async_result_is_valid (result, G_OBJECT (account), + empathy_account_set_display_name_finish)) + return FALSE; + + return TRUE; +} + +static void empathy_account_remove_cb (TpAccount *proxy, const GError *error, gpointer user_data, diff --git a/libempathy/empathy-account.h b/libempathy/empathy-account.h index 00daa46ee..67939d748 100644 --- a/libempathy/empathy-account.h +++ b/libempathy/empathy-account.h @@ -84,8 +84,11 @@ void empathy_account_remove_async (EmpathyAccount *account, gboolean empathy_account_remove_finish (EmpathyAccount *account, GAsyncResult *result, GError **error); -void empathy_account_set_display_name (EmpathyAccount *account, - const gchar *display_name); +void empathy_account_set_display_name_async (EmpathyAccount *account, + const gchar *display_name, GAsyncReadyCallback callback, + gpointer user_data); +gboolean empathy_account_set_display_name_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error); EmpathyAccount *empathy_account_new (TpDBusDaemon *bus_daemon, const gchar *unique_name); diff --git a/libempathy/empathy-connection-managers.c b/libempathy/empathy-connection-managers.c index 587a463a8..82699d3d6 100644 --- a/libempathy/empathy-connection-managers.c +++ b/libempathy/empathy-connection-managers.c @@ -295,3 +295,15 @@ empathy_connection_managers_get_cm (EmpathyConnectionManagers *managers, return NULL; } + +guint +empathy_connection_managers_get_cms_num (EmpathyConnectionManagers *managers) +{ + EmpathyConnectionManagersPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_CONNECTION_MANAGERS (managers), 0); + + priv = GET_PRIV (managers); + + return g_list_length (priv->cms); +} diff --git a/libempathy/empathy-connection-managers.h b/libempathy/empathy-connection-managers.h index 0c4147951..17289d36d 100644 --- a/libempathy/empathy-connection-managers.h +++ b/libempathy/empathy-connection-managers.h @@ -66,6 +66,8 @@ void empathy_connection_managers_update (EmpathyConnectionManagers *managers); GList * empathy_connection_managers_get_cms ( EmpathyConnectionManagers *managers); +guint empathy_connection_managers_get_cms_num + (EmpathyConnectionManagers *managers); TpConnectionManager *empathy_connection_managers_get_cm ( EmpathyConnectionManagers *managers, const gchar *cm); |