static GoaObject *
add_account (GoaProvider  *provider,
             GoaClient    *client,
             GtkDialog    *dialog,
             GtkBox       *vbox,
             GError      **error)
{
  GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (provider)->priv;
  AddAccountData data;
  TpawAccountSettings *settings = NULL;
  TpawAccountWidget *account_widget = NULL;
  GtkRequisition req;
  gint response;

  settings = tpaw_protocol_create_account_settings (priv->protocol);
  if (settings == NULL)
    {
      g_set_error (&data.error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED,
                   _("Failed to create a user interface for %s"),
                   priv->protocol != NULL ?
                      tpaw_protocol_get_protocol_name (priv->protocol) :
                      "(null)");
      return NULL;
    }

  memset (&data, 0, sizeof (AddAccountData));
  data.cancellable = g_cancellable_new ();
  data.loop = g_main_loop_new (NULL, FALSE);
  data.error = NULL;
  data.provider = GOA_TELEPATHY_PROVIDER (provider);
  data.dialog = dialog;
  data.vbox = vbox;

  goa_client_new (data.cancellable, goa_client_new_cb, &data);
  wait_for_account_settings_ready (settings, data.loop);

  account_widget = tpaw_account_widget_new_for_protocol (settings,
      dialog, TRUE);
  gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (account_widget), FALSE, FALSE, 0);
  gtk_widget_show (GTK_WIDGET (account_widget));
  g_signal_connect (account_widget, "account-created",
      G_CALLBACK (tp_account_created_cb), &data);
  g_signal_connect (account_widget, "close",
      G_CALLBACK (account_widget_close_cb), &data);

  /* The dialog now contains a lot of empty space between the account widget
   * and the buttons. We force it's vertical size to be just right to fit the
   * widget. */
  gtk_widget_get_preferred_size (GTK_WIDGET (dialog), NULL, &req);
  gtk_widget_set_size_request (GTK_WIDGET (dialog), req.width, 1);

  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_APPLY)
    {
      g_set_error (&data.error,
                   GOA_ERROR,
                   GOA_ERROR_DIALOG_DISMISSED,
                   _("Dialog was dismissed"));
      goto out;
    }

  if (data.error != NULL)
    {
      /* An error could have been set by a callback */
      goto out;
    }

  if (data.ret == NULL && !g_cancellable_is_cancelled (data.cancellable))
    {
      /* We wait for the account to be created */
      g_main_loop_run (data.loop);
    }

out:
  if (data.error != NULL)
    g_propagate_error (error, data.error);
  else
    g_assert (data.ret != NULL);

  if (data.cancellable != NULL)
    {
      g_cancellable_cancel (data.cancellable);
      g_object_unref (data.cancellable);
    }

  if (data.goa_account_added_id)
    g_signal_handler_disconnect (data.goa_client, data.goa_account_added_id);

  g_clear_pointer (&data.loop, g_main_loop_unref);
  g_clear_object (&data.goa_client);
  g_clear_object (&data.tp_account);

  return data.ret;
}
static gboolean
edit_connection_parameters (GoaObject  *goa_object,
                            GtkWindow  *parent,
                            GError    **out_error)
{
  GMainLoop *loop = NULL;
  TpAccount *tp_account = NULL;
  TpawAccountSettings *settings = NULL;
  GtkWidget *dialog = NULL;
  TpawAccountWidget *account_widget = NULL;
  GtkWidget *content_area = NULL;
  GtkWidget *align = NULL;
  gboolean ret;
  GError *error = NULL;

  loop = g_main_loop_new (NULL, FALSE);

  tp_account = find_tp_account (goa_object, loop, &error);
  if (tp_account == NULL)
    goto out;

  settings = tpaw_account_settings_new_for_account (tp_account);
  wait_for_account_settings_ready (settings, loop);

  dialog = gtk_dialog_new_with_buttons (_("Connection Settings"),
      parent,
      GTK_DIALOG_MODAL
      | GTK_DIALOG_DESTROY_WITH_PARENT
      | GTK_DIALOG_USE_HEADER_BAR,
      NULL, NULL);
  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);

  account_widget = tpaw_account_widget_new_for_protocol (settings,
      GTK_DIALOG (dialog), FALSE);
  g_signal_connect (account_widget, "cancelled",
      G_CALLBACK (account_dialog_widget_cancelled_cb), &error);
  g_signal_connect_swapped (account_widget, "close",
      G_CALLBACK (g_main_loop_quit), loop);

  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

  align = gtk_alignment_new (0.5, 0.5, 1, 1);
  gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 0, 6, 6);

  gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (account_widget));
  gtk_box_pack_start (GTK_BOX (content_area), align, TRUE, TRUE, 0);

  gtk_widget_show (GTK_WIDGET (account_widget));
  gtk_widget_show (align);
  gtk_widget_show (dialog);

  /* Wait for the dialog to be dismissed */
  g_main_loop_run (loop);

  gtk_widget_destroy (dialog);

out:
  if (error != NULL)
    {
      g_propagate_error (out_error, error);
      ret = FALSE;
    }
  else
    {
      ret = TRUE;
    }

  g_clear_object (&settings);
  g_clear_object (&tp_account);
  g_clear_pointer (&loop, g_main_loop_unref);

  return ret;
}
static void
empathy_local_xmpp_assistant_widget_constructed (GObject *object)
{
  EmpathyLocalXmppAssistantWidget *self = (EmpathyLocalXmppAssistantWidget *)
    object;
  GtkWidget *w;
  GdkPixbuf *pix;
  TpawAccountWidget *account_widget;
  gchar *markup;

  G_OBJECT_CLASS (empathy_local_xmpp_assistant_widget_parent_class)->
    constructed (object);

  gtk_container_set_border_width (GTK_CONTAINER (self), 12);

  w = gtk_label_new (
      _("Empathy can automatically discover and chat with the people "
        "connected on the same network as you. "
        "If you want to use this feature, please check that the "
        "details below are correct."));
  gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
  gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
  gtk_label_set_max_width_chars (GTK_LABEL (w), 60);
  gtk_grid_attach (GTK_GRID (self), w, 0, 0, 1, 1);
  gtk_widget_show (w);

  pix = tpaw_pixbuf_from_icon_name_sized ("im-local-xmpp", 48);
  if (pix != NULL)
    {
      w = gtk_image_new_from_pixbuf (pix);
      gtk_grid_attach (GTK_GRID (self), w, 1, 0, 1, 1);
      gtk_widget_show (w);

      g_object_unref (pix);
    }

  self->priv->settings = tpaw_account_settings_new ("salut", "local-xmpp",
      NULL, _("People nearby"));

  account_widget = tpaw_account_widget_new_for_protocol (
      self->priv->settings, NULL, TRUE);
  tpaw_account_widget_hide_buttons (account_widget);

  g_signal_connect (account_widget, "handle-apply",
      G_CALLBACK (handle_apply_cb), self);

  gtk_grid_attach (GTK_GRID (self), GTK_WIDGET (account_widget), 0, 1, 2, 1);
  gtk_widget_show (GTK_WIDGET (account_widget));

  w = gtk_label_new (NULL);
  markup = g_strdup_printf (
      "<span size=\"small\">%s</span>",
      _("You can change these details later or disable this feature "
        "by choosing <span style=\"italic\">Edit → Accounts</span> "
        "in the Contact List."));
  gtk_label_set_markup (GTK_LABEL (w), markup);
  g_free (markup);
  gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
  gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
  gtk_grid_attach (GTK_GRID (self), w, 0, 2, 2, 1);
  gtk_widget_show (w);
}