static void
account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
{
  const gchar *nick = NULL;
  const gchar *fullname = NULL;
  EmpathyAccountSettings *ac_settings;

  g_object_get (settings->self, "settings", &ac_settings, NULL);

  nick = empathy_account_settings_get_string (ac_settings, "account");
  fullname = empathy_account_settings_get_string (ac_settings,
      "fullname");

  if (!nick)
    {
      nick = g_strdup (g_get_user_name ());
      empathy_account_settings_set_string (ac_settings,
        "account", nick);
    }

  if (!fullname)
    {
      fullname = g_strdup (g_get_real_name ());
      if (!fullname)
        {
          fullname = g_strdup (nick);
        }
      empathy_account_settings_set_string (ac_settings,
          "fullname", fullname);
    }
}
static void
account_widget_entry_changed_common (EmpathyAccountWidget *self,
    GtkEntry *entry, gboolean focus)
{
  const gchar *str;
  const gchar *param_name;
  EmpathyAccountWidgetPriv *priv = GET_PRIV (self);

  str = gtk_entry_get_text (entry);
  param_name = g_object_get_data (G_OBJECT (entry), "param_name");

  if (EMP_STR_EMPTY (str))
    {
      const gchar *value = NULL;

      empathy_account_settings_unset (priv->settings, param_name);

      if (focus)
        {
          value = empathy_account_settings_get_string (priv->settings,
              param_name);
          DEBUG ("Unset %s and restore to %s", param_name, value);
          gtk_entry_set_text (entry, value ? value : "");
        }
    }
  else
    {
      DEBUG ("Setting %s to %s", param_name,
          tp_strdiff (param_name, "password") ? str : "***");
      empathy_account_settings_set_string (priv->settings, param_name, str);
    }
}
static void
set_label_from_settings (EmpathyIrcNetworkChooser *self)
{
  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
  const gchar *server;

  tp_clear_object (&priv->network);

  server = empathy_account_settings_get_string (priv->settings, "server");

  if (server != NULL)
    {
      EmpathyIrcServer *srv;
      gint port;
      gboolean ssl;

      priv->network = empathy_irc_network_manager_find_network_by_address (
          priv->network_manager, server);

      if (priv->network != NULL)
        {
          /* The network is known */
          g_object_ref (priv->network);
          set_label (self);
          return;
        }

      /* We don't have this network. Let's create it */
      port = empathy_account_settings_get_uint32 (priv->settings, "port");
      ssl = empathy_account_settings_get_boolean (priv->settings,
          "use-ssl");

      DEBUG ("Create a network %s", server);
      priv->network = empathy_irc_network_new (server);
      srv = empathy_irc_server_new (server, port, ssl);

      empathy_irc_network_append_server (priv->network, srv);
      empathy_irc_network_manager_add (priv->network_manager, priv->network);

      set_label (self);

      g_object_unref (srv);
      return;
    }

  /* Set default network */
  priv->network = empathy_irc_network_manager_find_network_by_address (
          priv->network_manager, DEFAULT_IRC_NETWORK);
  g_assert (priv->network != NULL);

  set_label (self);
  update_server_params (self);
  g_object_ref (priv->network);
}
static void
account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
{
  const gchar *nick = NULL;
  const gchar *fullname = NULL;
  const gchar *server = NULL;
  gint port = 6667;
  const gchar *charset;
  gboolean ssl = FALSE;
  EmpathyIrcNetwork *network = NULL;
  EmpathyAccountSettings *ac_settings;

  g_object_get (settings->self, "settings", &ac_settings, NULL);

  nick = empathy_account_settings_get_string (ac_settings, "account");
  fullname = empathy_account_settings_get_string (ac_settings,
      "fullname");
  server = empathy_account_settings_get_string (ac_settings, "server");
  charset = empathy_account_settings_get_string (ac_settings, "charset");
  port = empathy_account_settings_get_uint32 (ac_settings, "port");
  ssl = empathy_account_settings_get_boolean (ac_settings, "use-ssl");

  if (!nick)
    {
      nick = g_strdup (g_get_user_name ());
      empathy_account_settings_set_string (ac_settings,
        "account", nick);
    }

  if (!fullname)
    {
      fullname = g_strdup (g_get_real_name ());
      if (!fullname)
        {
          fullname = g_strdup (nick);
        }
      empathy_account_settings_set_string (ac_settings,
          "fullname", fullname);
    }

  if (server != NULL)
    {
      GtkListStore *store;

      network = empathy_irc_network_manager_find_network_by_address (
          settings->network_manager, server);


      store = GTK_LIST_STORE (gtk_combo_box_get_model (
            GTK_COMBO_BOX (settings->combobox_network)));

      if (network != NULL)
        {
          gchar *name;

          g_object_set (network, "charset", charset, NULL);

          g_object_get (network, "name", &name, NULL);
          DEBUG ("Account use network %s", name);

          g_free (name);
        }
      else
        {
          /* We don't have this network. Let's create it */
          EmpathyIrcServer *srv;
          GtkTreeIter iter;

          DEBUG ("Create a network %s", server);
          network = empathy_irc_network_new (server);
          srv = empathy_irc_server_new (server, port, ssl);

          empathy_irc_network_append_server (network, srv);
          empathy_irc_network_manager_add (settings->network_manager, network);

          gtk_list_store_insert_with_values (store, &iter, -1,
              COL_NETWORK_OBJ, network,
              COL_NETWORK_NAME, server,
              -1);

          gtk_combo_box_set_active_iter (
              GTK_COMBO_BOX (settings->combobox_network), &iter);

          g_object_unref (srv);
          g_object_unref (network);
        }
    }


  fill_networks_model (settings, network);
}
static void
account_widget_setup_widget (EmpathyAccountWidget *self,
    GtkWidget *widget,
    const gchar *param_name)
{
  EmpathyAccountWidgetPriv *priv = GET_PRIV (self);

  g_object_set_data_full (G_OBJECT (widget), "param_name",
      g_strdup (param_name), g_free);

  if (GTK_IS_SPIN_BUTTON (widget))
    {
      gint value = 0;
      const gchar *signature;

      signature = empathy_account_settings_get_dbus_signature (priv->settings,
          param_name);
      g_return_if_fail (signature != NULL);

      switch ((int)*signature)
        {
          case DBUS_TYPE_INT16:
          case DBUS_TYPE_INT32:
            value = empathy_account_settings_get_int32 (priv->settings,
              param_name);
            break;
          case DBUS_TYPE_INT64:
            value = empathy_account_settings_get_int64 (priv->settings,
              param_name);
            break;
          case DBUS_TYPE_UINT16:
          case DBUS_TYPE_UINT32:
            value = empathy_account_settings_get_uint32 (priv->settings,
              param_name);
            break;
          case DBUS_TYPE_UINT64:
            value = empathy_account_settings_get_uint64 (priv->settings,
                param_name);
            break;
          default:
            g_return_if_reached ();
        }

      gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);

      g_signal_connect (widget, "value-changed",
          G_CALLBACK (account_widget_int_changed_cb),
          self);
    }
  else if (GTK_IS_ENTRY (widget))
    {
      const gchar *str = NULL;

      str = empathy_account_settings_get_string (priv->settings, param_name);
      gtk_entry_set_text (GTK_ENTRY (widget), str ? str : "");

      if (strstr (param_name, "password"))
        {
          gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
        }

      g_signal_connect (widget, "changed",
          G_CALLBACK (account_widget_entry_changed_cb), self);
    }
  else if (GTK_IS_TOGGLE_BUTTON (widget))
    {
      gboolean value = FALSE;

      value = empathy_account_settings_get_boolean (priv->settings,
          param_name);
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value);

      g_signal_connect (widget, "toggled",
          G_CALLBACK (account_widget_checkbutton_toggled_cb),
          self);
    }
  else
    {
      DEBUG ("Unknown type of widget for param %s", param_name);
    }
}
static void
do_constructed (GObject *obj)
{
  EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj);
  EmpathyAccountWidgetPriv *priv = GET_PRIV (self);
  TpAccount *account;
  const gchar *protocol, *cm_name;
  guint i = 0;
  struct {
    const gchar *cm_name;
    const gchar *protocol;
    const char *file;
    void (*func)(EmpathyAccountWidget *self, const gchar *filename);
  } widgets [] = {
    { "salut", "local-xmpp", "empathy-account-widget-local-xmpp.ui",
        account_widget_build_salut },
    WIDGET (gabble, jabber),
    WIDGET (butterfly, msn),
    WIDGET (haze, icq),
    WIDGET (haze, aim),
    WIDGET (haze, yahoo),
    WIDGET (haze, groupwise),
    WIDGET (idle, irc),
    WIDGET (sofiasip, sip),
  };

  cm_name = empathy_account_settings_get_cm (priv->settings);
  protocol = empathy_account_settings_get_protocol (priv->settings);

  for (i = 0 ; i < G_N_ELEMENTS (widgets); i++)
    {
      if (!tp_strdiff (widgets[i].cm_name, cm_name) &&
          !tp_strdiff (widgets[i].protocol, protocol))
        {
          gchar *filename;

          filename = empathy_file_lookup (widgets[i].file,
              "libempathy-gtk");
          widgets[i].func (self, filename);
          g_free (filename);

          break;
        }
    }

  if (i == G_N_ELEMENTS (widgets))
    {
      gchar *filename = empathy_file_lookup (
          "empathy-account-widget-generic.ui", "libempathy-gtk");
      account_widget_build_generic (self, filename);
      g_free (filename);
    }

  /* handle default focus */
  if (self->ui_details->default_focus != NULL)
    {
      GObject *default_focus_entry;

      default_focus_entry = gtk_builder_get_object
        (self->ui_details->gui, self->ui_details->default_focus);
      g_signal_connect (default_focus_entry, "realize",
          G_CALLBACK (gtk_widget_grab_focus),
          NULL);
    }

  /* handle forget button */
  if (self->ui_details->add_forget)
    {
      const gchar *password = NULL;

      priv->button_forget = GTK_WIDGET (gtk_builder_get_object
          (self->ui_details->gui, "button_forget"));
      priv->entry_password = GTK_WIDGET (gtk_builder_get_object
          (self->ui_details->gui, "entry_password"));

      password = empathy_account_settings_get_string (priv->settings,
          "password");
      gtk_widget_set_sensitive (priv->button_forget,
          !EMP_STR_EMPTY (password));

      g_signal_connect (priv->button_forget, "clicked",
          G_CALLBACK (account_widget_forget_clicked_cb),
          self);
      g_signal_connect (priv->entry_password, "changed",
          G_CALLBACK (account_widget_password_changed_cb),
          self);
    }

  /* handle apply and cancel button */
  if (!priv->simple)
    {
      GtkWidget *hbox = gtk_hbox_new (TRUE, 3);

      priv->cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);

      if (priv->creating_account)
        {
          TpConnectionPresenceType state;
          priv->idle = empathy_idle_dup_singleton ();

          empathy_signal_connect_weak (priv->idle, "notify::state",
              G_CALLBACK (idle_state_change_cb), obj);

          state = empathy_idle_get_state (priv->idle);

          if (state > TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
            {
              /* We are online, display a Login button */
              GtkWidget *image;

              priv->apply_button = gtk_button_new_with_mnemonic (_("L_og in"));
              image = gtk_image_new_from_stock (GTK_STOCK_CONNECT,
                  GTK_ICON_SIZE_BUTTON);
              gtk_button_set_image (GTK_BUTTON (priv->apply_button), image);
            }
          else
            {
              /* We are offline, display a Save button */
              priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
            }
        }
      else
        {
          /* We are editing an existing account, display an Apply button */
          priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
        }

      gtk_box_pack_end (GTK_BOX (hbox), priv->apply_button, TRUE,
          TRUE, 3);
      gtk_box_pack_end (GTK_BOX (hbox), priv->cancel_button, TRUE,
          TRUE, 3);

      gtk_box_pack_end (GTK_BOX (self->ui_details->widget), hbox, FALSE,
          FALSE, 3);

      g_signal_connect (priv->cancel_button, "clicked",
          G_CALLBACK (account_widget_cancel_clicked_cb),
          self);
      g_signal_connect (priv->apply_button, "clicked",
          G_CALLBACK (account_widget_apply_clicked_cb),
          self);
      gtk_widget_show_all (hbox);

      if (priv->creating_account)
        /* When creating an account, the user might have nothing to enter.
         * That means that no control interaction might occur,
         * so we update the control button sensitivity manually.
         */
        account_widget_handle_control_buttons_sensitivity (self);
      else
        account_widget_set_control_buttons_sensitivity (self, FALSE);
    }

  account = empathy_account_settings_get_account (priv->settings);

  if (account != NULL)
    {
      g_signal_connect (account, "notify::enabled",
          G_CALLBACK (empathy_account_widget_enabled_cb), self);
    }

  /* handle the "Enabled" checkbox. We only add it when modifying an account */
  if (!priv->creating_account && priv->table_common_settings != NULL)
    {
#ifdef HAVE_MOBLIN
      GtkWidget *w;
#endif
      guint nb_rows, nb_columns;
      gboolean is_enabled;

      is_enabled = tp_account_is_enabled (account);

#ifndef HAVE_MOBLIN
      priv->enabled_checkbox =
          gtk_check_button_new_with_label (_("Enabled"));

      gtk_toggle_button_set_active (
          GTK_TOGGLE_BUTTON (priv->enabled_checkbox), is_enabled);
#else
      /* Translators: this is used only when built on a moblin platform */
      w = gtk_label_new (_("Account:"));
      gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);

      priv->enabled_checkbox = nbtk_gtk_light_switch_new ();

      nbtk_gtk_light_switch_set_active (
          NBTK_GTK_LIGHT_SWITCH (priv->enabled_checkbox), is_enabled);

      gtk_widget_show (w);
