]> git.0d.be Git - empathy.git/blobdiff - src/empathy-accounts-dialog.c
Merge branch 'sasl'
[empathy.git] / src / empathy-accounts-dialog.c
index 3d8aed9fd2cfa577af06f02b4d533c4a80b206ab..8eda73bb41ac3615955cdb16b83047e4cd8baa23 100644 (file)
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-connection-managers.h>
 #include <libempathy/empathy-connectivity.h>
-#include <libempathy-gtk/empathy-ui-utils.h>
 
+#include <libempathy-gtk/empathy-ui-utils.h>
 #include <libempathy-gtk/empathy-protocol-chooser.h>
 #include <libempathy-gtk/empathy-account-widget.h>
 #include <libempathy-gtk/empathy-account-widget-irc.h>
 #include <libempathy-gtk/empathy-account-widget-sip.h>
 #include <libempathy-gtk/empathy-cell-renderer-activatable.h>
-#include <libempathy-gtk/empathy-conf.h>
 #include <libempathy-gtk/empathy-images.h>
 
 #include "empathy-accounts-dialog.h"
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog)
 G_DEFINE_TYPE (EmpathyAccountsDialog, empathy_accounts_dialog, GTK_TYPE_DIALOG);
 
+enum
+{
+  NOTEBOOK_PAGE_ACCOUNT = 0,
+  NOTEBOOK_PAGE_LOADING
+};
+
 typedef struct {
   GtkWidget *alignment_settings;
   GtkWidget *alignment_infobar;
@@ -96,6 +101,10 @@ typedef struct {
   GtkWidget *label_type;
   GtkWidget *settings_widget;
 
+  GtkWidget *notebook_account;
+  GtkWidget *spinner;
+  gboolean loading;
+
   /* We have to keep a reference on the actual EmpathyAccountWidget, not just
    * his GtkWidget. It is the only reliable source we can query to know if
    * there are any unsaved changes to the currently selected account. We can't
@@ -112,6 +121,7 @@ typedef struct {
 
   TpAccountManager *account_manager;
   EmpathyConnectionManagers *cms;
+  EmpathyConnectivity *connectivity;
 
   GtkWindow *parent_window;
   TpAccount *initial_selection;
@@ -123,8 +133,6 @@ typedef struct {
    * EmpathyAccountsDialog object. */
   gboolean force_change_row;
   GtkTreeRowReference *destination_row;
-
-  gboolean dispose_has_run;
 } EmpathyAccountsDialogPriv;
 
 enum {
@@ -189,18 +197,27 @@ accounts_dialog_update_name_label (EmpathyAccountsDialog *dialog,
   g_free (text);
 }
 
+static void
+accounts_dialog_status_infobar_set_message (EmpathyAccountsDialog *dialog,
+    const gchar *message)
+{
+  EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
+  gchar *message_markup;
+
+  message_markup = g_markup_printf_escaped ("<i>%s</i>", message);
+  gtk_label_set_markup (GTK_LABEL (priv->label_status), message_markup);
+  g_free (message_markup);
+}
+
 static void
 accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
     TpAccount *account)
 {
   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-  const gchar               *message;
-  gchar                     *message_markup;
   gchar                     *status_message = NULL;
   guint                     status;
   guint                     reason;
   guint                     presence;
-  EmpathyConnectivity       *connectivity;
   GtkTreeView               *view;
   GtkTreeModel              *model;
   GtkTreeSelection          *selection;
@@ -259,7 +276,8 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
       switch (status)
         {
           case TP_CONNECTION_STATUS_CONNECTING:
-            message = _("Connecting…");
+            accounts_dialog_status_infobar_set_message (dialog,
+                _("Connecting…"));
             gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                 GTK_MESSAGE_INFO);
 
@@ -270,14 +288,24 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
           case TP_CONNECTION_STATUS_CONNECTED:
             if (g_strcmp0 (status_message, "") == 0)
               {
+                gchar *message;
+
                 message = g_strdup_printf ("%s",
                     empathy_presence_get_default_message (presence));
+
+                accounts_dialog_status_infobar_set_message (dialog, message);
+                g_free (message);
               }
             else
               {
+                gchar *message;
+
                 message = g_strdup_printf ("%s — %s",
                     empathy_presence_get_default_message (presence),
                     status_message);
+
+                accounts_dialog_status_infobar_set_message (dialog, message);
+                g_free (message);
               }
             gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                 GTK_MESSAGE_INFO);
@@ -286,33 +314,41 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
             gtk_widget_hide (priv->throbber);
             break;
           case TP_CONNECTION_STATUS_DISCONNECTED:
-            message = g_strdup_printf (_("Disconnected — %s"),
-                empathy_status_reason_get_default_message (reason));
-
             if (reason == TP_CONNECTION_STATUS_REASON_REQUESTED)
               {
+                gchar *message;
+
                 message = g_strdup_printf (_("Offline — %s"),
-                    empathy_status_reason_get_default_message (reason));
+                    empathy_account_get_error_message (account, NULL));
                 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                     GTK_MESSAGE_WARNING);
