]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-account-settings.c
Merge branch 'sasl'
[empathy.git] / libempathy / empathy-account-settings.c
index c470ce052d7fa5ad0a95dc0b2220f03c5625fa02..e5191a96ca092a10e6258147ec324df8c171a1ca 100644 (file)
@@ -43,6 +43,7 @@ enum {
   PROP_ACCOUNT = 1,
   PROP_CM_NAME,
   PROP_PROTOCOL,
+  PROP_SERVICE,
   PROP_DISPLAY_NAME,
   PROP_DISPLAY_NAME_OVERRIDDEN,
   PROP_READY
@@ -62,14 +63,21 @@ struct _EmpathyAccountSettingsPriv
   TpAccount *account;
   gchar *cm_name;
   gchar *protocol;
+  gchar *service;
   gchar *display_name;
   gchar *icon_name;
   gboolean display_name_overridden;
   gboolean ready;
 
+  /* Parameter name (gchar *) -> parameter value (GValue) */
   GHashTable *parameters;
+  /* Keys are parameter names from the hash above (gchar *).
+   * Values are regular expresions that should match corresponding parameter
+   * values (GRegex *). Possible regexp patterns are defined in
+   * empathy-account-widget.c */
+  GHashTable *param_regexps;
   GArray *unset_parameters;
-  GArray *required_params;
+  GList *required_params;
 
   gulong managers_ready_id;
 
@@ -91,7 +99,12 @@ empathy_account_settings_init (EmpathyAccountSettings *obj)
   priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
     g_free, (GDestroyNotify) tp_g_value_slice_free);
 
+  priv->param_regexps = g_hash_table_new_full (g_str_hash, g_str_equal,
+    g_free, (GDestroyNotify) g_regex_unref);
+
   priv->unset_parameters = g_array_new (TRUE, FALSE, sizeof (gchar *));
+
+  priv->required_params = NULL;
 }
 
 static void empathy_account_settings_dispose (GObject *object);
