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