+
+                accounts_dialog_status_infobar_set_message (dialog, message);
+                g_free (message);
               }
             else
               {
+                gchar *message;
+
+                message = g_strdup_printf (_("Disconnected — %s"),
+                    empathy_account_get_error_message (account, NULL));
                 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                     GTK_MESSAGE_ERROR);
+
+                accounts_dialog_status_infobar_set_message (dialog, message);
+                g_free (message);
               }
 
-            connectivity = empathy_connectivity_dup_singleton ();
-            if (!empathy_connectivity_is_online (connectivity))
-               message = _("Offline — No Network Connection");
+            if (!empathy_connectivity_is_online (priv->connectivity))
+               accounts_dialog_status_infobar_set_message (dialog,
+                    _("Offline — No Network Connection"));
 
-            g_object_unref (connectivity);
             gtk_spinner_stop (GTK_SPINNER (priv->throbber));
             gtk_widget_show (priv->image_status);
             gtk_widget_hide (priv->throbber);
             break;
           default:
-            message = _("Unknown Status");
+            accounts_dialog_status_infobar_set_message (dialog, _("Unknown Status"));
             gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                 GTK_MESSAGE_WARNING);
 
@@ -323,7 +359,8 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
     }
   else
     {
-      message = _("Offline — Account Disabled");
+      accounts_dialog_status_infobar_set_message (dialog,
+          _("Offline — Account Disabled"));
 
       gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
           GTK_MESSAGE_WARNING);
@@ -332,8 +369,6 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
       gtk_widget_hide (priv->throbber);
     }
 
-  message_markup = g_markup_printf_escaped ("<i>%s</i>", message);
-  gtk_label_set_markup (GTK_LABEL (priv->label_status), message_markup);
   gtk_widget_show (priv->label_status);
 
   if (!creating_account)
@@ -342,7 +377,6 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
     gtk_widget_hide (priv->infobar);
 
   g_free (status_message);
-  g_free (message_markup);
 }
 
 void
@@ -447,7 +481,7 @@ account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog,
     EmpathyAccountSettings *settings)
 {
   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-  gchar                     *icon_name;
+  const gchar               *icon_name;
   TpAccount                 *account;
 
   priv->setting_widget_object =
@@ -549,52 +583,11 @@ accounts_dialog_setup_ui_to_add_account (EmpathyAccountsDialog *dialog)
 {
   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
   EmpathyAccountSettings *settings;
-  gchar *str;
-  const gchar *name, *display_name;
-  TpConnectionManager *cm;
-  TpConnectionManagerProtocol *proto;
-  gboolean is_gtalk, is_facebook;
-
-  cm = empathy_protocol_chooser_dup_selected (
-      EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto, &is_gtalk,
-      &is_facebook);
-  if (cm == NULL)
-    return;
-
-  if (is_gtalk)
-    name = "gtalk";
-  else if (is_facebook)
-    name ="facebook";
-  else
-    name = proto->name;
 
-  display_name = empathy_protocol_name_to_display_name (name);
-  if (display_name == NULL)
-    display_name = proto->name;
-
-  /* Create account */
-  /* To translator: %s is the name of the protocol, such as "Google Talk" or
-   * "Yahoo!"
-   */
-  str = g_strdup_printf (_("New %s account"), display_name);
-  settings = empathy_account_settings_new (cm->name, proto->name, str);
-
-  g_free (str);
-
-  if (is_gtalk)
-    {
-      empathy_account_settings_set_icon_name_async (settings, "im-google-talk",
-          NULL, NULL);
-      /* We should not have to set the server but that may cause issue with
-       * buggy router. */
-      empathy_account_settings_set_string (settings, "server",
-          "talk.google.com");
-    }
-  else if (is_facebook)
-    {
-      empathy_account_settings_set_icon_name_async (settings, "im-facebook",
-          NULL, NULL);
-    }
+  settings = empathy_protocol_chooser_create_account_settings (
+      EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol));
+  if (settings == NULL)
+    return;
 
   accounts_dialog_add (dialog, settings);
   accounts_dialog_model_set_selected (dialog, settings);
@@ -602,7 +595,6 @@ accounts_dialog_setup_ui_to_add_account (EmpathyAccountsDialog *dialog)
   gtk_widget_show_all (priv->hbox_protocol);
 
   g_object_unref (settings);
-  g_object_unref (cm);
 }
 
 static void