@@ -123,6 +136,9 @@ empathy_account_settings_set_property (GObject *object,
       case PROP_PROTOCOL:
         priv->protocol = g_value_dup_string (value);
         break;
+      case PROP_SERVICE:
+        priv->service = g_value_dup_string (value);
+        break;
       case PROP_DISPLAY_NAME:
         priv->display_name = g_value_dup_string (value);
         break;
@@ -155,6 +171,9 @@ empathy_account_settings_get_property (GObject *object,
       case PROP_PROTOCOL:
         g_value_set_string (value, priv->protocol);
         break;
+      case PROP_SERVICE:
+        g_value_set_string (value, priv->service);
+        break;
       case PROP_DISPLAY_NAME:
         g_value_set_string (value, priv->display_name);
         break;
@@ -180,11 +199,14 @@ empathy_account_settings_constructed (GObject *object)
     {
       g_free (priv->cm_name);
       g_free (priv->protocol);
+      g_free (priv->service);
 
       priv->cm_name =
         g_strdup (tp_account_get_connection_manager (priv->account));
       priv->protocol =
         g_strdup (tp_account_get_protocol (priv->account));
+      priv->service =
+        g_strdup (tp_account_get_service (priv->account));
       priv->icon_name = g_strdup
         (tp_account_get_icon_name (priv->account));
     }
@@ -199,7 +221,12 @@ empathy_account_settings_constructed (GObject *object)
 
   if (!priv->ready)
     {
-      tp_account_prepare_async (priv->account, NULL,
+      GQuark features[] = {
+          TP_ACCOUNT_FEATURE_CORE,
+          TP_ACCOUNT_FEATURE_STORAGE,
+          0 };
+
+      tp_proxy_prepare_async (priv->account, features,
           empathy_account_settings_account_ready_cb, self);
       tp_g_signal_connect_object (priv->managers, "notify::ready",
         G_CALLBACK (empathy_account_settings_managers_ready_cb), object, 0);
@@ -248,6 +275,13 @@ empathy_account_settings_class_init (
       NULL,
       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+  g_object_class_install_property (object_class, PROP_SERVICE,
+    g_param_spec_string ("service",
+      "Service",
+      "The service of this account, or NULL",
+      NULL,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
   g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
     g_param_spec_string ("display-name",
       "display-name",
@@ -325,17 +359,24 @@ empathy_account_settings_finalize (GObject *object)
 {
   EmpathyAccountSettings *self = EMPATHY_ACCOUNT_SETTINGS (object);
   EmpathyAccountSettingsPriv *priv = GET_PRIV (self);
+  GList *l;
 
   /* free any data held directly by the object here */
   g_free (priv->cm_name);
   g_free (priv->protocol);
+  g_free (priv->service);
   g_free (priv->display_name);
   g_free (priv->icon_name);
 
   if (priv->required_params != NULL)
-    g_array_free (priv->required_params, TRUE);
+    {
+      for (l = priv->required_params; l; l = l->next)
+        g_free (l->data);
+      g_list_free (priv->required_params);
+    }
 
   g_hash_table_destroy (priv->parameters);
+  g_hash_table_destroy (priv->param_regexps);
 
   empathy_account_settings_free_unset_parameters (self);
   g_array_free (priv->unset_parameters, TRUE);
@@ -388,16 +429,13 @@ empathy_account_settings_check_readyness (EmpathyAccountSettings *self)
   if (priv->required_params == NULL)
     {
       TpConnectionManagerParam *cur;
-      char *val;
-
-      priv->required_params = g_array_new (TRUE, FALSE, sizeof (gchar *));
 
       for (cur = 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);
+              priv->required_params = g_list_append (priv->required_params,
+                                                     g_strdup (cur->name));
             }
         }
     }
@@ -417,7 +455,7 @@ empathy_account_settings_account_ready_cb (GObject *source_object,
   TpAccount *account = TP_ACCOUNT (source_object);
   GError *error = NULL;
 
-  if (!tp_account_prepare_finish (account, result, &error))
+  if (!tp_proxy_prepare_finish (account, result, &error))
     {
       DEBUG ("Failed to prepare account: %s", error->message);
       g_error_free (error);
@@ -440,11 +478,13 @@ empathy_account_settings_managers_ready_cb (GObject *object,
 EmpathyAccountSettings *
 empathy_account_settings_new (const gchar *connection_manager,
     const gchar *protocol,
+    const gchar *service,
     const char *display_name)
 {
   return g_object_new (EMPATHY_TYPE_ACCOUNT_SETTINGS,
       "connection-manager", connection_manager,
       "protocol", protocol,
+      "service", service,
       "display-name", display_name,
       NULL);
 }
@@ -502,6 +542,14 @@ empathy_account_settings_get_protocol (EmpathyAccountSettings *settings)
   return priv->protocol;
 }
 
+const gchar *
+empathy_account_settings_get_service (EmpathyAccountSettings *settings)
+{
+  EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
+
+  return priv->service;
+}
+
 gchar *
 empathy_account_settings_get_icon_name (EmpathyAccountSettings *settings)
 {
@@ -682,6 +730,20 @@ empathy_account_settings_get_string (EmpathyAccountSettings *settings,
   return g_value_get_string (v);
 }
 
+const gchar * const *
+empathy_account_settings_get_strv (EmpathyAccountSettings *settings,
+    const gchar *param)
+{
+  const GValue *v;
+
+  v = empathy_account_settings_get (settings, param);
+
+  if (v == NULL || !G_VALUE_HOLDS (v, G_TYPE_STRV))
+    return NULL;
+
+  return g_value_get_boxed (v);
+}
+
 gint32
 empathy_account_settings_get_int32 (EmpathyAccountSettings *settings,
     const gchar *param)
@@ -851,11 +913,29 @@ empathy_account_settings_set_string (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
+  g_return_if_fail (param != NULL);
+  g_return_if_fail (value != NULL);
+
   tp_asv_set_string (priv->parameters, g_strdup (param), value);
 
   account_settings_remove_from_unset (settings, param);
 }
 
+void
+empathy_account_settings_set_strv (EmpathyAccountSettings *settings,
+    const gchar *param,
+    gchar **value)
+{
+  EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
+
+  g_return_if_fail (param != NULL);
+  g_return_if_fail (value != NULL);
+
+  tp_asv_set_strv (priv->parameters, g_strdup (param), value);
+
+  account_settings_remove_from_unset (settings, param);
+}
+
 void
 empathy_account_settings_set_int32 (EmpathyAccountSettings *settings,
     const gchar *param,
@@ -863,6 +943,8 @@ empathy_account_settings_set_int32 (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
+  g_return_if_fail (param != NULL);
+
   tp_asv_set_int32 (priv->parameters, g_strdup (param), value);
 
   account_settings_remove_from_unset (settings, param);
@@ -875,6 +957,8 @@ empathy_account_settings_set_int64 (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
+  g_return_if_fail (param != NULL);
+
   tp_asv_set_int64 (priv->parameters, g_strdup (param), value);
 
   account_settings_remove_from_unset (settings, param);
@@ -887,6 +971,8 @@ empathy_account_settings_set_uint32 (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
+  g_return_if_fail (param != NULL);
+
   tp_asv_set_uint32 (priv->parameters, g_strdup (param), value);
 
   account_settings_remove_from_unset (settings, param);
@@ -899,6 +985,8 @@ empathy_account_settings_set_uint64 (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
+  g_return_if_fail (param != NULL);
+
   tp_asv_set_uint64 (priv->parameters, g_strdup (param), value);
 
   account_settings_remove_from_unset (settings, param);
@@ -911,6 +999,8 @@ empathy_account_settings_set_boolean (EmpathyAccountSettings *settings,
 {
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
 
+  g_return_if_fail (param != NULL);
+
   tp_asv_set_boolean (priv->parameters, g_strdup (param), value);
 
   account_settings_remove_from_unset (settings, param);
@@ -947,6 +1037,8 @@ empathy_account_settings_set_display_name_async (
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
   GSimpleAsyncResult *result;
 
+  g_return_if_fail (name != NULL);
+
   result = g_simple_async_result_new (G_OBJECT (settings),
       callback, user_data, empathy_account_settings_set_display_name_finish);
 
@@ -1021,6 +1113,8 @@ empathy_account_settings_set_icon_name_async (
   EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
   GSimpleAsyncResult *result;
 
+  g_return_if_fail (name != NULL);
+
   result = g_simple_async_result_new (G_OBJECT (settings),
       callback, user_data, empathy_account_settings_set_icon_name_finish);
 
@@ -1163,6 +1257,9 @@ empathy_account_settings_do_create_account (EmpathyAccountSettings *settings)
   tp_asv_set_string (properties, TP_IFACE_ACCOUNT ".Icon",
       priv->icon_name);
 
+  if (priv->service != NULL)
+    tp_asv_set_string (properties, TP_PROP_ACCOUNT_SERVICE, priv->service);
+
   tp_account_manager_create_account_async (priv->account_manager,
     priv->cm_name, priv->protocol, priv->display_name,
     priv->parameters, properties,
@@ -1261,42 +1358,90 @@ empathy_account_settings_has_account (EmpathyAccountSettings *settings,
   return (!tp_strdiff (account_path, priv_account_path));
 }
 
+void
+empathy_account_settings_set_regex (EmpathyAccountSettings *settings,
+    const gchar *param,
+    const gchar *pattern)
+{
+  EmpathyAccountSettingsPriv *priv = GET_PRIV (settings);
+  GRegex *regex;
+
+  regex = g_regex_new (pattern, 0, 0, NULL);
+  g_hash_table_insert (priv->param_regexps, g_strdup (param), regex);
+}
+
 gboolean
-empathy_account_settings_is_valid (EmpathyAccountSettings *settings)
+empathy_account_settings_parameter_is_valid (
+    EmpathyAccountSettings *settings,
+    const gchar *param)
 {
   EmpathyAccountSettingsPriv *priv;
-  guint idx;
-  gchar *current;
-  gboolean missed = FALSE;
+  const GRegex *regex;
+  const gchar *value;
 
   g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE);
 
   priv = GET_PRIV (settings);
 
-  for (idx = 0; idx < priv->required_params->len; idx++)
+  if (g_list_find_custom (priv->required_params, param, (GCompareFunc) strcmp))
     {
-      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 (tp_asv_lookup (priv->parameters, param))
+        goto test_regex;
 
       /* 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))
+          !empathy_account_settings_is_unset (settings, param))
         {
           const GHashTable *account_params;
 
           account_params = tp_account_get_parameters (priv->account);
-          if (tp_asv_lookup (account_params, current))
-            continue;
+          if (tp_asv_lookup (account_params, param))
+            goto test_regex;
         }
 
-      missed = TRUE;
-      break;
+      return FALSE;
+    }
+
+test_regex:
+  /* test whether parameter value matches its regex */
+  regex = g_hash_table_lookup (priv->param_regexps, param);
+  if (regex)
+    {
+      value = empathy_account_settings_get_string (settings, param);
+      if (value != NULL && !g_regex_match (regex, value, 0, NULL))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+empathy_account_settings_is_valid (EmpathyAccountSettings *settings)
+{
+  EmpathyAccountSettingsPriv *priv;
+  const gchar *param;
+  GHashTableIter iter;
+  GList *l;
+
+  g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE);
+
+  priv = GET_PRIV (settings);
+
+  for (l = priv->required_params; l; l = l->next)
+    {
+      if (!empathy_account_settings_parameter_is_valid (settings, l->data))
+        return FALSE;
     }
 
-  return !missed;
+  g_hash_table_iter_init (&iter, priv->param_regexps);
+  while (g_hash_table_iter_next (&iter, (gpointer *) &param, NULL))
+    {
+      if (!empathy_account_settings_parameter_is_valid (settings, param))
+        return FALSE;
+    }
+
+  return TRUE;
 }
 
 const TpConnectionManagerProtocol *