2 * empathy-account-settings.c - Source for EmpathyAccountSettings
3 * Copyright (C) 2009 Collabora Ltd.
4 * @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <telepathy-glib/account-manager.h>
26 #include <telepathy-glib/util.h>
27 #include <telepathy-glib/interfaces.h>
28 #include <telepathy-glib/gtypes.h>
30 #include "empathy-account-settings.h"
31 #include "empathy-connection-managers.h"
32 #include "empathy-utils.h"
33 #include "empathy-idle.h"
35 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
36 #include <libempathy/empathy-debug.h>
38 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountSettings)
40 G_DEFINE_TYPE(EmpathyAccountSettings, empathy_account_settings, G_TYPE_OBJECT)
48 PROP_DISPLAY_NAME_OVERRIDDEN,
52 /* private structure */
53 typedef struct _EmpathyAccountSettingsPriv EmpathyAccountSettingsPriv;
55 struct _EmpathyAccountSettingsPriv
57 gboolean dispose_has_run;
58 EmpathyConnectionManagers *managers;
59 TpAccountManager *account_manager;
61 TpConnectionManager *manager;
62 TpProtocol *protocol_obj;
70 gboolean display_name_overridden;
73 /* Parameter name (gchar *) -> parameter value (GValue) */
74 GHashTable *parameters;
75 /* Keys are parameter names from the hash above (gchar *).
76 * Values are regular expresions that should match corresponding parameter
77 * values (GRegex *). Possible regexp patterns are defined in
78 * empathy-account-widget.c */
79 GHashTable *param_regexps;
80 GArray *unset_parameters;
81 GList *required_params;
83 gulong managers_ready_id;
84 gboolean preparing_protocol;
86 GSimpleAsyncResult *apply_result;
90 empathy_account_settings_init (EmpathyAccountSettings *obj)
92 EmpathyAccountSettingsPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE ((obj),
93 EMPATHY_TYPE_ACCOUNT_SETTINGS, EmpathyAccountSettingsPriv);
97 /* allocate any data required by the object here */
98 priv->managers = empathy_connection_managers_dup_singleton ();
99 priv->account_manager = tp_account_manager_dup ();
101 priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
102 g_free, (GDestroyNotify) tp_g_value_slice_free);
104 priv->param_regexps = g_hash_table_new_full (g_str_hash, g_str_equal,
105 g_free, (GDestroyNotify) g_regex_unref);
107 priv->unset_parameters = g_array_new (TRUE, FALSE, sizeof (gchar *));
109 priv->required_params = NULL;
112 static void empathy_account_settings_dispose (GObject *object);
113 static void empathy_account_settings_finalize (GObject *object);
114 static void empathy_account_settings_account_ready_cb (GObject *source_object,
115 GAsyncResult *result, gpointer user_data);
116 static void empathy_account_settings_managers_ready_cb (GObject *obj,
117 GParamSpec *pspec, gpointer user_data);
118 static void empathy_account_settings_check_readyness (
119 EmpathyAccountSettings *self);
122 empathy_account_settings_set_property (GObject *object,
127 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (object);
128 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
133 priv->account = g_value_dup_object (value);
136 priv->cm_name = g_value_dup_string (value);
139 priv->protocol = g_value_dup_string (value);
142 priv->service = g_value_dup_string (value);
144 case PROP_DISPLAY_NAME:
145 priv->display_name = g_value_dup_string (value);
147 case PROP_DISPLAY_NAME_OVERRIDDEN:
148 priv->display_name_overridden = g_value_get_boolean (value);
151 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
157 empathy_account_settings_get_property (GObject *object,
162 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (object);
163 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
168 g_value_set_object (value, priv->account);
171 g_value_set_string (value, priv->cm_name);
174 g_value_set_string (value, priv->protocol);
177 g_value_set_string (value, priv->service);
179 case PROP_DISPLAY_NAME:
180 g_value_set_string (value, priv->display_name);
182 case PROP_DISPLAY_NAME_OVERRIDDEN:
183 g_value_set_boolean (value, priv->display_name_overridden);
186 g_value_set_boolean (value, priv->ready);
189 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
195 empathy_account_settings_constructed (GObject *object)
197 EmpathyAccountSettings *self = EMPATHY_ACCOUNT_SETTINGS (object);
198 EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
200 if (priv->account != NULL)
202 g_free (priv->cm_name);
203 g_free (priv->protocol);
204 g_free (priv->service);
207 g_strdup (tp_account_get_connection_manager (priv->account));
209 g_strdup (tp_account_get_protocol (priv->account));
211 g_strdup (tp_account_get_service (priv->account));
212 priv->icon_name = g_strdup
213 (tp_account_get_icon_name (priv->account));
217 priv->icon_name = empathy_protocol_icon_name (priv->protocol);
220 g_assert (priv->cm_name != NULL && priv->protocol != NULL);
222 empathy_account_settings_check_readyness (self);
226 GQuark features[] = {
227 TP_ACCOUNT_FEATURE_CORE,
228 TP_ACCOUNT_FEATURE_STORAGE,
231 tp_proxy_prepare_async (priv->account, features,
232 empathy_account_settings_account_ready_cb, self);
233 tp_g_signal_connect_object (priv->managers, "notify::ready",
234 G_CALLBACK (empathy_account_settings_managers_ready_cb), object, 0);
238 empathy_account_settings_parent_class)->constructed != NULL)
240 empathy_account_settings_parent_class)->constructed (object);
245 empathy_account_settings_class_init (
246 EmpathyAccountSettingsClass *empathy_account_settings_class)
248 GObjectClass *object_class = G_OBJECT_CLASS (empathy_account_settings_class);
250 g_type_class_add_private (empathy_account_settings_class, sizeof
251 (EmpathyAccountSettingsPriv));
253 object_class->dispose = empathy_account_settings_dispose;
254 object_class->finalize = empathy_account_settings_finalize;
255 object_class->set_property = empathy_account_settings_set_property;
256 object_class->get_property = empathy_account_settings_get_property;
257 object_class->constructed = empathy_account_settings_constructed;
259 g_object_class_install_property (object_class, PROP_ACCOUNT,
260 g_param_spec_object ("account",
262 "The TpAccount backing these settings",
264 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
266 g_object_class_install_property (object_class, PROP_CM_NAME,
267 g_param_spec_string ("connection-manager",
268 "connection-manager",
269 "The name of the connection manager this account uses",
271 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
273 g_object_class_install_property (object_class, PROP_PROTOCOL,
274 g_param_spec_string ("protocol",
276 "The name of the protocol this account uses",
278 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
280 g_object_class_install_property (object_class, PROP_SERVICE,
281 g_param_spec_string ("service",
283 "The service of this account, or NULL",
285 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
287 g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
288 g_param_spec_string ("display-name",
290 "The display name account these settings belong to",
292 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
294 g_object_class_install_property (object_class, PROP_DISPLAY_NAME_OVERRIDDEN,
295 g_param_spec_boolean ("display-name-overridden",
296 "display-name-overridden",
297 "Whether the display name for this account has been manually "
300 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
302 g_object_class_install_property (object_class, PROP_READY,
303 g_param_spec_boolean ("ready",
305 "Whether this account is ready to be used",
307 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
311 empathy_account_settings_dispose (GObject *object)
313 EmpathyAccountSettings *self = EMPATHY_ACCOUNT_SETTINGS (object);
314 EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
316 if (priv->dispose_has_run)
319 priv->dispose_has_run = TRUE;
321 if (priv->managers_ready_id != 0)
322 g_signal_handler_disconnect (priv->managers, priv->managers_ready_id);
323 priv->managers_ready_id = 0;
325 if (priv->managers != NULL)
326 g_object_unref (priv->managers);
327 priv->managers = NULL;
329 if (priv->manager != NULL)
330 g_object_unref (priv->manager);
331 priv->manager = NULL;
333 if (priv->account_manager != NULL)
334 g_object_unref (priv->account_manager);
335 priv->account_manager = NULL;
337 if (priv->account != NULL)
338 g_object_unref (priv->account);
339 priv->account = NULL;
341 if (priv->protocol_obj != NULL)
342 g_object_unref (priv->protocol_obj);
343 priv->protocol_obj = NULL;
345 /* release any references held by the object here */
346 if (G_OBJECT_CLASS (empathy_account_settings_parent_class)->dispose)
347 G_OBJECT_CLASS (empathy_account_settings_parent_class)->dispose (object);
351 empathy_account_settings_free_unset_parameters (
352 EmpathyAccountSettings *settings)
354 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
357 for (i = 0 ; i < priv->unset_parameters->len; i++)
358 g_free (g_array_index (priv->unset_parameters, gchar *, i));
360 g_array_set_size (priv->unset_parameters, 0);
364 empathy_account_settings_finalize (GObject *object)
366 EmpathyAccountSettings *self = EMPATHY_ACCOUNT_SETTINGS (object);
367 EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
370 /* free any data held directly by the object here */
371 g_free (priv->cm_name);
372 g_free (priv->protocol);
373 g_free (priv->service);
374 g_free (priv->display_name);
375 g_free (priv->icon_name);
377 if (priv->required_params != NULL)
379 for (l = priv->required_params; l; l = l->next)
381 g_list_free (priv->required_params);
384 g_hash_table_destroy (priv->parameters);
385 g_hash_table_destroy (priv->param_regexps);
387 empathy_account_settings_free_unset_parameters (self);
388 g_array_free (priv->unset_parameters, TRUE);
390 G_OBJECT_CLASS (empathy_account_settings_parent_class)->finalize (object);
394 empathy_account_settings_protocol_obj_prepared_cb (GObject *source,
395 GAsyncResult *result,
398 EmpathyAccountSettings *self = user_data;
399 GError *error = NULL;
401 if (!tp_proxy_prepare_finish (source, result, &error))
403 DEBUG ("Failed to prepare protocol object: %s", error->message);
404 g_clear_error (&error);
408 empathy_account_settings_check_readyness (self);
412 empathy_account_settings_check_readyness (EmpathyAccountSettings *self)
414 EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
415 const TpConnectionManagerProtocol *tp_protocol;
416 GQuark features[] = { TP_PROTOCOL_FEATURE_CORE, 0 };
421 if (priv->account != NULL
422 && !tp_account_is_prepared (priv->account, TP_ACCOUNT_FEATURE_CORE))
425 if (!empathy_connection_managers_is_ready (priv->managers))
428 if (priv->manager == NULL)
430 priv->manager = empathy_connection_managers_get_cm (
431 priv->managers, priv->cm_name);
434 if (priv->manager == NULL)
437 g_object_ref (priv->manager);
439 if (priv->account != NULL)
441 g_free (priv->display_name);
443 g_strdup (tp_account_get_display_name (priv->account));
445 g_free (priv->icon_name);
447 g_strdup (tp_account_get_icon_name (priv->account));
450 tp_protocol = tp_connection_manager_get_protocol (priv->manager,
453 if (tp_protocol == NULL)
455 priv->manager = NULL;
459 if (priv->required_params == NULL)
461 TpConnectionManagerParam *cur;
463 for (cur = tp_protocol->params; cur->name != NULL; cur++)
465 if (tp_connection_manager_param_is_required (cur))
467 priv->required_params = g_list_append (priv->required_params,
468 g_strdup (cur->name));
473 if (priv->protocol_obj == NULL)
475 priv->protocol_obj = g_object_ref (
476 tp_connection_manager_get_protocol_object (priv->manager,
480 if (!tp_proxy_is_prepared (priv->protocol_obj, TP_PROTOCOL_FEATURE_CORE)
481 && !priv->preparing_protocol)
483 priv->preparing_protocol = TRUE;
484 tp_proxy_prepare_async (priv->protocol_obj, features,
485 empathy_account_settings_protocol_obj_prepared_cb, self);
490 g_object_notify (G_OBJECT (self), "ready");
494 empathy_account_settings_account_ready_cb (GObject *source_object,
495 GAsyncResult *result,
498 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (user_data);
499 TpAccount *account = TP_ACCOUNT (source_object);
500 GError *error = NULL;
502 if (!tp_proxy_prepare_finish (account, result, &error))
504 DEBUG ("Failed to prepare account: %s", error->message);
505 g_error_free (error);
509 empathy_account_settings_check_readyness (settings);
513 empathy_account_settings_managers_ready_cb (GObject *object,
517 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (user_data);
519 empathy_account_settings_check_readyness (settings);
522 EmpathyAccountSettings *
523 empathy_account_settings_new (const gchar *connection_manager,
524 const gchar *protocol,
525 const gchar *service,
526 const char *display_name)
528 return g_object_new (EMPATHY_TYPE_ACCOUNT_SETTINGS,
529 "connection-manager", connection_manager,
530 "protocol", protocol,
532 "display-name", display_name,
536 EmpathyAccountSettings *
537 empathy_account_settings_new_for_account (TpAccount *account)
539 return g_object_new (EMPATHY_TYPE_ACCOUNT_SETTINGS,
544 TpConnectionManagerParam *
545 empathy_account_settings_get_tp_params (EmpathyAccountSettings *settings)
547 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
548 const TpConnectionManagerProtocol *tp_protocol;
550 g_return_val_if_fail (priv->manager != NULL, NULL);
551 g_return_val_if_fail (priv->protocol != NULL, NULL);
553 tp_protocol = tp_connection_manager_get_protocol (priv->manager,
555 if (tp_protocol == NULL)
557 DEBUG ("Can't retrieve TpConnectionManagerProtocol for protocol '%s'",
562 return tp_protocol->params;
566 empathy_account_settings_is_ready (EmpathyAccountSettings *settings)
568 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
574 empathy_account_settings_get_cm (EmpathyAccountSettings *settings)
576 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
578 return priv->cm_name;
582 empathy_account_settings_get_protocol (EmpathyAccountSettings *settings)
584 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
586 return priv->protocol;
590 empathy_account_settings_get_service (EmpathyAccountSettings *settings)
592 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
594 return priv->service;
598 empathy_account_settings_get_icon_name (EmpathyAccountSettings *settings)
600 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
602 return priv->icon_name;
606 empathy_account_settings_get_display_name (EmpathyAccountSettings *settings)
608 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
610 return priv->display_name;
614 empathy_account_settings_get_account (EmpathyAccountSettings *settings)
616 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
618 return priv->account;
622 empathy_account_settings_is_unset (EmpathyAccountSettings *settings,
625 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
629 a = priv->unset_parameters;
631 for (i = 0; i < a->len; i++)
633 if (!tp_strdiff (g_array_index (a, gchar *, i), param))
640 static TpConnectionManagerParam *
641 empathy_account_settings_get_tp_param (EmpathyAccountSettings *settings,
644 TpConnectionManagerParam *tp_params =
645 empathy_account_settings_get_tp_params (settings);
646 TpConnectionManagerParam *p;
648 for (p = tp_params; p != NULL && p->name != NULL; p++)
650 if (tp_strdiff (p->name, param))
660 account_settings_remove_from_unset (EmpathyAccountSettings *settings,
663 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
667 for (idx = 0; idx < priv->unset_parameters->len; idx++)
669 val = g_array_index (priv->unset_parameters, gchar *, idx);
671 if (!tp_strdiff (val, param))
673 priv->unset_parameters =
674 g_array_remove_index (priv->unset_parameters, idx);
683 empathy_account_settings_get_default (EmpathyAccountSettings *settings,
686 TpConnectionManagerParam *p;
688 p = empathy_account_settings_get_tp_param (settings, param);
690 if (p == NULL || !(p->flags & TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT))
693 return &(p->default_value);
697 empathy_account_settings_get_dbus_signature (EmpathyAccountSettings *settings,
700 TpConnectionManagerParam *p;
702 p = empathy_account_settings_get_tp_param (settings, param);
707 return p->dbus_signature;
711 empathy_account_settings_get (EmpathyAccountSettings *settings,
714 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
715 const GValue *result = NULL;
717 /* Lookup the update parameters we set */
718 result = tp_asv_lookup (priv->parameters, param);
722 /* If the parameters isn't unset use the accounts setting if any */
723 if (priv->account != NULL
724 && !empathy_account_settings_is_unset (settings, param))
726 const GHashTable *parameters;
728 parameters = tp_account_get_parameters (priv->account);
729 result = tp_asv_lookup (parameters, param);
735 /* fallback to the default */
736 return empathy_account_settings_get_default (settings, param);
740 empathy_account_settings_unset (EmpathyAccountSettings *settings,
743 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
745 if (empathy_account_settings_is_unset (settings, param))
748 v = g_strdup (param);
750 g_array_append_val (priv->unset_parameters, v);
751 g_hash_table_remove (priv->parameters, param);
755 empathy_account_settings_discard_changes (EmpathyAccountSettings *settings)
757 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
759 g_hash_table_remove_all (priv->parameters);
760 empathy_account_settings_free_unset_parameters (settings);
764 empathy_account_settings_get_string (EmpathyAccountSettings *settings,
769 v = empathy_account_settings_get (settings, param);
771 if (v == NULL || !G_VALUE_HOLDS_STRING (v))
774 return g_value_get_string (v);
777 const gchar * const *
778 empathy_account_settings_get_strv (EmpathyAccountSettings *settings,
783 v = empathy_account_settings_get (settings, param);
785 if (v == NULL || !G_VALUE_HOLDS (v, G_TYPE_STRV))
788 return g_value_get_boxed (v);
792 empathy_account_settings_get_int32 (EmpathyAccountSettings *settings,
798 v = empathy_account_settings_get (settings, param);
803 switch G_VALUE_TYPE (v)
806 ret = g_value_get_uchar (v);
809 ret = g_value_get_int (v);
812 ret = CLAMP (g_value_get_uint (v), (guint) G_MININT32,
816 ret = CLAMP (g_value_get_int64 (v), G_MININT32, G_MAXINT32);
819 ret = CLAMP (g_value_get_uint64 (v), (guint64) G_MININT32,
831 empathy_account_settings_get_int64 (EmpathyAccountSettings *settings,
837 v = empathy_account_settings_get (settings, param);
841 switch G_VALUE_TYPE (v)
844 ret = g_value_get_uchar (v);
847 ret = g_value_get_int (v);
850 ret = g_value_get_uint (v);
853 ret = g_value_get_int64 (v);
856 ret = CLAMP (g_value_get_uint64 (v), (guint64) G_MININT64, G_MAXINT64);
867 empathy_account_settings_get_uint32 (EmpathyAccountSettings *settings,
873 v = empathy_account_settings_get (settings, param);
877 switch G_VALUE_TYPE (v)
880 ret = g_value_get_uchar (v);
883 ret = MAX (0, g_value_get_int (v));
886 ret = g_value_get_uint (v);
889 ret = CLAMP (g_value_get_int64 (v), 0, G_MAXUINT32);
892 ret = MIN (g_value_get_uint64 (v), G_MAXUINT32);
903 empathy_account_settings_get_uint64 (EmpathyAccountSettings *settings,
909 v = empathy_account_settings_get (settings, param);
911 if (v == NULL || !G_VALUE_HOLDS_INT (v))
914 switch G_VALUE_TYPE (v)
917 ret = g_value_get_uchar (v);
920 ret = MAX (0, g_value_get_int (v));
923 ret = g_value_get_uint (v);
926 ret = MAX (0, g_value_get_int64 (v));
929 ret = g_value_get_uint64 (v);
940 empathy_account_settings_get_boolean (EmpathyAccountSettings *settings,
945 v = empathy_account_settings_get (settings, param);
947 if (v == NULL || !G_VALUE_HOLDS_BOOLEAN (v))
950 return g_value_get_boolean (v);
954 empathy_account_settings_set_string (EmpathyAccountSettings *settings,
958 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
960 g_return_if_fail (param != NULL);
961 g_return_if_fail (value != NULL);
963 tp_asv_set_string (priv->parameters, g_strdup (param), value);
965 account_settings_remove_from_unset (settings, param);
969 empathy_account_settings_set_strv (EmpathyAccountSettings *settings,
973 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
975 g_return_if_fail (param != NULL);
976 g_return_if_fail (value != NULL);
978 tp_asv_set_strv (priv->parameters, g_strdup (param), value);
980 account_settings_remove_from_unset (settings, param);
984 empathy_account_settings_set_int32 (EmpathyAccountSettings *settings,
988 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
990 g_return_if_fail (param != NULL);
992 tp_asv_set_int32 (priv->parameters, g_strdup (param), value);
994 account_settings_remove_from_unset (settings, param);
998 empathy_account_settings_set_int64 (EmpathyAccountSettings *settings,
1002 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1004 g_return_if_fail (param != NULL);
1006 tp_asv_set_int64 (priv->parameters, g_strdup (param), value);
1008 account_settings_remove_from_unset (settings, param);
1012 empathy_account_settings_set_uint32 (EmpathyAccountSettings *settings,
1016 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1018 g_return_if_fail (param != NULL);
1020 tp_asv_set_uint32 (priv->parameters, g_strdup (param), value);
1022 account_settings_remove_from_unset (settings, param);
1026 empathy_account_settings_set_uint64 (EmpathyAccountSettings *settings,
1030 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1032 g_return_if_fail (param != NULL);
1034 tp_asv_set_uint64 (priv->parameters, g_strdup (param), value);
1036 account_settings_remove_from_unset (settings, param);
1040 empathy_account_settings_set_boolean (EmpathyAccountSettings *settings,
1044 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1046 g_return_if_fail (param != NULL);
1048 tp_asv_set_boolean (priv->parameters, g_strdup (param), value);
1050 account_settings_remove_from_unset (settings, param);
1054 account_settings_display_name_set_cb (GObject *src,
1058 GError *error = NULL;
1059 TpAccount *account = TP_ACCOUNT (src);
1060 GSimpleAsyncResult *set_result = user_data;
1062 tp_account_set_display_name_finish (account, res, &error);
1066 g_simple_async_result_set_from_error (set_result, error);
1067 g_error_free (error);
1070 g_simple_async_result_complete (set_result);
1071 g_object_unref (set_result);
1075 empathy_account_settings_set_display_name_async (
1076 EmpathyAccountSettings *settings,
1078 GAsyncReadyCallback callback,
1081 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1082 GSimpleAsyncResult *result;
1084 g_return_if_fail (name != NULL);
1086 result = g_simple_async_result_new (G_OBJECT (settings),
1087 callback, user_data, empathy_account_settings_set_display_name_finish);
1089 if (!tp_strdiff (name, priv->display_name))
1092 g_simple_async_result_complete_in_idle (result);
1096 if (priv->account == NULL)
1098 if (priv->display_name != NULL)
1099 g_free (priv->display_name);
1101 priv->display_name = g_strdup (name);
1103 g_simple_async_result_complete_in_idle (result);
1108 tp_account_set_display_name_async (priv->account, name,
1109 account_settings_display_name_set_cb, result);
1113 empathy_account_settings_set_display_name_finish (
1114 EmpathyAccountSettings *settings,
1115 GAsyncResult *result,
1118 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1122 g_return_val_if_fail (g_simple_async_result_is_valid (result,
1123 G_OBJECT (settings), empathy_account_settings_set_display_name_finish),
1130 account_settings_icon_name_set_cb (GObject *src,
1134 GError *error = NULL;
1135 TpAccount *account = TP_ACCOUNT (src);
1136 GSimpleAsyncResult *set_result = user_data;
1138 tp_account_set_icon_name_finish (account, res, &error);
1142 g_simple_async_result_set_from_error (set_result, error);
1143 g_error_free (error);
1146 g_simple_async_result_complete (set_result);
1147 g_object_unref (set_result);
1151 empathy_account_settings_set_icon_name_async (
1152 EmpathyAccountSettings *settings,
1154 GAsyncReadyCallback callback,
1157 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1158 GSimpleAsyncResult *result;
1160 g_return_if_fail (name != NULL);
1162 result = g_simple_async_result_new (G_OBJECT (settings),
1163 callback, user_data, empathy_account_settings_set_icon_name_finish);
1165 if (priv->account == NULL)
1167 if (priv->icon_name != NULL)
1168 g_free (priv->icon_name);
1170 priv->icon_name = g_strdup (name);
1172 g_simple_async_result_complete_in_idle (result);
1177 tp_account_set_icon_name_async (priv->account, name,
1178 account_settings_icon_name_set_cb, result);
1182 empathy_account_settings_set_icon_name_finish (
1183 EmpathyAccountSettings *settings,
1184 GAsyncResult *result,
1187 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1191 g_return_val_if_fail (g_simple_async_result_is_valid (result,
1192 G_OBJECT (settings), empathy_account_settings_set_icon_name_finish),
1199 empathy_account_settings_account_updated (GObject *source,
1200 GAsyncResult *result,
1203 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (user_data);
1204 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1205 GSimpleAsyncResult *r;
1206 GError *error = NULL;
1208 if (!tp_account_update_parameters_finish (TP_ACCOUNT (source),
1209 result, NULL, &error))
1211 g_simple_async_result_set_from_error (priv->apply_result, error);
1212 g_error_free (error);
1216 empathy_account_settings_discard_changes (settings);
1219 r = priv->apply_result;
1220 priv->apply_result = NULL;
1222 g_simple_async_result_complete (r);
1227 empathy_account_settings_created_cb (GObject *source,
1228 GAsyncResult *result,
1231 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (user_data);
1232 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1234 GError *error = NULL;
1235 GSimpleAsyncResult *r;
1237 account = tp_account_manager_create_account_finish (
1238 TP_ACCOUNT_MANAGER (source), result, &error);
1240 if (account == NULL)
1242 g_simple_async_result_set_from_error (priv->apply_result, error);
1246 priv->account = g_object_ref (account);
1247 empathy_account_settings_discard_changes (settings);
1250 r = priv->apply_result;
1251 priv->apply_result = NULL;
1253 g_simple_async_result_complete (r);
1259 empathy_account_settings_do_create_account (EmpathyAccountSettings *settings)
1261 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1262 GHashTable *properties;
1263 TpConnectionPresenceType type;
1268 properties = tp_asv_new (NULL, NULL);
1270 idle = empathy_idle_dup_singleton ();
1271 type = empathy_idle_get_requested_presence (idle, &status, &message);
1272 g_object_unref (idle);
1274 if (type != TP_CONNECTION_PRESENCE_TYPE_UNSET)
1276 /* Create the account with the requested presence the same as the current
1277 * global requested presence, but don't enable it */
1278 GValueArray *presence;
1279 GValue vtype = { 0, };
1280 GValue vstatus = { 0, };
1281 GValue vmessage = { 0, };
1283 presence = g_value_array_new (3);
1285 g_value_init (&vtype, G_TYPE_UINT);
1286 g_value_set_uint (&vtype, type);
1287 g_value_array_append (presence, &vtype);
1289 g_value_init (&vstatus, G_TYPE_STRING);
1290 g_value_take_string (&vstatus, status);
1291 g_value_array_append (presence, &vstatus);
1293 g_value_init (&vmessage, G_TYPE_STRING);
1294 g_value_take_string (&vmessage, message);
1295 g_value_array_append (presence, &vmessage);
1297 tp_asv_take_boxed (properties, TP_IFACE_ACCOUNT ".RequestedPresence",
1298 TP_STRUCT_TYPE_SIMPLE_PRESENCE, presence);
1301 tp_asv_set_string (properties, TP_IFACE_ACCOUNT ".Icon",
1304 if (priv->service != NULL)
1305 tp_asv_set_string (properties, TP_PROP_ACCOUNT_SERVICE, priv->service);
1307 tp_account_manager_create_account_async (priv->account_manager,
1308 priv->cm_name, priv->protocol, priv->display_name,
1309 priv->parameters, properties,
1310 empathy_account_settings_created_cb,
1313 g_hash_table_unref (properties);
1317 empathy_account_settings_manager_ready_cb (GObject *source_object,
1318 GAsyncResult *result,
1321 EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (user_data);
1322 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1323 TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
1324 GError *error = NULL;
1326 if (!tp_account_manager_prepare_finish (account_manager, result, &error))
1328 DEBUG ("Failed to prepare account manager: %s", error->message);
1329 g_error_free (error);
1333 g_assert (priv->apply_result != NULL && priv->account == NULL);
1334 empathy_account_settings_do_create_account (settings);
1338 empathy_account_settings_apply_async (EmpathyAccountSettings *settings,
1339 GAsyncReadyCallback callback,
1342 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1344 if (priv->apply_result != NULL)
1346 g_simple_async_report_error_in_idle (G_OBJECT (settings),
1347 callback, user_data,
1348 G_IO_ERROR, G_IO_ERROR_PENDING, "Applying already in progress");
1352 priv->apply_result = g_simple_async_result_new (G_OBJECT (settings),
1353 callback, user_data, empathy_account_settings_apply_finish);
1355 if (priv->account == NULL)
1357 tp_account_manager_prepare_async (priv->account_manager, NULL,
1358 empathy_account_settings_manager_ready_cb, settings);
1362 tp_account_update_parameters_async (priv->account,
1363 priv->parameters, (const gchar **)priv->unset_parameters->data,
1364 empathy_account_settings_account_updated, settings);
1369 empathy_account_settings_apply_finish (EmpathyAccountSettings *settings,
1370 GAsyncResult *result,
1373 if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
1377 g_return_val_if_fail (g_simple_async_result_is_valid (result,
1378 G_OBJECT (settings), empathy_account_settings_apply_finish), FALSE);
1384 empathy_account_settings_has_account (EmpathyAccountSettings *settings,
1387 EmpathyAccountSettingsPriv *priv;
1388 const gchar *account_path;
1389 const gchar *priv_account_path;
1391 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE);
1392 g_return_val_if_fail (TP_IS_ACCOUNT (account), FALSE);
1394 priv = GET_PRIV (settings);
1396 if (priv->account == NULL)
1399 account_path = tp_proxy_get_object_path (TP_PROXY (account));
1400 priv_account_path = tp_proxy_get_object_path (TP_PROXY (priv->account));
1402 return (!tp_strdiff (account_path, priv_account_path));
1406 empathy_account_settings_set_regex (EmpathyAccountSettings *settings,
1408 const gchar *pattern)
1410 EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
1413 regex = g_regex_new (pattern, 0, 0, NULL);
1414 g_hash_table_insert (priv->param_regexps, g_strdup (param), regex);
1418 empathy_account_settings_parameter_is_valid (
1419 EmpathyAccountSettings *settings,
1422 EmpathyAccountSettingsPriv *priv;
1423 const GRegex *regex;
1426 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE);
1428 priv = GET_PRIV (settings);
1430 if (g_list_find_custom (priv->required_params, param, (GCompareFunc) strcmp))
1432 /* first, look if it's set in our own parameters */
1433 if (tp_asv_lookup (priv->parameters, param))
1436 /* if we did not unset the parameter, look if it's in the account */
1437 if (priv->account != NULL &&
1438 !empathy_account_settings_is_unset (settings, param))
1440 const GHashTable *account_params;
1442 account_params = tp_account_get_parameters (priv->account);
1443 if (tp_asv_lookup (account_params, param))
1451 /* test whether parameter value matches its regex */
1452 regex = g_hash_table_lookup (priv->param_regexps, param);
1455 value = empathy_account_settings_get_string (settings, param);
1456 if (value != NULL && !g_regex_match (regex, value, 0, NULL))
1464 empathy_account_settings_is_valid (EmpathyAccountSettings *settings)
1466 EmpathyAccountSettingsPriv *priv;
1468 GHashTableIter iter;
1471 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE);
1473 priv = GET_PRIV (settings);
1475 for (l = priv->required_params; l; l = l->next)
1477 if (!empathy_account_settings_parameter_is_valid (settings, l->data))
1481 g_hash_table_iter_init (&iter, priv->param_regexps);
1482 while (g_hash_table_iter_next (&iter, (gpointer *) ¶m, NULL))
1484 if (!empathy_account_settings_parameter_is_valid (settings, param))
1491 const TpConnectionManagerProtocol *
1492 empathy_account_settings_get_tp_protocol (EmpathyAccountSettings *self)
1494 EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
1496 return tp_connection_manager_get_protocol (priv->manager, priv->protocol);