#endif /* HAVE_MOBLIN */

      g_object_get (priv->table_common_settings, "n-rows", &nb_rows,
          "n-columns", &nb_columns, NULL);

      gtk_table_resize (GTK_TABLE (priv->table_common_settings), ++nb_rows,
          nb_columns);

#ifndef HAVE_MOBLIN
      gtk_table_attach (GTK_TABLE (priv->table_common_settings),
          priv->enabled_checkbox,
          0, nb_columns, nb_rows - 1, nb_rows,
          GTK_EXPAND | GTK_FILL, 0, 0, 0);
#else
      gtk_table_attach (GTK_TABLE (priv->table_common_settings),
          w,
          0, 1, nb_rows - 1, nb_rows,
          GTK_FILL, 0, 0, 0);
      gtk_table_attach (GTK_TABLE (priv->table_common_settings),
          priv->enabled_checkbox,
          1, nb_columns, nb_rows - 1, nb_rows,
          GTK_EXPAND | GTK_FILL, 0, 0, 0);
#endif /* HAVE_MOBLIN */

      gtk_widget_show (priv->enabled_checkbox);

#ifndef HAVE_MOBLIN
      g_signal_connect (G_OBJECT (priv->enabled_checkbox), "released",
          G_CALLBACK (account_widget_enabled_released_cb), self);
