aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/empathy-account-manager.c146
-rw-r--r--libempathy/empathy-account-settings.c123
-rw-r--r--libempathy/empathy-account-settings.h6
-rw-r--r--libempathy/empathy-account.c59
-rw-r--r--libempathy/empathy-account.h7
-rw-r--r--libempathy/empathy-connection-managers.c12
-rw-r--r--libempathy/empathy-connection-managers.h2
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);