]> git.0d.be Git - empathy.git/blob - src/empathy-accounts-dialog.c
Fix identation
[empathy.git] / src / empathy-accounts-dialog.c
1 /*
2  * Copyright (C) 2005-2007 Imendio AB
3  * Copyright (C) 2007-2009 Collabora Ltd.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA  02110-1301  USA
19  *
20  * Authors: Martyn Russell <martyn@imendio.com>
21  *          Xavier Claessens <xclaesse@gmail.com>
22  *          Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
23  */
24
25 #include <config.h>
26
27 #include <string.h>
28 #include <stdlib.h>
29
30 #include <gtk/gtk.h>
31 #include <glib/gi18n.h>
32 #include <dbus/dbus-glib.h>
33
34 #include <telepathy-glib/util.h>
35
36 #include <libempathy/empathy-utils.h>
37 #include <libempathy/empathy-account-manager.h>
38 #include <libempathy/empathy-connection-managers.h>
39 #include <libempathy-gtk/empathy-ui-utils.h>
40
41 #include <libempathy-gtk/empathy-protocol-chooser.h>
42 #include <libempathy-gtk/empathy-account-widget.h>
43 #include <libempathy-gtk/empathy-account-widget-irc.h>
44 #include <libempathy-gtk/empathy-account-widget-sip.h>
45 #include <libempathy-gtk/empathy-conf.h>
46
47 #include "empathy-accounts-dialog.h"
48 #if 0
49 /* FIXME MC-5 */
50 #include "empathy-import-dialog.h"
51 #endif
52
53 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
54 #include <libempathy/empathy-debug.h>
55
56 /* Flashing delay for icons (milliseconds). */
57 #define FLASH_TIMEOUT 500
58
59 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog)
60 G_DEFINE_TYPE (EmpathyAccountsDialog, empathy_accounts_dialog, G_TYPE_OBJECT);
61
62 static EmpathyAccountsDialog *dialog_singleton = NULL;
63
64 typedef struct {
65   GtkWidget *window;
66
67   GtkWidget *alignment_settings;
68
69   GtkWidget *vbox_details;
70   GtkWidget *frame_no_protocol;
71
72   GtkWidget *treeview;
73
74   GtkWidget *button_add;
75   GtkWidget *button_remove;
76   GtkWidget *button_import;
77
78   GtkWidget *frame_new_account;
79   GtkWidget *combobox_protocol;
80   GtkWidget *hbox_type;
81   GtkWidget *button_create;
82   GtkWidget *button_back;
83   GtkWidget *radiobutton_reuse;
84   GtkWidget *radiobutton_register;
85
86   GtkWidget *image_type;
87   GtkWidget *label_name;
88   GtkWidget *label_type;
89   GtkWidget *settings_widget;
90
91   gboolean  connecting_show;
92   guint connecting_id;
93
94   gulong  settings_ready_id;
95   EmpathyAccountSettings *settings_ready;
96
97   EmpathyAccountManager *account_manager;
98   EmpathyConnectionManagers *cms;
99
100   GtkWindow *parent_window;
101   EmpathyAccount *initial_selection;
102 } EmpathyAccountsDialogPriv;
103
104 enum {
105   COL_ENABLED,
106   COL_NAME,
107   COL_STATUS,
108   COL_ACCOUNT_POINTER,
109   COL_ACCOUNT_SETTINGS_POINTER,
110   COL_COUNT
111 };
112
113 enum {
114   PROP_PARENT = 1
115 };
116
117 static void accounts_dialog_update_settings (EmpathyAccountsDialog *dialog,
118     EmpathyAccountSettings *settings);
119
120 #if 0
121 /* FIXME MC-5 */
122 static void accounts_dialog_button_import_clicked_cb  (GtkWidget *button,
123     EmpathyAccountsDialog *dialog);
124 #endif
125
126 static void
127 accounts_dialog_update_name_label (EmpathyAccountsDialog *dialog,
128     EmpathyAccountSettings *settings)
129 {
130   gchar *text;
131   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
132
133   text = g_markup_printf_escaped ("<big><b>%s</b></big>",
134       empathy_account_settings_get_display_name (settings));
135   gtk_label_set_markup (GTK_LABEL (priv->label_name), text);
136
137   g_free (text);
138 }
139
140 static GtkWidget *
141 get_account_setup_widget (EmpathyAccountSettings *settings)
142 {
143   const gchar *cm = empathy_account_settings_get_cm (settings);
144   const gchar *proto = empathy_account_settings_get_protocol (settings);
145
146   struct {
147     const gchar *cm;
148     const gchar *proto;
149   } dialogs[] = {
150     { "gabble", "jabber" },
151     { "butterfly", "msn" },
152     { "salut", "local-xmpp" },
153     { "idle", "irc" },
154     { "haze", "icq" },
155     { "haze", "aim" },
156     { "haze", "yahoo" },
157     { "haze", "groupwise" },
158     { "sofiasip", "sip" },
159     { NULL, NULL }
160   };
161   int i;
162
163   for (i = 0; dialogs[i].cm != NULL; i++)
164     {
165       if (!tp_strdiff (cm, dialogs[i].cm)
166           && !tp_strdiff (proto, dialogs[i].proto))
167         return empathy_account_widget_new_for_protocol (dialogs[i].proto,
168           settings);
169     }
170
171   return empathy_account_widget_new_for_protocol ("generic", settings);
172 }
173
174 static void
175 account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog,
176     EmpathyAccountSettings *settings)
177 {
178   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
179   gchar *icon_name;
180
181   priv->settings_widget = get_account_setup_widget (settings);
182
183   gtk_container_add (GTK_CONTAINER (priv->alignment_settings),
184       priv->settings_widget);
185   gtk_widget_show (priv->settings_widget);
186
187   icon_name = empathy_account_settings_get_icon_name (settings);
188
189   gtk_image_set_from_icon_name (GTK_IMAGE (priv->image_type),
190       icon_name, GTK_ICON_SIZE_DIALOG);
191   gtk_widget_set_tooltip_text (priv->image_type,
192       empathy_account_settings_get_protocol (settings));
193
194   accounts_dialog_update_name_label (dialog, settings);
195
196   g_free (icon_name);
197 }
198
199 static void
200 account_dialog_settings_ready_cb (EmpathyAccountSettings *settings,
201     GParamSpec *spec,
202     EmpathyAccountsDialog *dialog)
203 {
204   if (empathy_account_settings_is_ready (settings))
205     account_dialog_create_settings_widget (dialog, settings);
206 }
207
208 static void
209 accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog)
210 {
211   GtkTreeView      *view;
212   GtkTreeModel     *model;
213   GtkTreeSelection *selection;
214   GtkTreeIter       iter;
215   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
216
217   /* select first */
218   view = GTK_TREE_VIEW (priv->treeview);
219   model = gtk_tree_view_get_model (view);
220
221   if (gtk_tree_model_get_iter_first (model, &iter))
222     {
223       selection = gtk_tree_view_get_selection (view);
224       gtk_tree_selection_select_iter (selection, &iter);
225     }
226   else
227     {
228       accounts_dialog_update_settings (dialog, NULL);
229     }
230 }
231
232 static void
233 accounts_dialog_protocol_changed_cb (GtkWidget *widget,
234     EmpathyAccountsDialog *dialog)
235 {
236   TpConnectionManager *cm;
237   TpConnectionManagerProtocol *proto;
238   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
239
240   cm = empathy_protocol_chooser_dup_selected (
241       EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto);
242
243   if (tp_connection_manager_protocol_can_register (proto))
244     {
245       gtk_widget_show (priv->radiobutton_register);
246       gtk_widget_show (priv->radiobutton_reuse);
247     }
248   else
249     {
250       gtk_widget_hide (priv->radiobutton_register);
251       gtk_widget_hide (priv->radiobutton_reuse);
252     }
253   g_object_unref (cm);
254 }
255
256 static void
257 accounts_dialog_button_add_clicked_cb (GtkWidget *button,
258     EmpathyAccountsDialog *dialog)
259 {
260   GtkTreeView      *view;
261   GtkTreeSelection *selection;
262   GtkTreeModel     *model;
263   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
264
265   view = GTK_TREE_VIEW (priv->treeview);
266   model = gtk_tree_view_get_model (view);
267   selection = gtk_tree_view_get_selection (view);
268   gtk_tree_selection_unselect_all (selection);
269
270   gtk_widget_set_sensitive (priv->button_add, FALSE);
271   gtk_widget_set_sensitive (priv->button_remove, FALSE);
272   gtk_widget_hide (priv->vbox_details);
273   gtk_widget_hide (priv->frame_no_protocol);
274   gtk_widget_show (priv->frame_new_account);
275
276   /* If we have no account, no need of a back button */
277   if (gtk_tree_model_iter_n_children (model, NULL) > 0)
278     gtk_widget_show (priv->button_back);
279   else
280     gtk_widget_hide (priv->button_back);
281
282   accounts_dialog_protocol_changed_cb (priv->radiobutton_register, dialog);
283   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_reuse),
284       TRUE);
285   gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combobox_protocol), 0);
286   gtk_widget_grab_focus (priv->combobox_protocol);
287 }
288
289 static void
290 accounts_dialog_update_settings (EmpathyAccountsDialog *dialog,
291     EmpathyAccountSettings *settings)
292 {
293   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
294
295   if (priv->settings_ready != NULL)
296     {
297       g_signal_handler_disconnect (priv->settings_ready,
298           priv->settings_ready_id);
299       priv->settings_ready = NULL;
300       priv->settings_ready_id = 0;
301     }
302
303   if (!settings)
304     {
305       GtkTreeView  *view;
306       GtkTreeModel *model;
307
308       view = GTK_TREE_VIEW (priv->treeview);
309       model = gtk_tree_view_get_model (view);
310
311       if (gtk_tree_model_iter_n_children (model, NULL) > 0)
312         {
313           /* We have configured accounts, select the first one */
314           accounts_dialog_model_select_first (dialog);
315           return;
316         }
317       if (empathy_connection_managers_get_cms_num (priv->cms) > 0)
318         {
319           /* We have no account configured but we have some
320            * profiles instsalled. The user obviously wants to add
321            * an account. Click on the Add button for him. */
322           accounts_dialog_button_add_clicked_cb (priv->button_add,
323               dialog);
324           return;
325         }
326
327       /* No account and no profile, warn the user */
328       gtk_widget_hide (priv->vbox_details);
329       gtk_widget_hide (priv->frame_new_account);
330       gtk_widget_show (priv->frame_no_protocol);
331       gtk_widget_set_sensitive (priv->button_add, FALSE);
332       gtk_widget_set_sensitive (priv->button_remove, FALSE);
333       return;
334     }
335
336   /* We have an account selected, destroy old settings and create a new
337    * one for the account selected */
338   gtk_widget_hide (priv->frame_new_account);
339   gtk_widget_hide (priv->frame_no_protocol);
340   gtk_widget_show (priv->vbox_details);
341   gtk_widget_set_sensitive (priv->button_add, TRUE);
342   gtk_widget_set_sensitive (priv->button_remove, TRUE);
343
344   if (priv->settings_widget)
345     {
346       gtk_widget_destroy (priv->settings_widget);
347       priv->settings_widget = NULL;
348     }
349
350   if (empathy_account_settings_is_ready (settings))
351     {
352       account_dialog_create_settings_widget (dialog, settings);
353     }
354   else
355     {
356       priv->settings_ready = settings;
357       priv->settings_ready_id =
358         g_signal_connect (settings, "notify::ready",
359             G_CALLBACK (account_dialog_settings_ready_cb), dialog);
360     }
361
362 }
363
364 static void
365 accounts_dialog_name_editing_started_cb (GtkCellRenderer *renderer,
366     GtkCellEditable *editable,
367     gchar *path,
368     EmpathyAccountsDialog *dialog)
369 {
370   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
371
372   if (priv->connecting_id)
373     g_source_remove (priv->connecting_id);
374
375   DEBUG ("Editing account name started; stopping flashing");
376 }
377
378 static void
379 accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column,
380     GtkCellRenderer *cell,
381     GtkTreeModel *model,
382     GtkTreeIter *iter,
383     EmpathyAccountsDialog *dialog)
384 {
385   EmpathyAccountSettings  *settings;
386   gchar              *icon_name;
387   GdkPixbuf          *pixbuf;
388   TpConnectionStatus  status;
389   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
390
391   gtk_tree_model_get (model, iter,
392       COL_STATUS, &status,
393       COL_ACCOUNT_SETTINGS_POINTER, &settings,
394       -1);
395
396   icon_name = empathy_account_settings_get_icon_name (settings);
397   pixbuf = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON);
398
399   g_free (icon_name);
400
401   if (pixbuf)
402     {
403       if (status == TP_CONNECTION_STATUS_DISCONNECTED ||
404           (status == TP_CONNECTION_STATUS_CONNECTING &&
405               !priv->connecting_show))
406         {
407           GdkPixbuf *modded_pixbuf;
408
409           modded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
410               TRUE,
411               8,
412               gdk_pixbuf_get_width (pixbuf),
413               gdk_pixbuf_get_height (pixbuf));
414
415           gdk_pixbuf_saturate_and_pixelate (pixbuf,
416               modded_pixbuf,
417               1.0,
418               TRUE);
419           g_object_unref (pixbuf);
420           pixbuf = modded_pixbuf;
421         }
422     }
423
424   g_object_set (cell,
425       "visible", TRUE,
426       "pixbuf", pixbuf,
427       NULL);
428
429   g_object_unref (settings);
430
431   if (pixbuf)
432     g_object_unref (pixbuf);
433 }
434
435 static void
436 accounts_dialog_enable_toggled_cb (GtkCellRendererToggle *cell_renderer,
437     gchar *path,
438     EmpathyAccountsDialog *dialog)
439 {
440   EmpathyAccount    *account;
441   GtkTreeModel *model;
442   GtkTreePath  *treepath;
443   GtkTreeIter   iter;
444   gboolean      enabled;
445   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
446
447   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
448   treepath = gtk_tree_path_new_from_string (path);
449   gtk_tree_model_get_iter (model, &iter, treepath);
450   gtk_tree_model_get (model, &iter,
451       COL_ACCOUNT_POINTER, &account,
452       -1);
453   gtk_tree_path_free (treepath);
454
455   if (account == NULL)
456     return;
457
458   enabled = empathy_account_is_enabled (account);
459   empathy_account_set_enabled (account, !enabled);
460
461   DEBUG ("%s account %s", enabled ? "Disabled" : "Enable",
462       empathy_account_get_display_name (account));
463
464   g_object_unref (account);
465 }
466
467 static gboolean
468 accounts_dialog_row_changed_foreach (GtkTreeModel *model,
469     GtkTreePath *path,
470     GtkTreeIter *iter,
471     gpointer user_data)
472 {
473   gtk_tree_model_row_changed (model, path, iter);
474
475   return FALSE;
476 }
477
478 static gboolean
479 accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog *dialog)
480 {
481   GtkTreeView  *view;
482   GtkTreeModel *model;
483   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
484
485   priv->connecting_show = !priv->connecting_show;
486
487   view = GTK_TREE_VIEW (priv->treeview);
488   model = gtk_tree_view_get_model (view);
489
490   gtk_tree_model_foreach (model, accounts_dialog_row_changed_foreach, NULL);
491
492   return TRUE;
493 }
494
495 static void
496 accounts_dialog_name_edited_cb (GtkCellRendererText *renderer,
497     gchar *path,
498     gchar *new_text,
499     EmpathyAccountsDialog *dialog)
500 {
501   EmpathyAccountSettings    *settings;
502   GtkTreeModel *model;
503   GtkTreePath  *treepath;
504   GtkTreeIter   iter;
505   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
506
507   if (empathy_account_manager_get_connecting_accounts
508       (priv->account_manager) > 0)
509     {
510       priv->connecting_id = g_timeout_add (FLASH_TIMEOUT,
511           (GSourceFunc) accounts_dialog_flash_connecting_cb,
512           dialog);
513     }
514
515   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
516   treepath = gtk_tree_path_new_from_string (path);
517   gtk_tree_model_get_iter (model, &iter, treepath);
518   gtk_tree_model_get (model, &iter,
519       COL_ACCOUNT_SETTINGS_POINTER, &settings,
520       -1);
521   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
522       COL_NAME, new_text,
523       -1);
524   gtk_tree_path_free (treepath);
525
526   empathy_account_settings_set_display_name_async (settings, new_text,
527       NULL, NULL);
528   g_object_unref (settings);
529 }
530
531 static void
532 accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog)
533 {
534   GtkTreeView       *view;
535   GtkTreeViewColumn *column;
536   GtkCellRenderer   *cell;
537   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
538
539   view = GTK_TREE_VIEW (priv->treeview);
540   gtk_tree_view_set_headers_visible (view, TRUE);
541
542   /* Enabled column */
543   cell = gtk_cell_renderer_toggle_new ();
544   gtk_tree_view_insert_column_with_attributes (view, -1,
545       _("Enabled"),
546       cell,
547       "active", COL_ENABLED,
548       NULL);
549   g_signal_connect (cell, "toggled",
550       G_CALLBACK (accounts_dialog_enable_toggled_cb),
551       dialog);
552
553   /* Account column */
554   column = gtk_tree_view_column_new ();
555   gtk_tree_view_column_set_title (column, _("Accounts"));
556   gtk_tree_view_column_set_expand (column, TRUE);
557   gtk_tree_view_append_column (view, column);
558
559   /* Icon renderer */
560   cell = gtk_cell_renderer_pixbuf_new ();
561   gtk_tree_view_column_pack_start (column, cell, FALSE);
562   gtk_tree_view_column_set_cell_data_func (column, cell,
563       (GtkTreeCellDataFunc)
564       accounts_dialog_model_pixbuf_data_func,
565       dialog,
566       NULL);
567
568   /* Name renderer */
569   cell = gtk_cell_renderer_text_new ();
570   g_object_set (cell,
571       "ellipsize", PANGO_ELLIPSIZE_END,
572       "width-chars", 25,
573       "editable", TRUE,
574       NULL);
575   gtk_tree_view_column_pack_start (column, cell, TRUE);
576   gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME);
577   g_signal_connect (cell, "edited",
578       G_CALLBACK (accounts_dialog_name_edited_cb),
579       dialog);
580   g_signal_connect (cell, "editing-started",
581       G_CALLBACK (accounts_dialog_name_editing_started_cb),
582       dialog);
583 }
584
585 static EmpathyAccountSettings *
586 accounts_dialog_model_get_selected_settings (EmpathyAccountsDialog *dialog)
587 {
588   GtkTreeView      *view;
589   GtkTreeModel     *model;
590   GtkTreeSelection *selection;
591   GtkTreeIter       iter;
592   EmpathyAccountSettings   *settings;
593   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
594
595   view = GTK_TREE_VIEW (priv->treeview);
596   selection = gtk_tree_view_get_selection (view);
597
598   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
599     return NULL;
600
601   gtk_tree_model_get (model, &iter,
602       COL_ACCOUNT_SETTINGS_POINTER, &settings, -1);
603
604   return settings;
605 }
606
607 static void
608 accounts_dialog_model_selection_changed (GtkTreeSelection *selection,
609     EmpathyAccountsDialog *dialog)
610 {
611   EmpathyAccountSettings *settings;
612   GtkTreeModel *model;
613   GtkTreeIter   iter;
614   gboolean      is_selection;
615
616   is_selection = gtk_tree_selection_get_selected (selection, &model, &iter);
617
618   settings = accounts_dialog_model_get_selected_settings (dialog);
619   accounts_dialog_update_settings (dialog, settings);
620
621   if (settings)
622     g_object_unref (settings);
623 }
624
625 static void
626 accounts_dialog_model_setup (EmpathyAccountsDialog *dialog)
627 {
628   GtkListStore     *store;
629   GtkTreeSelection *selection;
630   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
631
632   store = gtk_list_store_new (COL_COUNT,
633       G_TYPE_BOOLEAN,        /* enabled */
634       G_TYPE_STRING,         /* name */
635       G_TYPE_UINT,           /* status */
636       EMPATHY_TYPE_ACCOUNT,   /* account */
637       EMPATHY_TYPE_ACCOUNT_SETTINGS); /* settings */
638
639   gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
640       GTK_TREE_MODEL (store));
641
642   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
643   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
644
645   g_signal_connect (selection, "changed",
646       G_CALLBACK (accounts_dialog_model_selection_changed),
647       dialog);
648
649   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
650       COL_NAME, GTK_SORT_ASCENDING);
651
652   accounts_dialog_model_add_columns (dialog);
653
654   g_object_unref (store);
655 }
656
657 static gboolean
658 accounts_dialog_get_settings_iter (EmpathyAccountsDialog *dialog,
659     EmpathyAccountSettings *settings,
660     GtkTreeIter *iter)
661 {
662   GtkTreeView      *view;
663   GtkTreeSelection *selection;
664   GtkTreeModel     *model;
665   gboolean          ok;
666   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
667
668   /* Update the status in the model */
669   view = GTK_TREE_VIEW (priv->treeview);
670   selection = gtk_tree_view_get_selection (view);
671   model = gtk_tree_view_get_model (view);
672
673   for (ok = gtk_tree_model_get_iter_first (model, iter);
674        ok;
675        ok = gtk_tree_model_iter_next (model, iter))
676     {
677       EmpathyAccountSettings *this_settings;
678       gboolean   equal;
679
680       gtk_tree_model_get (model, iter,
681           COL_ACCOUNT_SETTINGS_POINTER, &this_settings,
682           -1);
683
684       equal = (this_settings == settings);
685       g_object_unref (this_settings);
686
687       if (equal)
688         return TRUE;
689     }
690
691   return FALSE;
692 }
693
694 static gboolean
695 accounts_dialog_get_account_iter (EmpathyAccountsDialog *dialog,
696     EmpathyAccount *account,
697     GtkTreeIter *iter)
698 {
699   GtkTreeView      *view;
700   GtkTreeSelection *selection;
701   GtkTreeModel     *model;
702   gboolean          ok;
703   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
704
705   /* Update the status in the model */
706   view = GTK_TREE_VIEW (priv->treeview);
707   selection = gtk_tree_view_get_selection (view);
708   model = gtk_tree_view_get_model (view);
709
710   for (ok = gtk_tree_model_get_iter_first (model, iter);
711        ok;
712        ok = gtk_tree_model_iter_next (model, iter))
713     {
714       EmpathyAccountSettings *settings;
715       gboolean   equal;
716
717       gtk_tree_model_get (model, iter,
718           COL_ACCOUNT_SETTINGS_POINTER, &settings,
719           -1);
720
721       equal = empathy_account_settings_has_account (settings, account);
722       g_object_unref (settings);
723
724       if (equal)
725         return TRUE;
726     }
727
728   return FALSE;
729 }
730
731 static EmpathyAccount *
732 accounts_dialog_model_get_selected_account (EmpathyAccountsDialog *dialog)
733 {
734   GtkTreeView      *view;
735   GtkTreeModel     *model;
736   GtkTreeSelection *selection;
737   GtkTreeIter       iter;
738   EmpathyAccount   *account;
739   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
740
741   view = GTK_TREE_VIEW (priv->treeview);
742   selection = gtk_tree_view_get_selection (view);
743
744   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
745     return NULL;
746
747   gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1);
748
749   return account;
750 }
751
752 static void
753 accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog,
754     EmpathyAccountSettings *settings)
755 {
756   GtkTreeSelection *selection;
757   GtkTreeIter       iter;
758   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
759
760   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
761   if (accounts_dialog_get_settings_iter (dialog, settings, &iter))
762     gtk_tree_selection_select_iter (selection, &iter);
763 }
764
765 static gboolean
766 accounts_dialog_model_remove_selected (EmpathyAccountsDialog *dialog)
767 {
768   GtkTreeView      *view;
769   GtkTreeModel     *model;
770   GtkTreeSelection *selection;
771   GtkTreeIter       iter;
772   EmpathyAccount *account;
773   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
774
775   view = GTK_TREE_VIEW (priv->treeview);
776   selection = gtk_tree_view_get_selection (view);
777
778   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
779     return FALSE;
780
781   gtk_tree_model_get (model, &iter,
782       COL_ACCOUNT_POINTER, &account,
783       -1);
784
785   if (account != NULL)
786     empathy_account_remove_async (account, NULL, NULL);
787
788   return gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
789 }
790
791 static void
792 accounts_dialog_add (EmpathyAccountsDialog *dialog,
793     EmpathyAccountSettings *settings)
794 {
795   GtkTreeModel       *model;
796   GtkTreeIter         iter;
797   const gchar        *name;
798   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
799
800   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
801   name = empathy_account_settings_get_display_name (settings);
802
803   gtk_list_store_append (GTK_LIST_STORE (model), &iter);
804
805   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
806       COL_ENABLED, FALSE,
807       COL_NAME, name,
808       COL_STATUS, TP_CONNECTION_STATUS_DISCONNECTED,
809       COL_ACCOUNT_SETTINGS_POINTER, settings,
810       -1);
811 }
812
813 static void
814 accounts_dialog_connection_changed_cb     (EmpathyAccountManager *manager,
815     EmpathyAccount *account,
816     TpConnectionStatusReason reason,
817     TpConnectionStatus current,
818     TpConnectionStatus previous,
819     EmpathyAccountsDialog *dialog)
820 {
821   GtkTreeModel *model;
822   GtkTreeIter   iter;
823   gboolean      found;
824   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
825
826   /* Update the status in the model */
827   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
828
829   if (accounts_dialog_get_account_iter (dialog, account, &iter))
830     {
831       GtkTreePath *path;
832
833       gtk_list_store_set (GTK_LIST_STORE (model), &iter,
834           COL_STATUS, current,
835           -1);
836
837       path = gtk_tree_model_get_path (model, &iter);
838       gtk_tree_model_row_changed (model, path, &iter);
839       gtk_tree_path_free (path);
840     }
841
842   found = (empathy_account_manager_get_connecting_accounts (manager) > 0);
843
844   if (!found && priv->connecting_id)
845     {
846       g_source_remove (priv->connecting_id);
847       priv->connecting_id = 0;
848     }
849
850   if (found && !priv->connecting_id)
851     priv->connecting_id = g_timeout_add (FLASH_TIMEOUT,
852         (GSourceFunc) accounts_dialog_flash_connecting_cb,
853         dialog);
854 }
855
856 static void
857 accounts_dialog_add_account (EmpathyAccountsDialog *dialog,
858     EmpathyAccount *account)
859 {
860   EmpathyAccountSettings *settings;
861   GtkTreeModel       *model;
862   GtkTreeIter         iter;
863   TpConnectionStatus  status;
864   const gchar        *name;
865   gboolean            enabled;
866   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
867
868   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
869   g_object_get (account, "connection-status", &status, NULL);
870   name = empathy_account_get_display_name (account);
871   enabled = empathy_account_is_enabled (account);
872
873   if (!accounts_dialog_get_account_iter (dialog, account, &iter))
874     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
875
876   settings = empathy_account_settings_new_for_account (account);
877
878   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
879       COL_ENABLED, enabled,
880       COL_NAME, name,
881       COL_STATUS, status,
882       COL_ACCOUNT_POINTER, account,
883       COL_ACCOUNT_SETTINGS_POINTER, settings,
884       -1);
885
886   accounts_dialog_connection_changed_cb (priv->account_manager,
887       account,
888       TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED,
889       status,
890       TP_CONNECTION_STATUS_DISCONNECTED,
891       dialog);
892
893   g_object_unref (settings);
894 }
895
896 static void
897 accounts_dialog_update (EmpathyAccountsDialog *dialog,
898     EmpathyAccountSettings *settings)
899 {
900   GtkTreeModel       *model;
901   GtkTreeIter         iter;
902   TpConnectionStatus  status = TP_CONNECTION_STATUS_DISCONNECTED;
903   const gchar        *name;
904   gboolean            enabled = FALSE;
905   EmpathyAccount     *account;
906   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
907
908   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
909   name = empathy_account_settings_get_display_name (settings);
910
911   account = empathy_account_settings_get_account (settings);
912   if (account != NULL)
913     {
914       enabled = empathy_account_is_enabled (account);
915       g_object_get (account, "connection-status", &status, NULL);
916     }
917
918   accounts_dialog_get_settings_iter (dialog, settings, &iter);
919   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
920       COL_ENABLED, enabled,
921       COL_NAME, name,
922       COL_STATUS, status,
923       COL_ACCOUNT_POINTER, account,
924       COL_ACCOUNT_SETTINGS_POINTER, settings,
925       -1);
926 }
927
928 static void
929 accounts_dialog_account_added_cb (EmpathyAccountManager *manager,
930     EmpathyAccount *account,
931     EmpathyAccountsDialog *dialog)
932 {
933   accounts_dialog_add_account (dialog, account);
934 }
935
936
937 static void
938 accounts_dialog_account_removed_cb (EmpathyAccountManager *manager,
939     EmpathyAccount *account,
940     EmpathyAccountsDialog *dialog)
941 {
942   GtkTreeIter iter;
943   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
944
945   if (accounts_dialog_get_account_iter (dialog, account, &iter))
946     gtk_list_store_remove (GTK_LIST_STORE (
947             gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))), &iter);
948 }
949
950 static void
951 enable_or_disable_account (EmpathyAccountsDialog *dialog,
952     EmpathyAccount *account,
953     gboolean enabled)
954 {
955   GtkTreeModel *model;
956   GtkTreeIter   iter;
957   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
958
959   /* Update the status in the model */
960   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
961
962   DEBUG ("Account %s is now %s",
963       empathy_account_get_display_name (account),
964       enabled ? "enabled" : "disabled");
965
966   if (accounts_dialog_get_account_iter (dialog, account, &iter))
967     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
968         COL_ENABLED, enabled,
969         -1);
970 }
971
972 static void
973 accounts_dialog_account_disabled_cb (EmpathyAccountManager *manager,
974     EmpathyAccount *account,
975     EmpathyAccountsDialog *dialog)
976 {
977   enable_or_disable_account (dialog, account, FALSE);
978 }
979
980 static void
981 accounts_dialog_account_enabled_cb (EmpathyAccountManager *manager,
982     EmpathyAccount *account,
983     EmpathyAccountsDialog *dialog)
984 {
985   enable_or_disable_account (dialog, account, TRUE);
986 }
987
988 static void
989 accounts_dialog_account_changed_cb (EmpathyAccountManager *manager,
990     EmpathyAccount *account,
991     EmpathyAccountsDialog  *dialog)
992 {
993   EmpathyAccountSettings *settings, *selected_settings;
994   GtkTreeModel *model;
995   GtkTreeIter iter;
996   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
997
998   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
999
1000   if (!accounts_dialog_get_account_iter (dialog, account, &iter))
1001     return;
1002
1003   gtk_tree_model_get (model, &iter,
1004       COL_ACCOUNT_SETTINGS_POINTER, &settings,
1005       -1);
1006
1007   accounts_dialog_update (dialog, settings);
1008   selected_settings = accounts_dialog_model_get_selected_settings (dialog);
1009
1010   if (settings == selected_settings)
1011     accounts_dialog_update_name_label (dialog, settings);
1012 }
1013
1014 static void
1015 accounts_dialog_button_create_clicked_cb (GtkWidget *button,
1016     EmpathyAccountsDialog *dialog)
1017 {
1018   EmpathyAccountSettings *settings;
1019   gchar     *str;
1020   TpConnectionManager *cm;
1021   TpConnectionManagerProtocol *proto;
1022   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1023
1024   cm = empathy_protocol_chooser_dup_selected (
1025       EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto);
1026
1027   /* Create account */
1028   /* To translator: %s is the protocol name */
1029   str = g_strdup_printf (_("New %s account"), proto->name);
1030
1031   settings = empathy_account_settings_new (cm->name, proto->name, str);
1032
1033   g_free (str);
1034
1035   if (tp_connection_manager_protocol_can_register (proto))
1036     {
1037       gboolean active;
1038
1039       active = gtk_toggle_button_get_active
1040           (GTK_TOGGLE_BUTTON (priv->radiobutton_register));
1041       if (active)
1042         empathy_account_settings_set_boolean (settings, "register", TRUE);
1043     }
1044
1045   accounts_dialog_add (dialog, settings);
1046   accounts_dialog_model_set_selected (dialog, settings);
1047
1048   g_object_unref (settings);
1049   g_object_unref (cm);
1050 }
1051
1052 static void
1053 accounts_dialog_button_back_clicked_cb (GtkWidget *button,
1054     EmpathyAccountsDialog *dialog)
1055 {
1056   EmpathyAccountSettings *settings;
1057
1058   settings = accounts_dialog_model_get_selected_settings (dialog);
1059   accounts_dialog_update (dialog, settings);
1060 }
1061
1062 static void
1063 accounts_dialog_button_help_clicked_cb (GtkWidget *button,
1064     EmpathyAccountsDialog *dialog)
1065 {
1066   empathy_url_show (button, "ghelp:empathy?empathy-create-account");
1067 }
1068
1069 static void
1070 accounts_dialog_button_remove_clicked_cb (GtkWidget *button,
1071     EmpathyAccountsDialog *dialog)
1072 {
1073   EmpathyAccount *account;
1074   GtkWidget *message_dialog;
1075   gint       res;
1076   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1077
1078   account = accounts_dialog_model_get_selected_account (dialog);
1079
1080   if (account == NULL || !empathy_account_is_valid (account))
1081     {
1082       accounts_dialog_model_remove_selected (dialog);
1083       accounts_dialog_model_select_first (dialog);
1084       return;
1085     }
1086   message_dialog = gtk_message_dialog_new
1087     (GTK_WINDOW (priv->window),
1088         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1089         GTK_MESSAGE_QUESTION,
1090         GTK_BUTTONS_NONE,
1091         _("You are about to remove your %s account!\n"
1092             "Are you sure you want to proceed?"),
1093         empathy_account_get_display_name (account));
1094
1095   gtk_message_dialog_format_secondary_text
1096     (GTK_MESSAGE_DIALOG (message_dialog),
1097         _("Any associated conversations and chat rooms will NOT be "
1098             "removed if you decide to proceed.\n"
1099             "\n"
1100             "Should you decide to add the account back at a later time, "
1101             "they will still be available."));
1102
1103   gtk_dialog_add_button (GTK_DIALOG (message_dialog),
1104       GTK_STOCK_CANCEL,
1105       GTK_RESPONSE_NO);
1106   gtk_dialog_add_button (GTK_DIALOG (message_dialog),
1107       GTK_STOCK_REMOVE,
1108       GTK_RESPONSE_YES);
1109
1110   gtk_widget_show (message_dialog);
1111   res = gtk_dialog_run (GTK_DIALOG (message_dialog));
1112
1113   if (res == GTK_RESPONSE_YES)
1114     {
1115       accounts_dialog_model_remove_selected (dialog);
1116       accounts_dialog_model_select_first (dialog);
1117     }
1118   gtk_widget_destroy (message_dialog);
1119 }
1120
1121 #if 0
1122 /* FIXME MC-5 */
1123 static void
1124 accounts_dialog_button_import_clicked_cb (GtkWidget *button,
1125     EmpathyAccountsDialog *dialog)
1126 {
1127   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1128
1129   empathy_import_dialog_show (GTK_WINDOW (priv->window), TRUE);
1130 }
1131 #endif
1132
1133 static void
1134 accounts_dialog_response_cb (GtkWidget *widget,
1135     gint response,
1136     EmpathyAccountsDialog *dialog)
1137 {
1138   GList *accounts, *l;
1139   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1140
1141   if (response == GTK_RESPONSE_CLOSE)
1142     {
1143       /* Delete incomplete accounts */
1144       accounts = empathy_account_manager_dup_accounts
1145         (priv->account_manager);
1146       for (l = accounts; l; l = l->next)
1147         {
1148           EmpathyAccount *account;
1149
1150           account = l->data;
1151           if (!empathy_account_is_valid (account))
1152             /* FIXME: Warn the user the account is not
1153              * complete and is going to be removed.
1154              */
1155             empathy_account_manager_remove
1156               (priv->account_manager, account);
1157
1158           g_object_unref (account);
1159         }
1160       g_list_free (accounts);
1161
1162       gtk_widget_destroy (widget);
1163     }
1164 }
1165
1166 static void
1167 accounts_dialog_destroy_cb (GtkObject *obj,
1168     EmpathyAccountsDialog *dialog)
1169 {
1170   DEBUG ("%p", obj);
1171
1172   g_object_unref (dialog);
1173 }
1174
1175 static void
1176 accounts_dialog_set_selected_account (EmpathyAccountsDialog *dialog,
1177     EmpathyAccount *account)
1178 {
1179   GtkTreeSelection *selection;
1180   GtkTreeIter       iter;
1181   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1182
1183   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
1184   if (accounts_dialog_get_account_iter (dialog, account, &iter))
1185     gtk_tree_selection_select_iter (selection, &iter);
1186 }
1187
1188 static void
1189 accounts_dialog_cms_ready_cb (EmpathyConnectionManagers *cms,
1190     GParamSpec *pspec,
1191     EmpathyAccountsDialog *dialog)
1192 {
1193   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1194
1195   if (empathy_connection_managers_is_ready (cms))
1196     {
1197       accounts_dialog_update_settings (dialog, NULL);
1198
1199       if (priv->initial_selection != NULL)
1200         {
1201           accounts_dialog_set_selected_account
1202               (dialog, priv->initial_selection);
1203           priv->initial_selection = NULL;
1204         }
1205     }
1206 }
1207
1208 static void
1209 accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
1210 {
1211   GtkBuilder                   *gui;
1212   gchar                        *filename;
1213   EmpathyAccountsDialogPriv    *priv = GET_PRIV (dialog);
1214
1215   filename = empathy_file_lookup ("empathy-accounts-dialog.ui", "src");
1216
1217   gui = empathy_builder_get_file (filename,
1218       "accounts_dialog", &priv->window,
1219       "vbox_details", &priv->vbox_details,
1220       "frame_no_protocol", &priv->frame_no_protocol,
1221       "alignment_settings", &priv->alignment_settings,
1222       "treeview", &priv->treeview,
1223       "frame_new_account", &priv->frame_new_account,
1224       "hbox_type", &priv->hbox_type,
1225       "button_create", &priv->button_create,
1226       "button_back", &priv->button_back,
1227       "radiobutton_reuse", &priv->radiobutton_reuse,
1228       "radiobutton_register", &priv->radiobutton_register,
1229       "image_type", &priv->image_type,
1230       "label_name", &priv->label_name,
1231       "button_add", &priv->button_add,
1232       "button_remove", &priv->button_remove,
1233       "button_import", &priv->button_import,
1234       NULL);
1235   g_free (filename);
1236
1237   empathy_builder_connect (gui, dialog,
1238       "accounts_dialog", "response", accounts_dialog_response_cb,
1239       "accounts_dialog", "destroy", accounts_dialog_destroy_cb,
1240       "button_create", "clicked", accounts_dialog_button_create_clicked_cb,
1241       "button_back", "clicked", accounts_dialog_button_back_clicked_cb,
1242       "button_add", "clicked", accounts_dialog_button_add_clicked_cb,
1243       "button_remove", "clicked", accounts_dialog_button_remove_clicked_cb,
1244 #if 0
1245       /* FIXME MC-5  */
1246       "button_import", "clicked", accounts_dialog_button_import_clicked_cb,
1247 #endif
1248       "button_help", "clicked", accounts_dialog_button_help_clicked_cb,
1249       NULL);
1250
1251   g_object_unref (gui);
1252
1253   priv->combobox_protocol = empathy_protocol_chooser_new ();
1254   gtk_box_pack_end (GTK_BOX (priv->hbox_type),
1255       priv->combobox_protocol,
1256       TRUE, TRUE, 0);
1257   gtk_widget_show (priv->combobox_protocol);
1258   g_signal_connect (priv->combobox_protocol, "changed",
1259       G_CALLBACK (accounts_dialog_protocol_changed_cb),
1260       dialog);
1261
1262   if (priv->parent_window)
1263     gtk_window_set_transient_for (GTK_WINDOW (priv->window),
1264         priv->parent_window);
1265 }
1266
1267 static void
1268 do_dispose (GObject *obj)
1269 {
1270   EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (obj);
1271   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1272
1273   /* Disconnect signals */
1274   g_signal_handlers_disconnect_by_func (priv->account_manager,
1275       accounts_dialog_account_added_cb,
1276       dialog);
1277   g_signal_handlers_disconnect_by_func (priv->account_manager,
1278       accounts_dialog_account_removed_cb,
1279       dialog);
1280   g_signal_handlers_disconnect_by_func (priv->account_manager,
1281       accounts_dialog_account_enabled_cb,
1282       dialog);
1283   g_signal_handlers_disconnect_by_func (priv->account_manager,
1284       accounts_dialog_account_disabled_cb,
1285       dialog);
1286   g_signal_handlers_disconnect_by_func (priv->account_manager,
1287       accounts_dialog_account_changed_cb,
1288       dialog);
1289   g_signal_handlers_disconnect_by_func (priv->account_manager,
1290       accounts_dialog_connection_changed_cb,
1291       dialog);
1292
1293   if (priv->connecting_id)
1294     g_source_remove (priv->connecting_id);
1295
1296   if (priv->account_manager != NULL)
1297     {
1298       g_object_unref (priv->account_manager);
1299       priv->account_manager = NULL;
1300     }
1301
1302   if (priv->cms != NULL)
1303     {
1304       g_object_unref (priv->cms);
1305       priv->cms = NULL;
1306     }
1307
1308   G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->dispose (obj);
1309 }
1310
1311 static GObject *
1312 do_constructor (GType type,
1313     guint n_props,
1314     GObjectConstructParam *props)
1315 {
1316   GObject *retval;
1317
1318   if (dialog_singleton)
1319     {
1320       retval = G_OBJECT (dialog_singleton);
1321     }
1322   else
1323     {
1324       retval =
1325         G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->constructor
1326             (type, n_props, props);
1327
1328       dialog_singleton = EMPATHY_ACCOUNTS_DIALOG (retval);
1329       g_object_add_weak_pointer (retval, (gpointer) &dialog_singleton);
1330     }
1331
1332   return retval;
1333 }
1334
1335 static void
1336 do_get_property (GObject *object,
1337     guint property_id,
1338     GValue *value,
1339     GParamSpec *pspec)
1340 {
1341   EmpathyAccountsDialogPriv *priv = GET_PRIV (object);
1342
1343   switch (property_id)
1344     {
1345     case PROP_PARENT:
1346       g_value_set_object (value, priv->parent_window);
1347       break;
1348     default:
1349       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1350     }
1351 }
1352
1353 static void
1354 do_set_property (GObject *object,
1355     guint property_id,
1356     const GValue *value,
1357     GParamSpec *pspec)
1358 {
1359   EmpathyAccountsDialogPriv *priv = GET_PRIV (object);
1360
1361   switch (property_id)
1362     {
1363     case PROP_PARENT:
1364       priv->parent_window = g_value_get_object (value);
1365       break;
1366     default:
1367       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1368     }
1369 }
1370
1371 static void
1372 do_constructed (GObject *object)
1373 {
1374   EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (object);
1375   EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
1376   GList *accounts, *l;
1377   gboolean import_asked;
1378
1379   accounts_dialog_build_ui (dialog);
1380
1381   /* Set up signalling */
1382   priv->account_manager = empathy_account_manager_dup_singleton ();
1383
1384   g_signal_connect (priv->account_manager, "account-created",
1385       G_CALLBACK (accounts_dialog_account_added_cb),
1386       dialog);
1387   g_signal_connect (priv->account_manager, "account-deleted",
1388       G_CALLBACK (accounts_dialog_account_removed_cb),
1389       dialog);
1390   g_signal_connect (priv->account_manager, "account-enabled",
1391       G_CALLBACK (accounts_dialog_account_enabled_cb),
1392       dialog);
1393   g_signal_connect (priv->account_manager, "account-disabled",
1394       G_CALLBACK (accounts_dialog_account_disabled_cb),
1395       dialog);
1396   g_signal_connect (priv->account_manager, "account-changed",
1397       G_CALLBACK (accounts_dialog_account_changed_cb),
1398       dialog);
1399   g_signal_connect (priv->account_manager, "account-connection-changed",
1400       G_CALLBACK (accounts_dialog_connection_changed_cb),
1401       dialog);
1402
1403   accounts_dialog_model_setup (dialog);
1404
1405   /* Add existing accounts */
1406   accounts = empathy_account_manager_dup_accounts (priv->account_manager);
1407   for (l = accounts; l; l = l->next)
1408     {
1409       accounts_dialog_add_account (dialog, l->data);
1410       g_object_unref (l->data);
1411     }
1412   g_list_free (accounts);
1413
1414   priv->cms = empathy_connection_managers_dup_singleton ();
1415   if (!empathy_connection_managers_is_ready (priv->cms))
1416     g_signal_connect (priv->cms, "notify::ready",
1417         G_CALLBACK (accounts_dialog_cms_ready_cb), dialog);
1418
1419   accounts_dialog_model_select_first (dialog);
1420
1421   empathy_conf_get_bool (empathy_conf_get (),
1422       EMPATHY_PREFS_IMPORT_ASKED, &import_asked);
1423
1424
1425 #if 0
1426   /* FIXME MC-5 */
1427   if (empathy_import_dialog_accounts_to_import ())
1428     {
1429
1430       if (!import_asked)
1431         {
1432           empathy_conf_set_bool (empathy_conf_get (),
1433               EMPATHY_PREFS_IMPORT_ASKED, TRUE);
1434           empathy_import_dialog_show (GTK_WINDOW (priv->window),
1435               FALSE);
1436         }
1437     }
1438   else
1439     {
1440       gtk_widget_set_sensitive (priv->button_import, FALSE);
1441     }
1442 #endif
1443 }
1444
1445 static void
1446 empathy_accounts_dialog_class_init (EmpathyAccountsDialogClass *klass)
1447 {
1448   GObjectClass *oclass = G_OBJECT_CLASS (klass);
1449   GParamSpec *param_spec;
1450
1451   oclass->constructor = do_constructor;
1452   oclass->dispose = do_dispose;
1453   oclass->constructed = do_constructed;
1454   oclass->set_property = do_set_property;
1455   oclass->get_property = do_get_property;
1456
1457   param_spec = g_param_spec_object ("parent",
1458       "parent", "The parent window",
1459       GTK_TYPE_WINDOW,
1460       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1461   g_object_class_install_property (oclass, PROP_PARENT, param_spec);
1462
1463   g_type_class_add_private (klass, sizeof (EmpathyAccountsDialogPriv));
1464 }
1465
1466 static void
1467 empathy_accounts_dialog_init (EmpathyAccountsDialog *dialog)
1468 {
1469   EmpathyAccountsDialogPriv *priv;
1470
1471   priv = G_TYPE_INSTANCE_GET_PRIVATE ((dialog),
1472       EMPATHY_TYPE_ACCOUNTS_DIALOG,
1473       EmpathyAccountsDialogPriv);
1474   dialog->priv = priv;
1475 }
1476
1477 /* public methods */
1478
1479 GtkWidget *
1480 empathy_accounts_dialog_show (GtkWindow *parent,
1481     EmpathyAccount *selected_account)
1482 {
1483   EmpathyAccountsDialog *dialog;
1484   EmpathyAccountsDialogPriv *priv;
1485
1486   dialog = g_object_new (EMPATHY_TYPE_ACCOUNTS_DIALOG,
1487       "parent", parent, NULL);
1488
1489   priv = GET_PRIV (dialog);
1490
1491   if (selected_account && empathy_connection_managers_is_ready (priv->cms))
1492     accounts_dialog_set_selected_account (dialog, selected_account);
1493   else
1494     /* save the selection to set it later when the cms
1495      * becomes ready.
1496      */
1497     priv->initial_selection = selected_account;
1498
1499   gtk_window_present (GTK_WINDOW (priv->window));
1500
1501   return priv->window;
1502 }