#else
      g_signal_connect (G_OBJECT (priv->enabled_checkbox), "switch-flipped",
          G_CALLBACK (account_widget_switch_flipped_cb), self);
#endif /* HAVE_MOBLIN */
    }

  /* hook up to widget destruction to unref ourselves */
  g_signal_connect (self->ui_details->widget, "destroy",
      G_CALLBACK (account_widget_destroy_cb), self);

  empathy_builder_unref_and_keep_widget (self->ui_details->gui,
      self->ui_details->widget);
  self->ui_details->gui = NULL;
}
EmpathyIrcNetworkChooser *
empathy_account_widget_irc_build (EmpathyAccountWidget *self,
    const char *filename,
    GtkWidget **table_common_settings)
{
  EmpathyAccountWidgetIrc *settings;
  EmpathyAccountSettings *ac_settings;
  GtkWidget *entry_password;
  const gchar *password;

  settings = g_slice_new0 (EmpathyAccountWidgetIrc);
  settings->self = self;

  self->ui_details->gui = empathy_builder_get_file (filename,
      "table_irc_settings", table_common_settings,
      "vbox_irc", &self->ui_details->widget,
      "table_irc_settings", &settings->vbox_settings,
      "entry_password", &entry_password,
      NULL);

  /* Add network chooser button */
  g_object_get (settings->self, "settings", &ac_settings, NULL);

  settings->network_chooser = empathy_irc_network_chooser_new (ac_settings);

  g_signal_connect (settings->network_chooser, "changed",
      G_CALLBACK (network_changed_cb), settings);

  gtk_table_attach (GTK_TABLE (*table_common_settings),
      settings->network_chooser, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);

  gtk_widget_show (settings->network_chooser);

  account_widget_irc_setup (settings);

  empathy_account_widget_handle_params (self,
      "entry_nick", "account",
      "entry_fullname", "fullname",
      "entry_password", "password",
      "entry_quit_message", "quit-message",
      NULL);

  empathy_builder_connect (self->ui_details->gui, settings,
      "table_irc_settings", "destroy", account_widget_irc_destroy_cb,
      NULL);

  self->ui_details->default_focus = g_strdup ("entry_nick");

  g_object_unref (ac_settings);

  /* Automatically set password-prompt when needed */
  password = empathy_account_settings_get_string (ac_settings, "password");

  if (set_password_prompt_if_needed (ac_settings, password))
    {
      /* Apply right now to save password-prompt */
      empathy_account_settings_apply_async (ac_settings, NULL, NULL);
    }

  g_signal_connect (entry_password, "changed",
      G_CALLBACK (entry_password_changed_cb), settings);

  return EMPATHY_IRC_NETWORK_CHOOSER (settings->network_chooser);
}
static void
protocol_changed_cb (GtkComboBox *chooser,
    EmpathyNewAccountDialog *self)
{
  EmpathyAccountSettings *settings;
  GtkWidget *account_widget;
  EmpathyAccountWidget *widget_object;
  gchar *password = NULL, *account = NULL;

  settings = empathy_protocol_chooser_create_account_settings (
      EMPATHY_PROTOCOL_CHOOSER (chooser));

  if (settings == NULL)
    return;

  /* Save "account" and "password" parameters */
  if (self->priv->settings != NULL)
    {
      account = g_strdup (empathy_account_settings_get_string (
            self->priv->settings, "account"));

      password = g_strdup (empathy_account_settings_get_string (
            self->priv->settings, "password"));

      g_object_unref (self->priv->settings);
    }

  widget_object = empathy_account_widget_new_for_protocol (settings, TRUE);
  account_widget = empathy_account_widget_get_widget (widget_object);

  if (self->priv->current_account_widget != NULL)
    {
      g_signal_handlers_disconnect_by_func (self->priv->current_widget_object,
          account_created_cb, self);
      g_signal_handlers_disconnect_by_func (self->priv->current_widget_object,
          cancelled_cb, self);

      gtk_widget_destroy (self->priv->current_account_widget);
    }

  self->priv->current_account_widget = account_widget;
  self->priv->current_widget_object = widget_object;

  self->priv->settings = settings;

  g_signal_connect (self->priv->current_widget_object, "account-created",
      G_CALLBACK (account_created_cb), self);
  g_signal_connect (self->priv->current_widget_object, "cancelled",
      G_CALLBACK (cancelled_cb), self);

  /* Restore "account" and "password" parameters in the new widget */
  if (account != NULL)
    {
      empathy_account_widget_set_account_param (widget_object, account);
      g_free (account);
    }

  if (password != NULL)
    {
      empathy_account_widget_set_password_param (widget_object, password);
      g_free (password);
    }

  gtk_box_pack_start (GTK_BOX (self->priv->main_vbox), account_widget,
      FALSE, FALSE, 0);
  gtk_widget_show (account_widget);
}