]> git.0d.be Git - empathy.git/blob - src/empathy-account-assistant.c
assistant: Fix creation of the last account created
[empathy.git] / src / empathy-account-assistant.c
1 /*
2  * Copyright (C) 2009 Collabora Ltd.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
19  */
20
21 /* empathy-account-assistant.c */
22
23 #include <glib/gi18n.h>
24 #include <telepathy-glib/util.h>
25 #include <gdk/gdkkeysyms.h>
26
27 #include "empathy-account-assistant.h"
28 #include "empathy-import-widget.h"
29 #include "empathy-import-utils.h"
30 #include "empathy-auto-salut-account-helper.h"
31
32 #include <libempathy/empathy-account-settings.h>
33 #include <libempathy/empathy-utils.h>
34
35 #include <libempathy-gtk/empathy-account-widget.h>
36 #include <libempathy-gtk/empathy-protocol-chooser.h>
37 #include <libempathy-gtk/empathy-ui-utils.h>
38 #include <libempathy-gtk/empathy-conf.h>
39
40 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
41 #include <libempathy/empathy-debug.h>
42
43 G_DEFINE_TYPE (EmpathyAccountAssistant, empathy_account_assistant,
44     GTK_TYPE_ASSISTANT)
45
46 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountAssistant)
47
48 typedef enum {
49   RESPONSE_IMPORT = 1,
50   RESPONSE_ENTER_ACCOUNT = 2,
51   RESPONSE_CREATE_ACCOUNT = 3,
52   RESPONSE_SALUT_ONLY = 4
53 } FirstPageResponse;
54
55 typedef enum {
56   RESPONSE_CREATE_AGAIN = 1,
57   RESPONSE_CREATE_STOP = 2
58 } CreateEnterPageResponse;
59
60 enum {
61   PAGE_INTRO = 0,
62   PAGE_IMPORT = 1,
63   PAGE_ENTER_CREATE = 2,
64   PAGE_SALUT = 3,
65 };
66
67 enum {
68   PROP_PARENT = 1,
69   PROP_CONNECTION_MGRS,
70 };
71
72 typedef struct {
73   FirstPageResponse first_resp;
74   CreateEnterPageResponse create_enter_resp;
75   gboolean enter_create_forward;
76   TpAccountManager *account_mgr;
77   EmpathyConnectionManagers *connection_mgrs;
78   gint current_page_id;
79
80   /* enter or create page */
81   GtkWidget *enter_or_create_page;
82   GtkWidget *current_account_widget;
83   EmpathyAccountWidget *current_widget_object;
84   GtkWidget *first_label;
85   GtkWidget *second_label;
86   GtkWidget *chooser;
87   GtkWidget *create_again_radio;
88   EmpathyAccountSettings *settings;
89   gboolean is_creating;
90
91   /* import page */
92   EmpathyImportWidget *iw;
93   GtkWidget *import_page;
94
95   /* salut page */
96   GtkWidget *salut_page;
97   EmpathyAccountSettings *salut_settings;
98   GtkWidget *salut_account_widget;
99   gboolean create_salut_account;
100   gboolean display_salut_page;
101
102   GtkWindow *parent_window;
103
104   gboolean dispose_run;
105 } EmpathyAccountAssistantPriv;
106
107 static GtkWidget * account_assistant_build_enter_or_create_page (
108     EmpathyAccountAssistant *self);
109 static void account_assistant_finish_enter_or_create_page (
110     EmpathyAccountAssistant *self,
111     gboolean is_enter);
112
113 static void do_constructed (GObject *object);
114
115 static GtkWidget *
116 build_error_vbox (const gchar *primary_message,
117     const gchar *secondary_message)
118 {
119   GtkWidget *main_vbox, *w, *hbox;
120   PangoAttrList *list;
121
122   main_vbox = gtk_vbox_new (FALSE, 12);
123   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
124   gtk_widget_show (main_vbox);
125
126   hbox = gtk_hbox_new (FALSE, 12);
127   gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
128   gtk_widget_show (hbox);
129
130   w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR,
131       GTK_ICON_SIZE_DIALOG);
132   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
133   gtk_widget_show (w);
134
135   w = gtk_label_new (primary_message);
136   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
137   list = pango_attr_list_new ();
138   pango_attr_list_insert (list, pango_attr_scale_new (PANGO_SCALE_LARGE));
139   pango_attr_list_insert (list, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
140   gtk_label_set_attributes (GTK_LABEL (w), list);
141   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
142   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
143   gtk_widget_show (w);
144
145   pango_attr_list_unref (list);
146
147   w = gtk_label_new (secondary_message);
148   gtk_label_set_use_markup (GTK_LABEL (w), TRUE);
149   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
150   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
151   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
152   gtk_widget_show (w);
153
154   return main_vbox;
155 }
156
157 static GtkWidget *
158 account_assistant_build_error_page (EmpathyAccountAssistant *self,
159     GError *error, gint page_num)
160 {
161   GtkWidget *main_vbox, *w;
162   const char *primary_message;
163   gchar *secondary_message, *markup;
164   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
165
166   if (page_num == PAGE_IMPORT)
167     primary_message = _("There was an error while importing the accounts.");
168   else if (page_num >= PAGE_ENTER_CREATE &&
169       priv->first_resp == RESPONSE_ENTER_ACCOUNT)
170     primary_message = _("There was an error while parsing the account details.");
171   else if (page_num >= PAGE_ENTER_CREATE &&
172       priv->first_resp == RESPONSE_CREATE_ACCOUNT)
173     primary_message = _("There was an error while creating the account.");
174   else
175     primary_message = _("There was an error.");
176
177   markup = g_markup_printf_escaped ("<span style=\"italic\">%s</span>",
178       error->message);
179   secondary_message = g_strdup_printf (_("The error message was: %s"), markup);
180
181   main_vbox = build_error_vbox (primary_message, secondary_message);
182
183   w = gtk_label_new (_("You can either go back and try to enter your "
184           "accounts' details again or quit this assistant and add accounts "
185           "later from the Edit menu."));
186   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 6);
187   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
188   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
189   gtk_widget_show (w);
190
191   g_free (markup);
192   g_free (secondary_message);
193   return main_vbox;
194 }
195
196 static void
197 account_assistant_back_button_clicked_cb (GtkButton *button,
198     EmpathyAccountAssistant *self)
199 {
200   gint page_num;
201
202   page_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
203           "page-num"));
204   gtk_assistant_remove_action_widget (GTK_ASSISTANT (self),
205       GTK_WIDGET (button));
206   gtk_assistant_set_current_page (GTK_ASSISTANT (self), page_num);
207 }
208
209 static void
210 account_assistant_present_error_page (EmpathyAccountAssistant *self,
211     GError *error, gint page_num)
212 {
213   GtkWidget *error_page, *back_button;
214   gint num;
215
216   error_page = account_assistant_build_error_page (self, error,
217       page_num);
218   num = gtk_assistant_append_page (GTK_ASSISTANT (self), error_page);
219   gtk_assistant_set_page_title (GTK_ASSISTANT (self), error_page,
220       _("An error occurred"));
221   gtk_assistant_set_page_type (GTK_ASSISTANT (self), error_page,
222       GTK_ASSISTANT_PAGE_SUMMARY);
223
224   back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
225   gtk_assistant_add_action_widget (GTK_ASSISTANT (self), back_button);
226   g_object_set_data (G_OBJECT (back_button),
227       "page-num", GINT_TO_POINTER (page_num));
228   g_signal_connect (back_button, "clicked",
229       G_CALLBACK (account_assistant_back_button_clicked_cb), self);
230   gtk_widget_show (back_button);
231
232   gtk_assistant_set_current_page (GTK_ASSISTANT (self), num);
233 }
234
235 static void
236 update_create_page_buttons (EmpathyAccountAssistant *self)
237 {
238   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
239   GtkAssistantPageType type;
240
241   if (priv->display_salut_page ||
242       priv->create_enter_resp == RESPONSE_CREATE_AGAIN)
243     type = GTK_ASSISTANT_PAGE_CONTENT;
244   else
245     type = GTK_ASSISTANT_PAGE_CONFIRM;
246
247   gtk_assistant_set_page_type (GTK_ASSISTANT (self), priv->enter_or_create_page,
248       type);
249 }
250
251 static void
252 account_assistant_reset_enter_create_page (EmpathyAccountAssistant *self)
253 {
254   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
255   GtkWidget *page;
256   gint idx;
257
258   page = account_assistant_build_enter_or_create_page (self);
259   idx = gtk_assistant_append_page (GTK_ASSISTANT (self), page);
260   priv->enter_or_create_page = page;
261   update_create_page_buttons (self);
262
263   gtk_assistant_set_current_page (GTK_ASSISTANT (self), idx);
264
265   account_assistant_finish_enter_or_create_page (self,
266       priv->first_resp == RESPONSE_ENTER_ACCOUNT ?
267       TRUE : FALSE);
268 }
269
270 static void
271 account_assistant_account_enabled_cb (GObject *source,
272     GAsyncResult *result,
273     gpointer user_data)
274 {
275   GError *error = NULL;
276   EmpathyAccountAssistant *self = user_data;
277   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
278   const gchar *protocol;
279   TpAccount *account = TP_ACCOUNT (source);
280   gint current_idx;
281   gboolean salut_created = FALSE;
282
283   tp_account_set_enabled_finish (account, result, &error);
284
285   if (error)
286     {
287       g_warning ("Error enabling an account: %s", error->message);
288       g_error_free (error);
289     }
290
291   protocol = tp_account_get_protocol (account);
292   if (!tp_strdiff (protocol, "local-xmpp"))
293     {
294       DEBUG ("Salut account has been created; update gconf key");
295
296       empathy_conf_set_bool (empathy_conf_get (),
297           EMPATHY_PREFS_SALUT_ACCOUNT_CREATED,
298           TRUE);
299
300       salut_created = TRUE;
301     }
302
303   current_idx = gtk_assistant_get_current_page (GTK_ASSISTANT (self));
304   if (current_idx == PAGE_SALUT && !salut_created)
305     /* We are on the Salut page and aren't creating the salut account so don't
306      * terminate the assistant. */
307     return;
308
309   if (priv->create_enter_resp == RESPONSE_CREATE_STOP)
310     g_signal_emit_by_name (self, "close");
311   else
312     account_assistant_reset_enter_create_page (self);
313 }
314
315 static void
316 account_assistant_apply_account_cb (GObject *source,
317     GAsyncResult *result,
318     gpointer user_data)
319 {
320   GError *error = NULL;
321   EmpathyAccountAssistant *self = user_data;
322   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
323   EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source);
324   TpAccount *account;
325   gchar *display_name;
326
327   empathy_account_settings_apply_finish (settings, result, &error);
328
329   if (empathy_account_settings_get_display_name (settings) == NULL)
330     {
331       /* set default display name */
332       display_name = empathy_account_widget_get_default_display_name (
333           priv->current_widget_object);
334
335       empathy_account_settings_set_display_name_async (settings,
336           display_name, NULL, NULL);
337
338       g_free (display_name);
339     }
340
341   priv->is_creating = FALSE;
342
343   if (error != NULL)
344     {
345       account_assistant_present_error_page (self, error,
346           gtk_assistant_get_current_page (GTK_ASSISTANT (self)));
347       g_error_free (error);
348       return;
349     }
350
351   /* enable the newly created account */
352   account = empathy_account_settings_get_account (settings);
353   tp_account_set_enabled_async (account, TRUE,
354       account_assistant_account_enabled_cb, self);
355 }
356
357 static void
358 account_assistant_apply_account_and_finish (EmpathyAccountAssistant *self,
359     EmpathyAccountSettings *settings)
360 {
361   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
362
363   if (settings == NULL)
364     return;
365
366   priv->is_creating = TRUE;
367
368   empathy_account_settings_apply_async (settings,
369       account_assistant_apply_account_cb, self);
370 }
371
372 static void
373 account_assistant_handle_apply_cb (EmpathyAccountWidget *widget_object,
374     gboolean is_valid,
375     EmpathyAccountAssistant *self)
376 {
377   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
378
379   gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
380       priv->enter_or_create_page, is_valid);
381 }
382
383 static void
384 account_assistant_protocol_changed_cb (GtkComboBox *chooser,
385     EmpathyAccountAssistant *self)
386 {
387   TpConnectionManager *cm;
388   TpConnectionManagerProtocol *proto;
389   EmpathyAccountSettings *settings;
390   EmpathyAccountAssistantPriv *priv;
391   char *str;
392   GtkWidget *account_widget;
393   EmpathyAccountWidget *widget_object = NULL;
394   gboolean is_gtalk, is_facebook;
395   const gchar *name;
396
397   priv = GET_PRIV (self);
398
399   cm = empathy_protocol_chooser_dup_selected (
400       EMPATHY_PROTOCOL_CHOOSER (chooser), &proto, &is_gtalk, &is_facebook);
401
402   if (cm == NULL || proto == NULL)
403     /* we are not ready yet */
404     return;
405
406   /* Create account */
407   if (is_gtalk)
408     name = "gtalk";
409   else if (is_facebook)
410     name = "facebook";
411   else
412     name = proto->name;
413
414   /* To translator: %s is the protocol name */
415   str = g_strdup_printf (_("New %s account"),
416       empathy_protocol_name_to_display_name (name));
417
418   settings = empathy_account_settings_new (cm->name, proto->name, str);
419
420   if (is_gtalk)
421     empathy_account_settings_set_icon_name_async (settings, "im-google-talk",
422       NULL, NULL);
423   else if (is_facebook)
424     empathy_account_settings_set_icon_name_async (settings, "im-facebook",
425       NULL, NULL);
426
427   if (priv->first_resp == RESPONSE_CREATE_ACCOUNT)
428     empathy_account_settings_set_boolean (settings, "register", TRUE);
429
430   widget_object = empathy_account_widget_new_for_protocol (settings, TRUE);
431   account_widget = empathy_account_widget_get_widget (widget_object);
432
433   if (priv->current_account_widget != NULL)
434     {
435       g_signal_handlers_disconnect_by_func (priv->current_widget_object,
436           account_assistant_handle_apply_cb, self);
437       gtk_widget_destroy (priv->current_account_widget);
438     }
439
440   priv->current_account_widget = account_widget;
441   priv->current_widget_object = widget_object;
442
443   if (priv->settings != NULL)
444     g_object_unref (priv->settings);
445
446   priv->settings = settings;
447
448   g_signal_connect (priv->current_widget_object, "handle-apply",
449       G_CALLBACK (account_assistant_handle_apply_cb), self);
450
451   if (empathy_account_settings_is_valid (settings))
452     {
453       gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
454           priv->enter_or_create_page, TRUE);
455     }
456
457   gtk_box_pack_start (GTK_BOX (priv->enter_or_create_page), account_widget,
458       FALSE, FALSE, 0);
459   gtk_widget_show (account_widget);
460
461   g_free (str);
462 }
463
464 static gboolean
465 account_assistant_chooser_enter_details_filter_func (
466     TpConnectionManager *cm,
467     TpConnectionManagerProtocol *protocol,
468     gboolean is_gtalk,
469     gboolean is_facebook,
470     gpointer user_data)
471 {
472   if (!tp_strdiff (protocol->name, "local-xmpp") ||
473       !tp_strdiff (protocol->name, "irc"))
474     return FALSE;
475
476   return TRUE;
477 }
478
479 static gboolean
480 account_assistant_chooser_create_account_filter_func (
481     TpConnectionManager *cm,
482     TpConnectionManagerProtocol *protocol,
483     gboolean is_gtalk,
484     gboolean is_facebook,
485     gpointer user_data)
486 {
487   if (is_gtalk || is_facebook)
488     return FALSE;
489
490   return tp_connection_manager_protocol_can_register (protocol);
491 }
492
493 static void
494 account_assistant_finish_enter_or_create_page (EmpathyAccountAssistant *self,
495     gboolean is_enter)
496 {
497   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
498
499   if (is_enter)
500     {
501       gtk_label_set_label (GTK_LABEL (priv->first_label),
502           _("What kind of chat account do you have?"));
503       /*      gtk_label_set_label (GTK_LABEL (priv->second_label),
504           _("If you have other accounts to set up, you can do "
505               "that at any time from the Edit menu."));
506       */
507       gtk_label_set_label (GTK_LABEL (priv->second_label),
508           _("Do you have any other chat accounts you want to set up?"));
509       empathy_protocol_chooser_set_visible (
510           EMPATHY_PROTOCOL_CHOOSER (priv->chooser),
511           account_assistant_chooser_enter_details_filter_func, self);
512
513       gtk_assistant_set_page_title (GTK_ASSISTANT (self),
514           priv->enter_or_create_page, _("Enter your account details"));
515     }
516   else
517     {
518       gtk_label_set_label (GTK_LABEL (priv->first_label),
519           _("What kind of chat account do you want to create?"));
520       /*      gtk_label_set_label (GTK_LABEL (priv->second_label),
521           _("You can register other accounts, or setup "
522               "an existing one at any time from the Edit menu."));
523       */
524       gtk_label_set_label (GTK_LABEL (priv->second_label),
525           _("Do you want to create other chat accounts?"));
526       empathy_protocol_chooser_set_visible (
527           EMPATHY_PROTOCOL_CHOOSER (priv->chooser),
528           account_assistant_chooser_create_account_filter_func, self);
529
530       gtk_assistant_set_page_title (GTK_ASSISTANT (self),
531           priv->enter_or_create_page,
532           _("Enter the details for the new account"));
533     }
534
535   g_signal_connect (priv->chooser, "changed",
536       G_CALLBACK (account_assistant_protocol_changed_cb), self);
537
538   /* trigger show the first account widget */
539   account_assistant_protocol_changed_cb (GTK_COMBO_BOX (priv->chooser), self);
540 }
541
542 static gint
543 account_assistant_page_forward_func (gint current_page,
544     gpointer user_data)
545 {
546   EmpathyAccountAssistant *self = user_data;
547   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
548   gint retval;
549
550   retval = current_page;
551
552   if (current_page == PAGE_INTRO)
553     {
554       if (priv->first_resp == RESPONSE_ENTER_ACCOUNT ||
555           priv->first_resp == RESPONSE_CREATE_ACCOUNT)
556         retval = PAGE_ENTER_CREATE;
557       else if (priv->first_resp == RESPONSE_IMPORT)
558         retval = PAGE_IMPORT;
559       else if (priv->first_resp == RESPONSE_SALUT_ONLY)
560         retval = PAGE_SALUT;
561     }
562   else if (current_page == PAGE_IMPORT)
563     {
564       if (priv->display_salut_page)
565         retval = PAGE_SALUT;
566       else
567         /* Don't go forward */
568         retval = -1;
569     }
570   else if (current_page == PAGE_SALUT)
571     {
572       /* Don't go forward */
573       retval = -1;
574     }
575   else if (current_page >= PAGE_ENTER_CREATE)
576     {
577       if (priv->create_enter_resp == RESPONSE_CREATE_AGAIN)
578         {
579           priv->enter_create_forward = TRUE;
580           retval = current_page;
581         }
582       else if (priv->display_salut_page)
583         {
584           retval = PAGE_SALUT;
585         }
586       else
587         {
588           /* Don't go forward */
589           retval = -1;
590         }
591     }
592
593   return retval;
594 }
595
596 static void
597 update_intro_page_buttons (EmpathyAccountAssistant *self)
598 {
599   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
600   GtkWidget *intro_page;
601
602   intro_page = gtk_assistant_get_nth_page (GTK_ASSISTANT (self),
603       PAGE_INTRO);
604
605   if (priv->first_resp == RESPONSE_SALUT_ONLY &&
606       !priv->display_salut_page)
607     gtk_assistant_set_page_type (GTK_ASSISTANT (self), intro_page,
608         GTK_ASSISTANT_PAGE_SUMMARY);
609   else
610     gtk_assistant_set_page_type (GTK_ASSISTANT (self), intro_page,
611         GTK_ASSISTANT_PAGE_INTRO);
612 }
613
614 static void
615 account_assistant_radio_choice_toggled_cb (GtkToggleButton *button,
616     EmpathyAccountAssistant *self)
617 {
618   FirstPageResponse response;
619   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
620
621   response = GPOINTER_TO_INT (g_object_get_data
622       (G_OBJECT (button), "response"));
623
624   priv->first_resp = response;
625
626   update_intro_page_buttons (self);
627 }
628
629 static GtkWidget *
630 account_assistant_build_introduction_page (EmpathyAccountAssistant *self)
631 {
632   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
633   GtkWidget *main_vbox, *hbox_1, *w, *vbox_1;
634   GtkWidget *radio = NULL;
635   GdkPixbuf *pix;
636   const gchar *str;
637
638   main_vbox = gtk_vbox_new (FALSE, 12);
639   gtk_widget_show (main_vbox);
640   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
641
642   hbox_1 = gtk_hbox_new (FALSE, 12);
643   gtk_box_pack_start (GTK_BOX (main_vbox), hbox_1, TRUE, TRUE, 0);
644   gtk_widget_show (hbox_1);
645
646   w = gtk_label_new (
647       _("With Empathy you can chat with people "
648         "online nearby and with friends and colleagues "
649         "who use Google Talk, AIM, Windows Live "
650         "and many other chat programs. With a microphone "
651         "or a webcam you can also have audio or video calls."));
652   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
653   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
654   gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 0);
655   gtk_widget_show (w);
656
657   pix = empathy_pixbuf_from_icon_name_sized ("empathy", 80);
658   w = gtk_image_new_from_pixbuf (pix);
659   gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 6);
660   gtk_widget_show (w);
661
662   g_object_unref (pix);
663
664   w = gtk_label_new (_("Do you have an account you've been using "
665           "with another chat program?"));
666   gtk_misc_set_alignment (GTK_MISC (w), 0, 0);
667   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
668   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
669   gtk_widget_show (w);
670
671   w = gtk_alignment_new (0, 0, 0, 0);
672   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
673   gtk_box_pack_start (GTK_BOX (main_vbox), w, TRUE, TRUE, 0);
674   gtk_widget_show (w);
675
676   vbox_1 = gtk_vbox_new (TRUE, 0);
677   gtk_container_add (GTK_CONTAINER (w), vbox_1);
678   gtk_widget_show (vbox_1);
679
680   if (empathy_import_accounts_to_import ())
681     {
682       hbox_1 = gtk_hbox_new (FALSE, 0);
683       gtk_box_pack_start (GTK_BOX (vbox_1), hbox_1, TRUE, TRUE, 0);
684       gtk_widget_show (hbox_1);
685
686       radio = gtk_radio_button_new_with_label (NULL,
687           _("Yes, import my account details from "));
688       gtk_box_pack_start (GTK_BOX (hbox_1), radio, TRUE, TRUE, 0);
689       g_object_set_data (G_OBJECT (radio), "response",
690           GINT_TO_POINTER (RESPONSE_IMPORT));
691       gtk_widget_show (radio);
692
693       w = gtk_combo_box_new_text ();
694       gtk_combo_box_append_text (GTK_COMBO_BOX (w), "Pidgin");
695       gtk_box_pack_start (GTK_BOX (hbox_1), w, TRUE, TRUE, 0);
696       gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
697       gtk_widget_show (w);
698
699       g_signal_connect (radio, "clicked",
700           G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
701       priv->first_resp = RESPONSE_IMPORT;
702     }
703   else
704     {
705       priv->first_resp = RESPONSE_ENTER_ACCOUNT;
706     }
707
708   str = _("Yes, I'll enter my account details now");
709
710   if (radio == NULL)
711     {
712       radio = gtk_radio_button_new_with_label (NULL, str);
713       w = radio;
714     }
715   else
716     {
717       w = gtk_radio_button_new_with_label_from_widget (
718           GTK_RADIO_BUTTON (radio), str);
719     }
720
721   gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
722   g_object_set_data (G_OBJECT (w), "response",
723       GINT_TO_POINTER (RESPONSE_ENTER_ACCOUNT));
724   gtk_widget_show (w);
725
726   g_signal_connect (w, "clicked",
727       G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
728
729   w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
730       _("No, I want a new account"));
731   gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
732   g_object_set_data (G_OBJECT (w), "response",
733       GINT_TO_POINTER (RESPONSE_CREATE_ACCOUNT));
734   gtk_widget_show (w);
735
736   g_signal_connect (w, "clicked",
737       G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
738
739   w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
740       _("No, I just want to see people online nearby for now"));
741   gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
742   g_object_set_data (G_OBJECT (w), "response",
743       GINT_TO_POINTER (RESPONSE_SALUT_ONLY));
744   gtk_widget_show (w);
745
746   g_signal_connect (w, "clicked",
747       G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
748
749   return main_vbox;
750 }
751
752 static GtkWidget *
753 account_assistant_build_import_page (EmpathyAccountAssistant *self)
754 {
755   GtkWidget *main_vbox, *w, *import;
756   EmpathyImportWidget *iw;
757   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
758
759   main_vbox = gtk_vbox_new (FALSE, 12);
760   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
761   w = gtk_label_new (_("Select the accounts you want to import:"));
762   gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
763   gtk_widget_show (w);
764   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 6);
765
766   w = gtk_alignment_new (0, 0, 0, 0);
767   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
768   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
769   gtk_widget_show (w);
770
771   /* NOTE: this is hardcoded as we support pidgin only */
772   iw = empathy_import_widget_new (EMPATHY_IMPORT_APPLICATION_PIDGIN);
773   import = empathy_import_widget_get_widget (iw);
774   gtk_container_add (GTK_CONTAINER (w), import);
775   gtk_widget_show (import);
776
777   priv->iw = iw;
778
779   gtk_widget_show (main_vbox);
780
781   return main_vbox;
782 }
783
784 static void
785 account_assistant_radio_create_again_clicked_cb (GtkButton *button,
786     EmpathyAccountAssistant *self)
787 {
788   CreateEnterPageResponse response;
789   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
790
791   response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
792           "response"));
793
794   priv->create_enter_resp = response;
795
796   update_create_page_buttons (self);
797 }
798
799 static GtkWidget *
800 account_assistant_build_enter_or_create_page (EmpathyAccountAssistant *self)
801 {
802   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
803   GtkWidget *main_vbox, *w, *chooser, *vbox, *hbox, *radio;
804
805   main_vbox = gtk_vbox_new (FALSE, 12);
806   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
807   gtk_widget_show (main_vbox);
808
809   w = gtk_label_new (NULL);
810   gtk_misc_set_alignment (GTK_MISC (w), 0, 0);
811   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
812   gtk_widget_show (w);
813   priv->first_label = w;
814
815   w = gtk_alignment_new (0, 0, 0, 0);
816   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
817   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
818   gtk_widget_show (w);
819
820   chooser = empathy_protocol_chooser_new ();
821   gtk_container_add (GTK_CONTAINER (w), chooser);
822   gtk_widget_show (chooser);
823   priv->chooser = chooser;
824
825   vbox = gtk_vbox_new (FALSE, 6);
826   gtk_box_pack_end (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
827   gtk_widget_show (vbox);
828
829   w = gtk_label_new (NULL);
830   gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
831   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
832   gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
833   gtk_widget_show (w);
834   priv->second_label = w;
835
836   w = gtk_alignment_new (0, 0, 0, 0);
837   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
838   gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
839   gtk_widget_show (w);
840
841   hbox = gtk_hbox_new (FALSE, 6);
842   gtk_container_add (GTK_CONTAINER (w), hbox);
843   gtk_widget_show (hbox);
844
845   radio = gtk_radio_button_new_with_label (NULL, _("Yes"));
846   gtk_box_pack_start (GTK_BOX (hbox), radio, FALSE, FALSE, 0);
847   g_object_set_data (G_OBJECT (radio), "response",
848       GINT_TO_POINTER (RESPONSE_CREATE_AGAIN));
849   gtk_widget_show (radio);
850
851   w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
852       _("No, that's all for now"));
853   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
854   g_object_set_data (G_OBJECT (w), "response",
855       GINT_TO_POINTER (RESPONSE_CREATE_STOP));
856   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
857   priv->create_enter_resp = RESPONSE_CREATE_STOP;
858   priv->create_again_radio = w;
859   gtk_widget_show (w);
860
861   g_signal_connect (w, "clicked",
862       G_CALLBACK (account_assistant_radio_create_again_clicked_cb), self);
863   g_signal_connect (radio, "clicked",
864       G_CALLBACK (account_assistant_radio_create_again_clicked_cb), self);
865
866   return main_vbox;
867 }
868
869 static void
870 account_assistant_close_cb (GtkAssistant *assistant,
871     gpointer user_data)
872 {
873   EmpathyAccountAssistantPriv *priv = GET_PRIV (assistant);
874
875   if (priv->is_creating)
876     return;
877
878   gtk_widget_destroy (GTK_WIDGET (assistant));
879 }
880
881 static void
882 impl_signal_apply (GtkAssistant *assistant)
883 {
884   EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (assistant);
885   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
886   gint current_page;
887
888   current_page = gtk_assistant_get_current_page (assistant);
889
890   if (current_page == PAGE_SALUT)
891     {
892       if (priv->create_salut_account)
893         account_assistant_apply_account_and_finish (self, priv->salut_settings);
894       return;
895     }
896   else if (current_page == PAGE_ENTER_CREATE &&
897       priv->settings != NULL &&
898       empathy_account_settings_is_valid (priv->settings))
899     {
900       account_assistant_apply_account_and_finish (self, priv->settings);
901     }
902 }
903
904 static void
905 impl_signal_cancel (GtkAssistant *assistant)
906 {
907   gtk_widget_destroy (GTK_WIDGET (assistant));
908 }
909
910 static void
911 impl_signal_prepare (GtkAssistant *assistant,
912     GtkWidget *current_page)
913 {
914   EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (assistant);
915   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
916   gint current_idx;
917
918   /* check from which page we are coming from */
919   switch (priv->current_page_id)
920     {
921       case PAGE_IMPORT:
922         empathy_import_widget_add_selected_accounts (priv->iw);
923         break;
924     }
925
926   current_idx = gtk_assistant_get_current_page (assistant);
927   priv->current_page_id = current_idx;
928
929   if (current_idx >= PAGE_ENTER_CREATE)
930     {
931       if (!priv->enter_create_forward && current_idx != PAGE_SALUT)
932         {
933           account_assistant_finish_enter_or_create_page (self,
934               priv->first_resp == RESPONSE_ENTER_ACCOUNT ?
935               TRUE : FALSE);
936         }
937       else
938         {
939           priv->enter_create_forward = FALSE;
940         }
941
942       if (priv->settings != NULL &&
943           empathy_account_settings_is_valid (priv->settings))
944         {
945           account_assistant_apply_account_and_finish (self, priv->settings);
946           g_object_unref (priv->settings);
947           priv->settings = NULL;
948         }
949     }
950 }
951
952 static void
953 do_get_property (GObject *object,
954     guint property_id,
955     GValue *value,
956     GParamSpec *pspec)
957 {
958   EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
959
960   switch (property_id)
961     {
962     case PROP_PARENT:
963       g_value_set_object (value, priv->parent_window);
964       break;
965     case PROP_CONNECTION_MGRS:
966       g_value_set_object (value, priv->connection_mgrs);
967       break;
968     default:
969       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
970     }
971 }
972
973 static void
974 do_set_property (GObject *object,
975     guint property_id,
976     const GValue *value,
977     GParamSpec *pspec)
978 {
979   EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
980
981   switch (property_id)
982     {
983     case PROP_PARENT:
984       priv->parent_window = g_value_get_object (value);
985       break;
986     case PROP_CONNECTION_MGRS:
987       priv->connection_mgrs = g_value_dup_object (value);
988       break;
989     default:
990       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
991     }
992 }
993
994 static void
995 do_dispose (GObject *obj)
996 {
997   EmpathyAccountAssistantPriv *priv = GET_PRIV (obj);
998
999   if (priv->dispose_run)
1000     return;
1001
1002   priv->dispose_run = TRUE;
1003
1004   if (priv->settings != NULL)
1005     {
1006       g_object_unref (priv->settings);
1007       priv->settings = NULL;
1008     }
1009
1010   g_object_unref (priv->account_mgr);
1011   priv->account_mgr = NULL;
1012
1013   g_object_unref (priv->connection_mgrs);
1014   priv->connection_mgrs = NULL;
1015
1016   if (G_OBJECT_CLASS (empathy_account_assistant_parent_class)->dispose != NULL)
1017     G_OBJECT_CLASS (empathy_account_assistant_parent_class)->dispose (obj);
1018 }
1019
1020 static void
1021 empathy_account_assistant_class_init (EmpathyAccountAssistantClass *klass)
1022 {
1023   GObjectClass *oclass = G_OBJECT_CLASS (klass);
1024   GtkAssistantClass *gtkclass = GTK_ASSISTANT_CLASS (klass);
1025   GParamSpec *param_spec;
1026
1027   oclass->get_property = do_get_property;
1028   oclass->set_property = do_set_property;
1029   oclass->constructed = do_constructed;
1030   oclass->dispose = do_dispose;
1031
1032   gtkclass->apply = impl_signal_apply;
1033   gtkclass->prepare = impl_signal_prepare;
1034   gtkclass->cancel = impl_signal_cancel;
1035
1036   param_spec = g_param_spec_object ("parent-window",
1037       "parent-window", "The parent window",
1038       GTK_TYPE_WINDOW,
1039       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1040   g_object_class_install_property (oclass, PROP_PARENT, param_spec);
1041
1042   param_spec = g_param_spec_object ("connection-managers",
1043       "connection-managers", "A EmpathyConnectionManagers",
1044       EMPATHY_TYPE_CONNECTION_MANAGERS,
1045       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
1046   g_object_class_install_property (oclass, PROP_CONNECTION_MGRS, param_spec);
1047
1048   g_type_class_add_private (klass, sizeof (EmpathyAccountAssistantPriv));
1049 }
1050
1051 static void
1052 create_salut_check_box_toggled_cb (GtkWidget *widget,
1053     EmpathyAccountAssistant *self)
1054 {
1055   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
1056   gboolean sensitive;
1057   gboolean page_valid;
1058
1059   sensitive = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
1060
1061   gtk_widget_set_sensitive (priv->salut_account_widget, sensitive);
1062
1063   if (!sensitive)
1064     {
1065       page_valid = TRUE;
1066       priv->create_salut_account = FALSE;
1067     }
1068   else
1069     {
1070       /* page is complete if the account is valid */
1071       page_valid = empathy_account_settings_is_valid (priv->salut_settings);
1072       priv->create_salut_account = TRUE;
1073     }
1074
1075   gtk_assistant_set_page_complete (GTK_ASSISTANT (self), priv->salut_page,
1076       page_valid);
1077 }
1078
1079 static void
1080 account_assistant_salut_handle_apply_cb (EmpathyAccountWidget *widget_object,
1081     gboolean is_valid,
1082     EmpathyAccountAssistant *self)
1083 {
1084   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
1085
1086   gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
1087       priv->salut_page, is_valid);
1088 }
1089
1090 static GtkWidget *
1091 account_assistant_build_salut_page (EmpathyAccountAssistant *self)
1092 {
1093   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
1094   GtkWidget *main_vbox, *hbox_1, *w;
1095   GdkPixbuf *pix;
1096   EmpathyAccountSettings *settings;
1097   GtkWidget *account_widget;
1098   EmpathyAccountWidget *widget_object;
1099   gchar *markup;
1100
1101   main_vbox = gtk_vbox_new (FALSE, 12);
1102   gtk_widget_show (main_vbox);
1103   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
1104
1105   hbox_1 = gtk_hbox_new (FALSE, 12);
1106   gtk_box_pack_start (GTK_BOX (main_vbox), hbox_1, TRUE, TRUE, 0);
1107   gtk_widget_show (hbox_1);
1108
1109   w = gtk_label_new ("");
1110   markup = g_strdup_printf ("%s (<span style=\"italic\">%s</span>).",
1111       _("Empathy can automatically discover and chat with the people "
1112         "connected on the same network as you. "
1113         "If you want to use this feature, please check that the "
1114         "details below are correct. "
1115         "You can easily change these details later or disable this feature "
1116         "by using the 'Accounts' dialog"),
1117       _("Edit->Accounts"));
1118   gtk_label_set_markup (GTK_LABEL (w), markup);
1119   g_free (markup);
1120   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
1121   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
1122   gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 0);
1123   gtk_widget_show (w);
1124
1125   pix = empathy_pixbuf_from_icon_name_sized ("im-local-xmpp", 80);
1126   w = gtk_image_new_from_pixbuf (pix);
1127   gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 6);
1128   gtk_widget_show (w);
1129
1130   g_object_unref (pix);
1131
1132   w = gtk_check_button_new_with_label (
1133       _("I don't want to enable this feature for now"));
1134   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
1135   g_signal_connect (w, "toggled",
1136       G_CALLBACK (create_salut_check_box_toggled_cb), self);
1137   gtk_widget_show (w);
1138
1139   w = gtk_alignment_new (0, 0, 0, 0);
1140   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
1141   gtk_box_pack_start (GTK_BOX (main_vbox), w, TRUE, TRUE, 0);
1142   gtk_widget_show (w);
1143
1144   settings = create_salut_account_settings ();
1145
1146   widget_object = empathy_account_widget_new_for_protocol (settings, TRUE);
1147   account_widget = empathy_account_widget_get_widget (widget_object);
1148
1149   priv->salut_settings = settings;
1150   priv->salut_account_widget = account_widget;
1151
1152   g_signal_connect (widget_object, "handle-apply",
1153       G_CALLBACK (account_assistant_salut_handle_apply_cb), self);
1154
1155   gtk_box_pack_start (GTK_BOX (main_vbox), account_widget,
1156       FALSE, FALSE, 0);
1157   gtk_widget_show (account_widget);
1158
1159   return main_vbox;
1160 }
1161
1162 static GtkWidget *
1163 account_assistant_build_salut_error_page (EmpathyAccountAssistant *self)
1164 {
1165   GtkWidget *vbox;
1166   gchar *markup;
1167
1168   markup = g_strdup_printf ("%s (<span style=\"italic\">%s</span>).",
1169       _("You won't be able to chat with people connected to your local "
1170         "network, as telepathy-salut is not installed. If you want to enable "
1171         "this feature, please install the telepathy-salut package and create "
1172         "a People Nearby account from the Accounts dialog"),
1173         _("Edit->Accounts"));
1174
1175   vbox = build_error_vbox (_("telepathy-salut not installed"), markup);
1176   g_free (markup);
1177   return vbox;
1178 }
1179
1180 static void
1181 account_mgr_prepare_cb (GObject *source_object,
1182     GAsyncResult *result,
1183     gpointer user_data)
1184 {
1185   EmpathyAccountAssistant *self = user_data;
1186   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
1187   TpAccountManager *manager = TP_ACCOUNT_MANAGER (source_object);
1188   GError *error = NULL;
1189
1190   if (!tp_account_manager_prepare_finish (manager, result, &error))
1191     {
1192       DEBUG ("Failed to prepare account manager: %s", error->message);
1193       g_error_free (error);
1194       return;
1195     }
1196
1197   if (!should_create_salut_account (manager))
1198     {
1199       DEBUG ("No need to create a Salut account");
1200       priv->display_salut_page = FALSE;
1201
1202       update_intro_page_buttons (self);
1203
1204       gtk_assistant_set_page_type (GTK_ASSISTANT (self), priv->import_page,
1205           GTK_ASSISTANT_PAGE_CONFIRM);
1206
1207       update_create_page_buttons (self);
1208     }
1209 }
1210
1211 static void
1212 empathy_account_assistant_init (EmpathyAccountAssistant *self)
1213 {
1214   EmpathyAccountAssistantPriv *priv;
1215
1216   priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_ACCOUNT_ASSISTANT,
1217       EmpathyAccountAssistantPriv);
1218   self->priv = priv;
1219
1220   priv->account_mgr = tp_account_manager_dup ();
1221 }
1222
1223 static void
1224 do_constructed (GObject *object)
1225 {
1226   GtkAssistant *assistant = GTK_ASSISTANT (object);
1227   EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (object);
1228   EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
1229   GtkWidget *page;
1230
1231   /* set us as transient for the parent window if any */
1232   if (priv->parent_window)
1233     gtk_window_set_transient_for (GTK_WINDOW (object),
1234         priv->parent_window);
1235
1236   /* set the dialog hint, so this will be centered over the parent window */
1237   gtk_window_set_type_hint (GTK_WINDOW (object), GDK_WINDOW_TYPE_HINT_DIALOG);
1238
1239   g_assert (priv->connection_mgrs != NULL);
1240   g_assert (empathy_connection_managers_is_ready (priv->connection_mgrs));
1241
1242   g_signal_connect (self, "close",
1243       G_CALLBACK (account_assistant_close_cb), NULL);
1244
1245   gtk_assistant_set_forward_page_func (assistant,
1246       account_assistant_page_forward_func, self, NULL);
1247
1248   /* first page (introduction) */
1249   page = account_assistant_build_introduction_page (self);
1250   gtk_assistant_append_page (assistant, page);
1251   gtk_assistant_set_page_title (assistant, page,
1252       _("Welcome to Empathy"));
1253   gtk_assistant_set_page_type (assistant, page,
1254       GTK_ASSISTANT_PAGE_INTRO);
1255   gtk_assistant_set_page_complete (assistant, page, TRUE);
1256
1257   /* second page (import accounts) */
1258   page = account_assistant_build_import_page (self);
1259   gtk_assistant_append_page (assistant, page);
1260   gtk_assistant_set_page_title (assistant, page,
1261       _("Import your existing accounts"));
1262   gtk_assistant_set_page_complete (assistant, page, TRUE);
1263   gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
1264   priv->import_page = page;
1265
1266   /* third page (enter account details) */
1267   page = account_assistant_build_enter_or_create_page (self);
1268   gtk_assistant_append_page (assistant, page);
1269   gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
1270   priv->enter_or_create_page = page;
1271
1272   /* fourth page (salut details) */
1273   if (empathy_connection_managers_get_cm (priv->connection_mgrs, "salut")
1274       != NULL)
1275     {
1276       page = account_assistant_build_salut_page (self);
1277       gtk_assistant_append_page (assistant, page);
1278       gtk_assistant_set_page_title (assistant, page,
1279           _("Please enter personal details"));
1280       gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
1281
1282       priv->create_salut_account = TRUE;
1283
1284       if (empathy_account_settings_is_valid (priv->salut_settings))
1285         {
1286           gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
1287               page, TRUE);
1288         }
1289     }
1290   else
1291     {
1292       page = account_assistant_build_salut_error_page (self);
1293       gtk_assistant_append_page (assistant, page);
1294       gtk_assistant_set_page_title (assistant, page, _("An error occurred"));
1295       gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_SUMMARY);
1296
1297       priv->create_salut_account = FALSE;
1298     }
1299
1300   priv->salut_page = page;
1301   priv->display_salut_page = TRUE;
1302
1303   tp_account_manager_prepare_async (priv->account_mgr, NULL,
1304       account_mgr_prepare_cb, self);
1305
1306   gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
1307 }
1308
1309 GtkWidget *
1310 empathy_account_assistant_show (GtkWindow *window,
1311     EmpathyConnectionManagers *connection_mgrs)
1312 {
1313   static GtkWidget *dialog = NULL;
1314
1315   if (dialog == NULL)
1316     {
1317       dialog =  g_object_new (EMPATHY_TYPE_ACCOUNT_ASSISTANT,
1318           "parent-window", window,
1319           "connection-managers", connection_mgrs,
1320           NULL);
1321       g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer *) &dialog);
1322     }
1323
1324   gtk_window_present (GTK_WINDOW (dialog));
1325
1326   return dialog;
1327 }
1328
1329