]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-account-widget.c
debug-window: fix typo
[empathy.git] / libempathy-gtk / empathy-account-widget.c
index 7494fa0a0dc49c550a45e015d2398192cdad0ee3..794e7d5247a4ccb84dc81abf73183ad93930f5fd 100644 (file)
  *          Danielle Madeley <danielle.madeley@collabora.co.uk>
  */
 
-#include <config.h>
+#include "config.h"
 
-#include <string.h>
-
-#include <gtk/gtk.h>
 #include <glib/gi18n-lib.h>
 
-#include <gio/gdesktopappinfo.h>
-
 #include <libempathy/empathy-utils.h>
 
-#include <telepathy-glib/account.h>
-#include <telepathy-glib/account-manager.h>
-#include <telepathy-glib/connection-manager.h>
-#include <telepathy-glib/util.h>
 #include <dbus/dbus-protocol.h>
 
-#include "empathy-account-widget.h"
 #include "empathy-account-widget-private.h"
 #include "empathy-account-widget-sip.h"
 #include "empathy-account-widget-irc.h"
@@ -50,7 +40,7 @@
 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
 #include <libempathy/empathy-debug.h>
 
-G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, G_TYPE_OBJECT)
+G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, GTK_TYPE_BOX)
 
 typedef enum
 {
@@ -134,8 +124,6 @@ enum {
   LAST_SIGNAL
 };
 
-static void account_widget_apply_and_log_in (EmpathyAccountWidget *);
-
 enum {
   RESPONSE_LAUNCH
 };
@@ -174,14 +162,6 @@ static guint signals[LAST_SIGNAL] = { 0 };
 /* Based on http://www.ietf.org/rfc/rfc2812.txt (section 2.3.1) */
 #define IRC_SPECIAL       "_\\[\\]{}\\\\|`^"
 #define IRC_NICK_NAME     "(["ALPHA IRC_SPECIAL"]["ALPHADIGITDASH IRC_SPECIAL"]*)"
-/*   user       =  1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF )
- *                ; any octet except NUL, CR, LF, " " and "@"
- *
- * so technically, like so many other places in IRC, we should be using arrays
- * of bytes here rather than UTF-8 strings. Life: too short. In practice this
- * will always be ASCII.
- */
-#define IRC_USER_NAME     "([^\r\n@ ])+"
 
 /* Based on http://www.ietf.org/rfc/rfc4622.txt (section 2.2)
  * We just exclude invalid characters to avoid ucschars and other redundant
@@ -198,7 +178,6 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 #define ACCOUNT_REGEX_ICQ      "^"ICQ_USER_NAME"$"
 #define ACCOUNT_REGEX_IRC      "^"IRC_NICK_NAME"$"
-#define USERNAME_REGEX_IRC     "^"IRC_USER_NAME"$"
 #define ACCOUNT_REGEX_JABBER   "^"JABBER_USER_NAME"@[^@/]+"
 #define ACCOUNT_REGEX_MSN      "^"MSN_USER_NAME"@"HOST"$"
 #define ACCOUNT_REGEX_YAHOO    "^"YAHOO_USER_NAME"$"
@@ -288,24 +267,26 @@ account_widget_entry_changed_common (EmpathyAccountWidget *self,
 
   if (EMP_STR_EMPTY (str))
     {
-      const gchar *value = NULL;
-
       empathy_account_settings_unset (self->priv->settings, param_name);
 
       if (focus)
         {
-          value = empathy_account_settings_get_string (self->priv->settings,
+          gchar *value;
+
+          value = empathy_account_settings_dup_string (self->priv->settings,
               param_name);
+
           DEBUG ("Unset %s and restore to %s", param_name, value);
           gtk_entry_set_text (entry, value ? value : "");
+          g_free (value);
         }
     }
   else
     {
       DEBUG ("Setting %s to %s", param_name,
           tp_strdiff (param_name, "password") ? str : "***");
-      empathy_account_settings_set_string (self->priv->settings, param_name,
-          str);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_string (str));
     }
 
   curr_status = empathy_account_settings_parameter_is_valid (
@@ -361,21 +342,21 @@ account_widget_int_changed_cb (GtkWidget *widget,
     {
     case DBUS_TYPE_INT16:
     case DBUS_TYPE_INT32:
-      empathy_account_settings_set_int32 (self->priv->settings, param_name,
-          value);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_int32 (value));
       break;
     case DBUS_TYPE_INT64:
-      empathy_account_settings_set_int64 (self->priv->settings, param_name,
-          value);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_int64 (value));
       break;
     case DBUS_TYPE_UINT16:
     case DBUS_TYPE_UINT32:
-      empathy_account_settings_set_uint32 (self->priv->settings, param_name,
-          value);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_uint32 (value));
       break;
     case DBUS_TYPE_UINT64:
-      empathy_account_settings_set_uint64 (self->priv->settings, param_name,
-          value);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_uint64 (value));
       break;
     default:
       g_return_if_reached ();
@@ -409,8 +390,8 @@ account_widget_checkbutton_toggled_cb (GtkWidget *widget,
   else
     {
       DEBUG ("Setting %s to %d", param_name, value);
-      empathy_account_settings_set_boolean (self->priv->settings, param_name,
-          value);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_boolean (value));
     }
 
   empathy_account_widget_changed (self);
@@ -450,7 +431,7 @@ account_widget_combobox_changed_cb (GtkWidget *widget,
   GtkTreeIter iter;
   GtkTreeModel *model;
   const gchar *value;
-  const GValue *v;
+  GVariant *v;
   const gchar *default_value = NULL;
   const gchar *param_name;
 
@@ -463,9 +444,9 @@ account_widget_combobox_changed_cb (GtkWidget *widget,
 
   param_name = g_object_get_data (G_OBJECT (widget), "param_name");
 
-  v = empathy_account_settings_get_default (self->priv->settings, param_name);
-  if (v != NULL)
-    default_value = g_value_get_string (v);
+  v = empathy_account_settings_dup_default (self->priv->settings, param_name);
+  if (v != NULL && g_variant_is_of_type (v, G_VARIANT_TYPE_STRING))
+    default_value = g_variant_get_string (v, NULL);
 
   if (!tp_strdiff (value, default_value))
     {
@@ -475,11 +456,13 @@ account_widget_combobox_changed_cb (GtkWidget *widget,
   else
     {
       DEBUG ("Setting %s to %s", param_name, value);
-      empathy_account_settings_set_string (self->priv->settings, param_name,
-          value);
+      empathy_account_settings_set (self->priv->settings, param_name,
+          g_variant_new_string (value));
     }
 
   empathy_account_widget_changed (self);
+
+  tp_clear_pointer (&v, g_variant_unref);
 }
 
 static void
@@ -516,7 +499,7 @@ password_entry_activated_cb (GtkEntry *entry,
     EmpathyAccountWidget *self)
 {
     if (gtk_widget_get_sensitive (self->priv->apply_button))
-        account_widget_apply_and_log_in (self);
+        empathy_account_widget_apply_and_log_in (self);
 }
 
 static void
@@ -524,7 +507,7 @@ account_entry_activated_cb (GtkEntry *entry,
     EmpathyAccountWidget *self)
 {
     if (gtk_widget_get_sensitive (self->priv->apply_button))
-        account_widget_apply_and_log_in (self);
+        empathy_account_widget_apply_and_log_in (self);
 }
 
 void
@@ -576,9 +559,9 @@ empathy_account_widget_setup_widget (EmpathyAccountWidget *self,
     }
   else if (GTK_IS_ENTRY (widget))
     {
-      const gchar *str = NULL;
+      gchar *str;
 
-      str = empathy_account_settings_get_string (self->priv->settings,
+      str = empathy_account_settings_dup_string (self->priv->settings,
           param_name);
       gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");
 
@@ -609,11 +592,12 @@ empathy_account_widget_setup_widget (EmpathyAccountWidget *self,
         g_signal_connect (widget, "activate",
             G_CALLBACK (account_entry_activated_cb), self);
 
-
       g_signal_connect (widget, "changed",
           G_CALLBACK (account_widget_entry_changed_cb), self);
       g_signal_connect (widget, "map",
           G_CALLBACK (account_widget_entry_map_cb), self);
+
+      g_free (str);
     }
   else if (GTK_IS_TOGGLE_BUTTON (widget))
     {
@@ -631,12 +615,12 @@ empathy_account_widget_setup_widget (EmpathyAccountWidget *self,
     {
       /* The combo box's model has to contain the param value in its first
        * column (as a string) */
-      const gchar *str;
+      gchar *str;
       GtkTreeModel *model;
       GtkTreeIter iter;
       gboolean valid;
 
-      str = empathy_account_settings_get_string (self->priv->settings,
+      str = empathy_account_settings_dup_string (self->priv->settings,
           param_name);
       model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
 
@@ -659,6 +643,8 @@ empathy_account_widget_setup_widget (EmpathyAccountWidget *self,
           g_free (name);
         }
 
+      g_free (str);
+
       g_signal_connect (widget, "changed",
           G_CALLBACK (account_widget_combobox_changed_cb),
           self);
@@ -728,26 +714,28 @@ accounts_widget_generic_setup (EmpathyAccountWidget *self,
     GtkWidget *grid_common_settings,
     GtkWidget *grid_advanced_settings)
 {
-  TpConnectionManagerParam *params, *param;
+  GList *params, *l;
   guint row_common = 0, row_advanced = 0;
 
-  params = empathy_account_settings_get_tp_params (self->priv->settings);
+  params = empathy_account_settings_dup_tp_params (self->priv->settings);
 
-  for (param = params; param != NULL && param->name != NULL; param++)
+  for (l = params; l != NULL; l = g_list_next (l))
     {
+      TpConnectionManagerParam *param = l->data;
       GtkWidget       *grid_settings;
       guint           row;
       GtkWidget       *widget = NULL;
       gchar           *param_name_formatted;
+      const gchar *dbus_signature;
 
-      if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED)
+      if (tp_connection_manager_param_is_required (param))
         {
           grid_settings = grid_common_settings;
           row = row_common++;
         }
       else if (self->priv->simple)
         {
-          return;
+          continue;
         }
       else
         {
@@ -755,16 +743,20 @@ accounts_widget_generic_setup (EmpathyAccountWidget *self,
           row = row_advanced++;
         }
 
-      param_name_formatted = account_widget_generic_format_param_name
-        (param->name);
+      param_name_formatted = account_widget_generic_format_param_name (
+          tp_connection_manager_param_get_name (param));
+
+      dbus_signature = tp_connection_manager_param_get_dbus_signature (param);
 
-      if (param->dbus_signature[0] == 's')
+      if (dbus_signature[0] == 's')
         {
           gchar *str;
 
-          str = g_strdup_printf (_("%s:"), param_name_formatted);
+          str = g_strdup_printf (_("%s"), param_name_formatted);
           widget = gtk_label_new (str);
-          gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
+          gtk_misc_set_alignment (GTK_MISC (widget), 1., 0.5);
+          gtk_style_context_add_class (gtk_widget_get_style_context (widget),
+              GTK_STYLE_CLASS_DIM_LABEL);
           g_free (str);
 
           gtk_grid_attach (GTK_GRID (grid_settings),
@@ -773,7 +765,8 @@ accounts_widget_generic_setup (EmpathyAccountWidget *self,
           gtk_widget_show (widget);
 
           widget = gtk_entry_new ();
-          if (strcmp (param->name, "account") == 0)
+          if (strcmp (tp_connection_manager_param_get_name (param),
+                "account") == 0)
             {
               g_signal_connect (widget, "realize",
                   G_CALLBACK (gtk_widget_grab_focus),
@@ -786,21 +779,21 @@ accounts_widget_generic_setup (EmpathyAccountWidget *self,
           gtk_widget_show (widget);
         }
       /* int types: ynqiuxt. double type is 'd' */
-      else if (param->dbus_signature[0] == 'y' ||
-          param->dbus_signature[0] == 'n' ||
-          param->dbus_signature[0] == 'q' ||
-          param->dbus_signature[0] == 'i' ||
-          param->dbus_signature[0] == 'u' ||
-          param->dbus_signature[0] == 'x' ||
-          param->dbus_signature[0] == 't' ||
-          param->dbus_signature[0] == 'd')
+      else if (dbus_signature[0] == 'y' ||
+          dbus_signature[0] == 'n' ||
+          dbus_signature[0] == 'q' ||
+          dbus_signature[0] == 'i' ||
+          dbus_signature[0] == 'u' ||
+          dbus_signature[0] == 'x' ||
+          dbus_signature[0] == 't' ||
+          dbus_signature[0] == 'd')
         {
           gchar   *str = NULL;
           gdouble  minint = 0;
           gdouble  maxint = 0;
           gdouble  step = 1;
 
-          switch (param->dbus_signature[0])
+          switch (dbus_signature[0])
             {
             case 'y': minint = G_MININT8;  maxint = G_MAXINT8;   break;
             case 'n': minint = G_MININT16; maxint = G_MAXINT16;  break;
@@ -828,7 +821,7 @@ accounts_widget_generic_setup (EmpathyAccountWidget *self,
               widget, 1, row, 1, 1);
           gtk_widget_show (widget);
         }
-      else if (param->dbus_signature[0] == 'b')
+      else if (dbus_signature[0] == 'b')
         {
           widget = gtk_check_button_new_with_label (param_name_formatted);
           gtk_grid_attach (GTK_GRID (grid_settings),
@@ -838,14 +831,17 @@ accounts_widget_generic_setup (EmpathyAccountWidget *self,
       else
         {
           DEBUG ("Unknown signature for param %s: %s",
-              param_name_formatted, param->dbus_signature);
+              param_name_formatted, dbus_signature);
         }
 
       if (widget)
-        empathy_account_widget_setup_widget (self, widget, param->name);
+        empathy_account_widget_setup_widget (self, widget,
+            tp_connection_manager_param_get_name (param));
 
       g_free (param_name_formatted);
     }
+
+  g_list_free_full (params, (GDestroyNotify) tp_connection_manager_param_free);
 }
 
 static void
@@ -903,6 +899,8 @@ account_widget_account_enabled_cb (GObject *source_object,
       empathy_connect_new_account (account, self->priv->account_manager);
     }
 
+  g_signal_emit (self, signals[CLOSE], 0, GTK_RESPONSE_APPLY);
+
   /* unref self - part of the workaround */
   g_object_unref (self);
 }
@@ -917,6 +915,7 @@ account_widget_applied_cb (GObject *source_object,
   EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source_object);
   EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (user_data);
   gboolean reconnect_required;
+  gboolean fire_close = TRUE;
 
   empathy_account_settings_apply_finish (settings, res, &reconnect_required,
       &error);
@@ -942,6 +941,9 @@ account_widget_applied_cb (GObject *source_object,
           tp_account_set_enabled_async (account, TRUE,
               account_widget_account_enabled_cb, self);
           g_signal_emit (self, signals[ACCOUNT_CREATED], 0, account);
+
+          /* Will be fired in account_widget_account_enabled_cb */
+          fire_close = FALSE;
         }
       else
         {
@@ -969,15 +971,18 @@ account_widget_applied_cb (GObject *source_object,
 
   self->priv->contains_pending_changes = FALSE;
 
-  /* announce the widget can be closed */
-  g_signal_emit (self, signals[CLOSE], 0, GTK_RESPONSE_APPLY);
+  if (fire_close)
+    {
+      /* announce the widget can be closed */
+      g_signal_emit (self, signals[CLOSE], 0, GTK_RESPONSE_APPLY);
+    }
 
   /* unref the widget - part of the workaround */
   g_object_unref (self);
 }
 
-static void
-account_widget_apply_and_log_in (EmpathyAccountWidget *self)
+void
+empathy_account_widget_apply_and_log_in (EmpathyAccountWidget *self)
 {
   gboolean display_name_overridden;
 
@@ -987,8 +992,8 @@ account_widget_apply_and_log_in (EmpathyAccountWidget *self)
             self->priv->radiobutton_reuse));
 
       DEBUG ("Set register param: %d", !reuse);
-      empathy_account_settings_set_boolean (self->priv->settings, "register",
-          !reuse);
+      empathy_account_settings_set (self->priv->settings, "register",
+          g_variant_new_boolean (!reuse));
     }
 
   g_object_get (self->priv->settings,
@@ -1018,7 +1023,7 @@ static void
 account_widget_apply_clicked_cb (GtkWidget *button,
     EmpathyAccountWidget *self)
 {
-    account_widget_apply_and_log_in (self);
+    empathy_account_widget_apply_and_log_in (self);
 }
 
 static void
@@ -1049,15 +1054,15 @@ account_widget_settings_ready_cb (EmpathyAccountSettings *settings,
     account_widget_setup_generic (self);
 }
 
-static void
+static GtkWidget *
 account_widget_build_generic (EmpathyAccountWidget *self,
     const char *filename)
 {
-  GtkWidget *expander_advanced;
+  GtkWidget *expander_advanced, *box;
 
   self->ui_details->gui = empathy_builder_get_file (filename,
       "grid_common_settings", &self->priv->grid_common_settings,
-      "vbox_generic_settings", &self->ui_details->widget,
+      "vbox_generic_settings", &box,
       "expander_advanced_settings", &expander_advanced,
       NULL);
 
@@ -1071,17 +1076,19 @@ account_widget_build_generic (EmpathyAccountWidget *self,
   else
     g_signal_connect (self->priv->settings, "notify::ready",
         G_CALLBACK (account_widget_settings_ready_cb), self);
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_salut (EmpathyAccountWidget *self,
     const char *filename)
 {
-  GtkWidget *expander_advanced;
+  GtkWidget *expander_advanced, *box;
 
   self->ui_details->gui = empathy_builder_get_file (filename,
       "grid_common_settings", &self->priv->grid_common_settings,
-      "vbox_salut_settings", &self->ui_details->widget,
+      "vbox_salut_settings", &box,
       "expander_advanced_settings", &expander_advanced,
       NULL);
 
@@ -1098,34 +1105,40 @@ account_widget_build_salut (EmpathyAccountWidget *self,
     gtk_widget_hide (expander_advanced);
 
   self->ui_details->default_focus = g_strdup ("entry_first_name");
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_irc (EmpathyAccountWidget *self,
   const char *filename)
 {
+  GtkWidget *box;
+
   empathy_account_settings_set_regex (self->priv->settings, "account",
       ACCOUNT_REGEX_IRC);
-  empathy_account_settings_set_regex (self->priv->settings, "username",
-      USERNAME_REGEX_IRC);
 
   if (self->priv->simple)
     {
       self->priv->irc_network_chooser = empathy_account_widget_irc_build_simple
-        (self, filename);
+        (self, filename, &box);
     }
   else
     {
       self->priv->irc_network_chooser = empathy_account_widget_irc_build (self,
-          filename, &self->priv->grid_common_settings);
+          filename, &self->priv->grid_common_settings, &box);
     }
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_sip (EmpathyAccountWidget *self,
   const char *filename)
 {
-  empathy_account_widget_sip_build (self, filename,
+  GtkWidget *box;
+
+  box = empathy_account_widget_sip_build (self, filename,
     &self->priv->grid_common_settings);
 
   if (self->priv->simple)
@@ -1139,19 +1152,23 @@ account_widget_build_sip (EmpathyAccountWidget *self,
       self->priv->remember_password_widget = GTK_WIDGET (
           gtk_builder_get_object (self->ui_details->gui, "remember_password"));
     }
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_msn (EmpathyAccountWidget *self,
     const char *filename)
 {
+  GtkWidget *box;
+
   empathy_account_settings_set_regex (self->priv->settings, "account",
       ACCOUNT_REGEX_MSN);
 
   if (self->priv->simple)
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_msn_simple", &self->ui_details->widget,
+          "vbox_msn_simple", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1169,7 +1186,7 @@ account_widget_build_msn (EmpathyAccountWidget *self,
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
           "grid_common_msn_settings", &self->priv->grid_common_settings,
-          "vbox_msn_settings", &self->ui_details->widget,
+          "vbox_msn_settings", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1184,20 +1201,23 @@ account_widget_build_msn (EmpathyAccountWidget *self,
       self->priv->remember_password_widget = GTK_WIDGET (
           gtk_builder_get_object (self->ui_details->gui, "remember_password"));
     }
+
+  return box;
 }
 
 static void
 suffix_id_widget_changed_cb (GtkWidget *entry,
     EmpathyAccountWidget *self)
 {
-  const gchar *account;
+  gchar *account;
 
   g_assert (self->priv->jid_suffix != NULL);
 
   account_widget_entry_changed_common (self, GTK_ENTRY (entry), FALSE);
 
-  account = empathy_account_settings_get_string (self->priv->settings,
+  account = empathy_account_settings_dup_string (self->priv->settings,
       "account");
+
   if (!EMP_STR_EMPTY (account) &&
       !g_str_has_suffix (account, self->priv->jid_suffix))
     {
@@ -1207,12 +1227,14 @@ suffix_id_widget_changed_cb (GtkWidget *entry,
 
       DEBUG ("Change account from '%s' to '%s'", account, tmp);
 
-      empathy_account_settings_set_string (self->priv->settings, "account",
-          tmp);
+      empathy_account_settings_set (self->priv->settings, "account",
+          g_variant_new_string (tmp));
       g_free (tmp);
     }
 
   empathy_account_widget_changed (self);
+
+  g_free (account);
 }
 
 static gchar *
@@ -1232,7 +1254,7 @@ setup_id_widget_with_suffix (EmpathyAccountWidget *self,
     GtkWidget *widget,
     const gchar *suffix)
 {
-  const gchar *str = NULL;
+  gchar *str = NULL;
 
   g_object_set_data_full (G_OBJECT (widget), "param_name",
       g_strdup ("account"), g_free);
@@ -1240,7 +1262,7 @@ setup_id_widget_with_suffix (EmpathyAccountWidget *self,
   g_assert (self->priv->jid_suffix == NULL);
   self->priv->jid_suffix = g_strdup (suffix);
 
-  str = empathy_account_settings_get_string (self->priv->settings, "account");
+  str = empathy_account_settings_dup_string (self->priv->settings, "account");
   if (str != NULL)
     {
       gchar *tmp;
@@ -1248,6 +1270,7 @@ setup_id_widget_with_suffix (EmpathyAccountWidget *self,
       tmp = remove_jid_suffix (self, str);
       gtk_entry_set_text (GTK_ENTRY (widget), tmp);
       g_free (tmp);
+      g_free (str);
     }
 
   self->priv->param_account_widget = widget;
@@ -1277,7 +1300,7 @@ account_widget_get_service (EmpathyAccountWidget *self)
   return NO_SERVICE;
 }
 
-static void
+static GtkWidget *
 account_widget_build_jabber (EmpathyAccountWidget *self,
     const char *filename)
 {
@@ -1289,6 +1312,7 @@ account_widget_build_jabber (EmpathyAccountWidget *self,
   GtkWidget *label_example;
   GtkWidget *expander_advanced;
   GtkWidget *entry_id;
+  GtkWidget *box;
   Service service;
 
   service = account_widget_get_service (self);
@@ -1300,7 +1324,7 @@ account_widget_build_jabber (EmpathyAccountWidget *self,
     {
       /* Simple widget for XMPP */
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_jabber_simple", &self->ui_details->widget,
+          "vbox_jabber_simple", &box,
           "label_id_simple", &label_id,
           "label_id_create", &label_id_create,
           "label_password_simple", &label_password,
@@ -1331,7 +1355,7 @@ account_widget_build_jabber (EmpathyAccountWidget *self,
     {
       /* Simple widget for Google Talk */
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_gtalk_simple", &self->ui_details->widget,
+          "vbox_gtalk_simple", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1349,7 +1373,7 @@ account_widget_build_jabber (EmpathyAccountWidget *self,
     {
       /* Simple widget for Facebook */
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_fb_simple", &self->ui_details->widget,
+          "vbox_fb_simple", &box,
           "entry_id_fb_simple", &entry_id,
           NULL);
 
@@ -1372,7 +1396,7 @@ account_widget_build_jabber (EmpathyAccountWidget *self,
       /* Full widget for XMPP, Google Talk and Facebook*/
       self->ui_details->gui = empathy_builder_get_file (filename,
           "grid_common_settings", &self->priv->grid_common_settings,
-          "vbox_jabber_settings", &self->ui_details->widget,
+          "vbox_jabber_settings", &box,
           "spinbutton_port", &spinbutton_port,
           "checkbutton_ssl", &checkbutton_ssl,
           "label_username_f_example", &label_example_fb,
@@ -1434,13 +1458,16 @@ account_widget_build_jabber (EmpathyAccountWidget *self,
       if (!info.show_advanced)
         gtk_widget_hide (expander_advanced);
     }
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_icq (EmpathyAccountWidget *self,
     const char *filename)
 {
   GtkWidget *spinbutton_port;
+  GtkWidget *box;
 
   empathy_account_settings_set_regex (self->priv->settings, "account",
       ACCOUNT_REGEX_ICQ);
@@ -1448,7 +1475,7 @@ account_widget_build_icq (EmpathyAccountWidget *self,
   if (self->priv->simple)
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_icq_simple", &self->ui_details->widget,
+          "vbox_icq_simple", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1466,7 +1493,7 @@ account_widget_build_icq (EmpathyAccountWidget *self,
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
           "grid_common_settings", &self->priv->grid_common_settings,
-          "vbox_icq_settings", &self->ui_details->widget,
+          "vbox_icq_settings", &box,
           "spinbutton_port", &spinbutton_port,
           NULL);
 
@@ -1483,18 +1510,20 @@ account_widget_build_icq (EmpathyAccountWidget *self,
       self->priv->remember_password_widget = GTK_WIDGET (
           gtk_builder_get_object (self->ui_details->gui, "remember_password"));
     }
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_aim (EmpathyAccountWidget *self,
     const char *filename)
 {
-  GtkWidget *spinbutton_port;
+  GtkWidget *spinbutton_port, *box;
 
   if (self->priv->simple)
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_aim_simple", &self->ui_details->widget,
+          "vbox_aim_simple", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1512,7 +1541,7 @@ account_widget_build_aim (EmpathyAccountWidget *self,
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
           "grid_common_settings", &self->priv->grid_common_settings,
-          "vbox_aim_settings", &self->ui_details->widget,
+          "vbox_aim_settings", &box,
           "spinbutton_port", &spinbutton_port,
           NULL);
 
@@ -1528,19 +1557,23 @@ account_widget_build_aim (EmpathyAccountWidget *self,
       self->priv->remember_password_widget = GTK_WIDGET (
           gtk_builder_get_object (self->ui_details->gui, "remember_password"));
     }
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_yahoo (EmpathyAccountWidget *self,
     const char *filename)
 {
+  GtkWidget *box;
+
   empathy_account_settings_set_regex (self->priv->settings, "account",
       ACCOUNT_REGEX_YAHOO);
 
   if (self->priv->simple)
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_yahoo_simple", &self->ui_details->widget,
+          "vbox_yahoo_simple", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1558,7 +1591,7 @@ account_widget_build_yahoo (EmpathyAccountWidget *self,
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
           "grid_common_settings", &self->priv->grid_common_settings,
-          "vbox_yahoo_settings", &self->ui_details->widget,
+          "vbox_yahoo_settings", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1575,16 +1608,20 @@ account_widget_build_yahoo (EmpathyAccountWidget *self,
       self->priv->remember_password_widget = GTK_WIDGET (
           gtk_builder_get_object (self->ui_details->gui, "remember_password"));
     }
+
+  return box;
 }
 
-static void
+static GtkWidget *
 account_widget_build_groupwise (EmpathyAccountWidget *self,
     const char *filename)
 {
+  GtkWidget *box;
+
   if (self->priv->simple)
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
-          "vbox_groupwise_simple", &self->ui_details->widget,
+          "vbox_groupwise_simple", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1602,7 +1639,7 @@ account_widget_build_groupwise (EmpathyAccountWidget *self,
     {
       self->ui_details->gui = empathy_builder_get_file (filename,
           "grid_common_groupwise_settings", &self->priv->grid_common_settings,
-          "vbox_groupwise_settings", &self->ui_details->widget,
+          "vbox_groupwise_settings", &box,
           NULL);
 
       empathy_account_widget_handle_params (self,
@@ -1617,16 +1654,8 @@ account_widget_build_groupwise (EmpathyAccountWidget *self,
       self->priv->remember_password_widget = GTK_WIDGET (
           gtk_builder_get_object (self->ui_details->gui, "remember_password"));
     }
-}
 
-static void
-account_widget_destroy_cb (GtkWidget *widget,
-    EmpathyAccountWidget *self)
-{
-  /* set the destroyed flag - workaround */
-  self->priv->destroyed = TRUE;
-
-  g_object_unref (self);
+  return box;
 }
 
 void
@@ -1786,9 +1815,8 @@ static void
 add_register_buttons (EmpathyAccountWidget *self,
     TpAccount *account)
 {
-  const TpConnectionManagerProtocol *protocol;
+  TpProtocol *protocol;
   GtkWidget *radiobutton_register;
-  GtkWidget *vbox = self->ui_details->widget;
 
   if (!self->priv->creating_account)
     return;
@@ -1797,7 +1825,7 @@ add_register_buttons (EmpathyAccountWidget *self,
   if (protocol == NULL)
     return;
 
-  if (!tp_connection_manager_protocol_can_register (protocol))
+  if (!tp_protocol_can_register (protocol))
     return;
 
   if (account_widget_get_service (self) != NO_SERVICE)
@@ -1813,11 +1841,11 @@ add_register_buttons (EmpathyAccountWidget *self,
         GTK_RADIO_BUTTON (self->priv->radiobutton_reuse)),
       _("Create a new account on the server"));
 
-  gtk_box_pack_start (GTK_BOX (vbox), self->priv->radiobutton_reuse, FALSE,
+  gtk_box_pack_start (GTK_BOX (self), self->priv->radiobutton_reuse, FALSE,
       FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (vbox), radiobutton_register, FALSE, FALSE, 0);
-  gtk_box_reorder_child (GTK_BOX (vbox), self->priv->radiobutton_reuse, 0);
-  gtk_box_reorder_child (GTK_BOX (vbox), radiobutton_register, 1);
+  gtk_box_pack_start (GTK_BOX (self), radiobutton_register, FALSE, FALSE, 0);
+  gtk_box_reorder_child (GTK_BOX (self), self->priv->radiobutton_reuse, 0);
+  gtk_box_reorder_child (GTK_BOX (self), radiobutton_register, 1);
   gtk_widget_show (self->priv->radiobutton_reuse);
   gtk_widget_show (radiobutton_register);
 }
@@ -1826,16 +1854,11 @@ static void
 remember_password_toggled_cb (GtkToggleButton *button,
     EmpathyAccountWidget *self)
 {
-  if (gtk_toggle_button_get_active (button))
-    {
-      gtk_widget_set_sensitive (self->priv->param_password_widget, TRUE);
-    }
-  else
-    {
-      gtk_widget_set_sensitive (self->priv->param_password_widget, FALSE);
-      gtk_entry_set_text (GTK_ENTRY (self->priv->param_password_widget), "");
-      empathy_account_settings_unset (self->priv->settings, "password");
-    }
+  empathy_account_settings_set_remember_password (self->priv->settings,
+      gtk_toggle_button_get_active (button));
+
+  if (!self->priv->automatic_change)
+    empathy_account_widget_changed (self);
 }
 
 static void
@@ -1843,23 +1866,29 @@ account_settings_password_retrieved_cb (GObject *object,
     gpointer user_data)
 {
   EmpathyAccountWidget *self = user_data;
-  const gchar *password = empathy_account_settings_get_string (
+  gchar *password;
+
+  password = empathy_account_settings_dup_string (
       self->priv->settings, "password");
 
+  /* We have to do this so that when we call gtk_entry_set_text,
+   * the ::changed callback doesn't think the user made the
+   * change. This is also used in remember_password_toggled_cb. */
+  self->priv->automatic_change = TRUE;
+
   if (password != NULL)
     {
-      /* We have to do this so that when we call gtk_entry_set_text,
-       * the ::changed callback doesn't think the user made the
-       * change. */
-      self->priv->automatic_change = TRUE;
       gtk_entry_set_text (GTK_ENTRY (self->priv->param_password_widget),
           password);
-      self->priv->automatic_change = FALSE;
     }
 
   gtk_toggle_button_set_active (
       GTK_TOGGLE_BUTTON (self->priv->remember_password_widget),
       !EMP_STR_EMPTY (password));
+
+  self->priv->automatic_change = FALSE;
+
+  g_free (password);
 }
 
 static void
@@ -1873,7 +1902,7 @@ do_constructed (GObject *obj)
     const gchar *cm_name;
     const gchar *protocol;
     const char *file;
-    void (*func)(EmpathyAccountWidget *self, const gchar *filename);
+    GtkWidget * (*func)(EmpathyAccountWidget *self, const gchar *filename);
   } widgets [] = {
     { "salut", "local-xmpp", "empathy-account-widget-local-xmpp.ui",
         account_widget_build_salut },
@@ -1887,6 +1916,7 @@ do_constructed (GObject *obj)
     WIDGET (sofiasip, sip),
   };
   const gchar *protocol, *cm_name;
+  GtkWidget *box;
 
   account = empathy_account_settings_get_account (self->priv->settings);
 
@@ -1902,7 +1932,7 @@ do_constructed (GObject *obj)
 
           filename = empathy_file_lookup (widgets[i].file,
               "libempathy-gtk");
-          widgets[i].func (self, filename);
+          box = widgets[i].func (self, filename);
           g_free (filename);
 
           break;
@@ -1913,10 +1943,12 @@ do_constructed (GObject *obj)
     {
       gchar *filename = empathy_file_lookup (
           "empathy-account-widget-generic.ui", "libempathy-gtk");
-      account_widget_build_generic (self, filename);
+      box = account_widget_build_generic (self, filename);
       g_free (filename);
     }
 
+  gtk_container_add (GTK_CONTAINER (self), box);
+
   /* handle default focus */
   if (self->ui_details->default_focus != NULL)
     {
@@ -1941,10 +1973,17 @@ do_constructed (GObject *obj)
         }
       else
         {
+          gchar *password;
+
+          password = empathy_account_settings_dup_string (self->priv->settings,
+              "password");
+
+          /* FIXME: we should enable this checkbox only if the password is
+           * stored for good in the password storage, not only for the session
+           * (bgo #683571) */
           gtk_toggle_button_set_active (
               GTK_TOGGLE_BUTTON (self->priv->remember_password_widget),
-              !EMP_STR_EMPTY (empathy_account_settings_get_string (
-                      self->priv->settings, "password")));
+              !EMP_STR_EMPTY (password));
 
           /* The password might not have been retrieved from the
            * keyring yet. We should update the remember password
@@ -1952,18 +1991,24 @@ do_constructed (GObject *obj)
           tp_g_signal_connect_object (self->priv->settings,
               "password-retrieved",
               G_CALLBACK (account_settings_password_retrieved_cb), self, 0);
+
+          g_free (password);
         }
 
       g_signal_connect (self->priv->remember_password_widget, "toggled",
           G_CALLBACK (remember_password_toggled_cb), self);
 
+      self->priv->automatic_change = TRUE;
       remember_password_toggled_cb (
           GTK_TOGGLE_BUTTON (self->priv->remember_password_widget), self);
+      self->priv->automatic_change = FALSE;
     }
   else if (self->priv->remember_password_widget != NULL
       && !empathy_account_settings_supports_sasl (self->priv->settings))
     {
       gtk_widget_set_visible (self->priv->remember_password_widget, FALSE);
+      empathy_account_settings_set_remember_password (self->priv->settings,
+          TRUE);
     }
 
   /* dup and init the account-manager */
@@ -1994,7 +2039,7 @@ do_constructed (GObject *obj)
   gtk_box_pack_end (GTK_BOX (self->priv->hbox_buttons),
       self->priv->cancel_button, TRUE, TRUE, 3);
 
-  gtk_box_pack_end (GTK_BOX (self->ui_details->widget), self->priv->hbox_buttons, FALSE,
+  gtk_box_pack_end (GTK_BOX (self), self->priv->hbox_buttons, FALSE,
       FALSE, 3);
 
   g_signal_connect (self->priv->cancel_button, "clicked",
@@ -2016,16 +2061,7 @@ do_constructed (GObject *obj)
 
   add_register_buttons (self, account);
 
-  /* hook up to widget destruction to unref ourselves */
-  g_signal_connect (self->ui_details->widget, "destroy",
-      G_CALLBACK (account_widget_destroy_cb), self);
-
-  if (self->ui_details->gui != NULL)
-    {
-      empathy_builder_unref_and_keep_widget (self->ui_details->gui,
-          self->ui_details->widget);
-      self->ui_details->gui = NULL;
-    }
+  g_clear_object (&self->ui_details->gui);
 
   display_name = empathy_account_settings_get_display_name (
       self->priv->settings);
@@ -2180,39 +2216,30 @@ empathy_account_widget_handle_params (EmpathyAccountWidget *self,
   va_end (args);
 }
 
-GtkWidget *
-empathy_account_widget_get_widget (EmpathyAccountWidget *widget)
-{
-  return widget->ui_details->widget;
-}
-
 EmpathyAccountWidget *
 empathy_account_widget_new_for_protocol (EmpathyAccountSettings *settings,
     gboolean simple)
 {
-  EmpathyAccountWidget *self;
-
   g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL);
 
-  self = g_object_new
-    (EMPATHY_TYPE_ACCOUNT_WIDGET,
-        "settings", settings, "simple", simple,
+  return g_object_new (EMPATHY_TYPE_ACCOUNT_WIDGET,
+        "orientation", GTK_ORIENTATION_VERTICAL,
+        "settings", settings,
+        "simple", simple,
         "creating-account",
-        empathy_account_settings_get_account (settings) == NULL,
+          empathy_account_settings_get_account (settings) == NULL,
         NULL);
-
-  return self;
 }
 
 gchar *
 empathy_account_widget_get_default_display_name (EmpathyAccountWidget *self)
 {
-  const gchar *login_id;
+  gchar *login_id;
   const gchar *protocol, *p;
   gchar *default_display_name;
   Service service;
 
-  login_id = empathy_account_settings_get_string (self->priv->settings,
+  login_id = empathy_account_settings_dup_string (self->priv->settings,
       "account");
   protocol = empathy_account_settings_get_protocol (self->priv->settings);
   service = account_widget_get_service (self);
@@ -2266,6 +2293,8 @@ empathy_account_widget_get_default_display_name (EmpathyAccountWidget *self)
       default_display_name = g_strdup (_("New account"));
     }
 
+  g_free (login_id);
+
   return default_display_name;
 }