@@ -1276,7 +1268,8 @@ accounts_dialog_model_selection_changed (GtkTreeSelection *selection,
     }
 
   /* Update remove button sensitivity */
-  gtk_widget_set_sensitive (priv->button_remove, is_selection && !creating);
+  gtk_widget_set_sensitive (priv->button_remove, is_selection && !creating &&
+      !priv->loading);
 }
 
 static void
@@ -1831,6 +1824,29 @@ accounts_dialog_set_selected_account (EmpathyAccountsDialog *dialog,
     gtk_tree_selection_select_iter (selection, &iter);
 }
 
+static void
+finished_loading (EmpathyAccountsDialog *self)
+{
+  EmpathyAccountsDialogPriv *priv = GET_PRIV (self);
+  GtkTreeSelection *selection;
+  gboolean has_selected;
+
+  priv->loading = FALSE;
+
+  gtk_widget_set_sensitive (priv->button_add, TRUE);
+  gtk_widget_set_sensitive (priv->button_import, TRUE);
+  gtk_widget_set_sensitive (priv->treeview, TRUE);
+
+  /* Sensitive the remove button if there is an account selected */
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+  has_selected = gtk_tree_selection_get_selected (selection, NULL, NULL);
+  gtk_widget_set_sensitive (priv->button_remove, has_selected);
+
+  gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook_account),
+      NOTEBOOK_PAGE_ACCOUNT);
+}
+
 static void
 accounts_dialog_cms_prepare_cb (GObject *source,
     GAsyncResult *result,
@@ -1841,7 +1857,7 @@ accounts_dialog_cms_prepare_cb (GObject *source,
   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
 
   if (!empathy_connection_managers_prepare_finish (cms, result, NULL))
-    return;
+    goto out;
 
   accounts_dialog_update_settings (dialog, NULL);
 
@@ -1851,6 +1867,9 @@ accounts_dialog_cms_prepare_cb (GObject *source,
       g_object_unref (priv->initial_selection);
       priv->initial_selection = NULL;
     }
+
+out:
+  finished_loading (dialog);
 }
 
 static void
@@ -1957,6 +1976,7 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
   EmpathyAccountsDialogPriv    *priv = GET_PRIV (dialog);
   GtkWidget                    *content_area;
   GtkWidget *action_area, *vbox, *hbox, *align;
+  GtkWidget *alig;
 
   filename = empathy_file_lookup ("empathy-accounts-dialog.ui", "src");
 
@@ -1971,6 +1991,8 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
       "button_remove", &priv->button_remove,
       "button_import", &priv->button_import,
       "hbox_protocol", &priv->hbox_protocol,
+      "notebook_account", &priv->notebook_account,
+      "alignment_loading", &alig,
       NULL);
   g_free (filename);
 
@@ -1984,7 +2006,7 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
 
   content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 
-  gtk_container_add (GTK_CONTAINER (content_area), top_hbox);
+  gtk_box_pack_start (GTK_BOX (content_area), top_hbox, TRUE, TRUE, 0);
 
   g_object_unref (gui);
 
@@ -1995,9 +2017,28 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
   gtk_widget_hide (priv->button_remove);
 #endif /* HAVE_MEEGO */
 
-  /* Remove button is unsensitive until we have a selected account */
+  /* Display loading page */
+  priv->loading = TRUE;
+
+  priv->spinner = gtk_spinner_new ();
+
+  gtk_spinner_start (GTK_SPINNER (priv->spinner));
+  gtk_widget_show (priv->spinner);
+
+  gtk_container_add (GTK_CONTAINER (alig), priv->spinner);
+
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook_account),
+      NOTEBOOK_PAGE_LOADING);
+
+  /* Remove button is insensitive until we have a selected account */
   gtk_widget_set_sensitive (priv->button_remove, FALSE);
 
+  /* Add and Import buttons and treeview are insensitive while the dialog
+   * is loading */
+  gtk_widget_set_sensitive (priv->button_add, FALSE);
+  gtk_widget_set_sensitive (priv->button_import, FALSE);
+  gtk_widget_set_sensitive (priv->treeview, FALSE);
+
   priv->combobox_protocol = empathy_protocol_chooser_new ();
   gtk_box_pack_start (GTK_BOX (priv->hbox_protocol), priv->combobox_protocol,
       TRUE, TRUE, 0);
@@ -2068,8 +2109,6 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
 
   gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
 
-  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-
   /* add dialog buttons */
   gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), GTK_BUTTONBOX_END);
 
@@ -2090,38 +2129,12 @@ do_dispose (GObject *obj)
 {
   EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (obj);
   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-  GtkTreeModel *model;
-
-  if (priv->dispose_has_run)
-    return;
-
-  priv->dispose_has_run = TRUE;
-
-  /* Disconnect signals */
-  model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
-  g_signal_handlers_disconnect_by_func (model,
-      accounts_dialog_accounts_model_row_inserted_cb, dialog);
-  g_signal_handlers_disconnect_by_func (model,
-      accounts_dialog_accounts_model_row_deleted_cb, dialog);
-
-  g_signal_handlers_disconnect_by_func (priv->account_manager,
-      accounts_dialog_account_validity_changed_cb,
-      dialog);
-  g_signal_handlers_disconnect_by_func (priv->account_manager,
-      accounts_dialog_account_removed_cb,
-      dialog);
-  g_signal_handlers_disconnect_by_func (priv->account_manager,
-      accounts_dialog_account_enabled_cb,
-      dialog);
-  g_signal_handlers_disconnect_by_func (priv->account_manager,
-      accounts_dialog_account_disabled_cb,
-      dialog);
-  g_signal_handlers_disconnect_by_func (priv->account_manager,
-      accounts_dialog_manager_ready_cb,
-      dialog);
 
-  if (priv->connecting_id)
-    g_source_remove (priv->connecting_id);
+  if (priv->connecting_id != 0)
+    {
+      g_source_remove (priv->connecting_id);
+      priv->connecting_id = 0;
+    }
 
   if (priv->account_manager != NULL)
     {
@@ -2135,9 +2148,17 @@ do_dispose (GObject *obj)
       priv->cms = NULL;
     }
 
+  if (priv->connectivity)
+    {
+      g_object_unref (priv->connectivity);
+      priv->connectivity = NULL;
+    }
+
   if (priv->initial_selection != NULL)
-    g_object_unref (priv->initial_selection);
-  priv->initial_selection = NULL;
+    {
+      g_object_unref (priv->initial_selection);
+      priv->initial_selection = NULL;
+    }
 
   G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->dispose (obj);
 }
@@ -2183,7 +2204,6 @@ do_constructed (GObject *object)
 {
   EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (object);
   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-  gboolean import_asked;
   GtkTreeModel *model;
 
   accounts_dialog_build_ui (dialog);
@@ -2201,24 +2221,7 @@ do_constructed (GObject *object)
   tp_account_manager_prepare_async (priv->account_manager, NULL,
       accounts_dialog_manager_ready_cb, dialog);
 
-  empathy_conf_get_bool (empathy_conf_get (),
-      EMPATHY_PREFS_IMPORT_ASKED, &import_asked);
-
-  if (empathy_import_accounts_to_import ())
-    {
-      gtk_widget_show (priv->button_import);
-
-      if (!import_asked)
-        {
-          GtkWidget *import_dialog;
-
-          empathy_conf_set_bool (empathy_conf_get (),
-              EMPATHY_PREFS_IMPORT_ASKED, TRUE);
-          import_dialog = empathy_import_dialog_new (GTK_WINDOW (dialog),
-              FALSE);
-          gtk_widget_show (import_dialog);
-        }
-    }
+  priv->connectivity = empathy_connectivity_dup_singleton ();
 }
 
 static void
@@ -2289,7 +2292,7 @@ empathy_accounts_dialog_show_application (GdkScreen *screen,
     gboolean hidden)
 {
   GError *error = NULL;
-  gchar *argv[4] = { NULL, };
+  const gchar *argv[4] = { NULL, };
   gint i = 0;
   gchar *account_option = NULL;
   gchar *path;
@@ -2331,7 +2334,7 @@ empathy_accounts_dialog_show_application (GdkScreen *screen,
     selected_account == NULL ? "<none selected>" :
       tp_proxy_get_object_path (TP_PROXY (selected_account)));
 
-  gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
+  gdk_spawn_on_screen (screen, NULL, (gchar**) argv, NULL, G_SPAWN_SEARCH_PATH,
       NULL, NULL, NULL, &error);
   if (error != NULL)
     {