]> git.0d.be Git - empathy.git/blob - src/empathy-account-assistant.c
Don't hardcode new lines
[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
26 #include "empathy-account-assistant.h"
27 #include "empathy-import-dialog.h"
28 #include "empathy-import-widget.h"
29
30 #include <libempathy/empathy-account-settings.h>
31 #include <libempathy/empathy-utils.h>
32
33 #include <libempathy-gtk/empathy-account-widget.h>
34 #include <libempathy-gtk/empathy-protocol-chooser.h>
35 #include <libempathy-gtk/empathy-ui-utils.h>
36
37 G_DEFINE_TYPE (EmpathyAccountAssistant, empathy_account_assistant,
38     GTK_TYPE_ASSISTANT)
39
40 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountAssistant)
41
42 typedef enum {
43   RESPONSE_IMPORT = 1,
44   RESPONSE_ENTER_ACCOUNT = 2,
45   RESPONSE_CREATE_ACCOUNT = 3,
46   RESPONSE_SALUT_ONLY = 4
47 } FirstPageResponse;
48
49 enum {
50   PAGE_INTRO = 0,
51   PAGE_IMPORT = 1,
52   PAGE_ENTER_CREATE = 2,
53   PAGE_SALUT_ONLY = 3
54 };
55
56 enum {
57   PROP_PARENT = 1
58 };
59
60 typedef struct {
61   FirstPageResponse first_resp;
62
63   /* enter or create page */
64   GtkWidget *enter_or_create_page;
65   GtkWidget *current_account_widget;
66   EmpathyAccountWidget *current_widget_object;
67   GtkWidget *first_label;
68   GtkWidget *second_label;
69   GtkWidget *chooser;
70   EmpathyAccountSettings *settings;
71   gboolean is_creating;
72
73   /* import page */
74   EmpathyImportWidget *iw;
75
76   GtkWindow *parent_window;
77
78   gboolean dispose_run;
79 } EmpathyAccountAssistantPriv;
80
81 static GtkWidget *
82 account_assistant_build_error_page (EmpathyAccountAssistant *self,
83     GError *error, gint page_num)
84 {
85   GtkWidget *main_vbox, *w, *hbox;
86   GString *str;
87   char *message;
88   PangoAttrList *list;
89   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
90
91   main_vbox = gtk_vbox_new (FALSE, 12);
92   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
93   gtk_widget_show (main_vbox);
94
95   hbox = gtk_hbox_new (FALSE, 12);
96   gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
97   gtk_widget_show (hbox);
98
99   w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR,
100       GTK_ICON_SIZE_DIALOG);
101   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
102   gtk_widget_show (w);
103
104   /* translators: this is followed by the "while ..." strings some lines
105    * down this file.
106    */
107   str = g_string_new (_("There has been an error "));
108
109   if (page_num == PAGE_IMPORT)
110     /* translators: this follows the "There has been an error " string */
111     str = g_string_append (str, _("while importing the accounts."));
112   else if (page_num == PAGE_ENTER_CREATE &&
113       priv->first_resp == RESPONSE_ENTER_ACCOUNT)
114     /* translators: this follows the "There has been an error " string */
115     str = g_string_append (str, _("while parsing the account details."));
116   else if (page_num == PAGE_ENTER_CREATE &&
117       priv->first_resp == RESPONSE_CREATE_ACCOUNT)
118     /* translators: this follows the "There has been an error " string */
119     str = g_string_append (str, _("while creating the account."));
120
121   message = g_string_free (str, FALSE);
122
123   w = gtk_label_new (message);
124   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
125   list = pango_attr_list_new ();
126   pango_attr_list_insert (list, pango_attr_scale_new (PANGO_SCALE_LARGE));
127   pango_attr_list_insert (list, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
128   gtk_label_set_attributes (GTK_LABEL (w), list);
129   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
130   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
131   gtk_widget_show (w);
132
133   g_free (message);
134   pango_attr_list_unref (list);
135
136   message = g_markup_printf_escaped
137     (_("The error message was: <span style=\"italic\">%s</span>"),
138         error->message);
139   w = gtk_label_new (message);
140   gtk_label_set_use_markup (GTK_LABEL (w), TRUE);
141   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
142   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
143   gtk_widget_show (w);
144
145   w = gtk_label_new (_("You can either go back and try to enter your "
146           "accounts' details again or quit this wizard and add accounts "
147           "later from the Edit menu."));
148   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 6);
149   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
150   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
151   gtk_widget_show (w);
152
153   return main_vbox;
154 }
155
156 static void
157 account_assistant_back_button_clicked_cb (GtkButton *button,
158     EmpathyAccountAssistant *self)
159 {
160   gint page_num;
161
162   page_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
163           "page-num"));
164   gtk_assistant_remove_action_widget (GTK_ASSISTANT (self),
165       GTK_WIDGET (button));
166   gtk_assistant_set_current_page (GTK_ASSISTANT (self), page_num);
167 }
168
169 static void
170 account_assistant_present_error_page (EmpathyAccountAssistant *self,
171     GError *error, gint page_num)
172 {
173   GtkWidget *error_page, *back_button;
174   gint num;
175
176   error_page = account_assistant_build_error_page (self, error,
177       page_num);
178   num = gtk_assistant_append_page (GTK_ASSISTANT (self), error_page);
179   gtk_assistant_set_page_title (GTK_ASSISTANT (self), error_page,
180       _("An error occurred"));
181   gtk_assistant_set_page_type (GTK_ASSISTANT (self), error_page,
182       GTK_ASSISTANT_PAGE_SUMMARY);
183
184   back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
185   gtk_assistant_add_action_widget (GTK_ASSISTANT (self), back_button);
186   g_object_set_data (G_OBJECT (back_button),
187       "page-num", GINT_TO_POINTER (page_num));
188   g_signal_connect (back_button, "clicked",
189       G_CALLBACK (account_assistant_back_button_clicked_cb), self);
190   gtk_widget_show (back_button);
191
192   gtk_assistant_set_current_page (GTK_ASSISTANT (self), num);
193 }
194
195 static void
196 account_assistant_account_enabled_cb (GObject *source,
197     GAsyncResult *result,
198     gpointer user_data)
199 {
200   GError *error = NULL;
201   EmpathyAccountAssistant *self = user_data;
202
203   empathy_account_set_enabled_finish (EMPATHY_ACCOUNT (source),
204       result, &error);
205
206   if (error)
207     {
208       g_warning ("Error enabling an account: %s", error->message);
209       g_error_free (error);
210     }
211
212   g_signal_emit_by_name (self, "close");
213 }
214
215 static void
216 account_assistant_apply_account_cb (GObject *source,
217     GAsyncResult *result,
218     gpointer user_data)
219 {
220   GError *error = NULL;
221   EmpathyAccountAssistant *self = user_data;
222   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
223   EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source);
224   EmpathyAccount *account;
225
226   empathy_account_settings_apply_finish (settings, result, &error);
227
228   priv->is_creating = FALSE;
229
230   if (error != NULL)
231     {
232       account_assistant_present_error_page (self, error, PAGE_ENTER_CREATE);
233       g_error_free (error);
234       return;
235     }
236
237   /* enable the newly created account */
238   account = empathy_account_settings_get_account (settings);
239   empathy_account_set_enabled_async (account, TRUE,
240       account_assistant_account_enabled_cb, self);
241 }
242
243 static void
244 account_assistant_apply_account_and_finish (EmpathyAccountAssistant *self)
245 {
246   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
247
248   if (priv->settings == NULL)
249     return;
250
251   priv->is_creating = TRUE;
252
253   empathy_account_settings_apply_async (priv->settings,
254       account_assistant_apply_account_cb, self);
255 }
256
257 static void
258 account_assistant_handle_apply_cb (EmpathyAccountWidget *widget_object,
259     gboolean is_valid,
260     EmpathyAccountAssistant *self)
261 {
262   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
263
264   gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
265       priv->enter_or_create_page, is_valid);
266 }
267
268 static void
269 account_assistant_protocol_changed_cb (GtkComboBox *chooser,
270     EmpathyAccountAssistant *self)
271 {
272   TpConnectionManager *cm;
273   TpConnectionManagerProtocol *proto;
274   EmpathyAccountSettings *settings;
275   EmpathyAccountAssistantPriv *priv;
276   char *str;
277   GtkWidget *account_widget;
278   EmpathyAccountWidget *widget_object = NULL;
279
280   priv = GET_PRIV (self);
281
282   cm = empathy_protocol_chooser_dup_selected (
283       EMPATHY_PROTOCOL_CHOOSER (chooser), &proto);
284
285   if (cm == NULL || proto == NULL)
286     /* we are not ready yet */
287     return;
288
289   /* Create account */
290   /* To translator: %s is the protocol name */
291   str = g_strdup_printf (_("New %s account"), proto->name);
292
293   settings = empathy_account_settings_new (cm->name, proto->name, str);
294
295   if (priv->first_resp == RESPONSE_CREATE_ACCOUNT)
296     empathy_account_settings_set_boolean (settings, "register", TRUE);
297
298   account_widget = empathy_account_widget_simple_new_for_protocol
299     (proto->name, settings, &widget_object);
300
301   if (priv->current_account_widget != NULL)
302     {
303       g_signal_handlers_disconnect_by_func (priv->current_widget_object,
304           account_assistant_handle_apply_cb, self);
305       gtk_widget_destroy (priv->current_account_widget);
306     }
307
308   priv->current_account_widget = account_widget;
309   priv->current_widget_object = widget_object;
310
311   if (priv->settings != NULL)
312     g_object_unref (priv->settings);
313
314   priv->settings = settings;
315
316   g_signal_connect (priv->current_widget_object, "handle-apply",
317       G_CALLBACK (account_assistant_handle_apply_cb), self);
318
319   gtk_box_pack_start (GTK_BOX (priv->enter_or_create_page), account_widget,
320       FALSE, FALSE, 0);
321   gtk_widget_show (account_widget);
322
323   g_free (str);
324 }
325
326 static gboolean
327 account_assistant_chooser_enter_details_filter_func (
328     TpConnectionManager *cm,
329     TpConnectionManagerProtocol *protocol,
330     gpointer user_data)
331 {
332   if (!tp_strdiff (protocol->name, "local-xmpp") ||
333       !tp_strdiff (protocol->name, "irc"))
334     return FALSE;
335
336   return TRUE;
337 }
338
339 static gboolean
340 account_assistant_chooser_create_account_filter_func (
341     TpConnectionManager *cm,
342     TpConnectionManagerProtocol *protocol,
343     gpointer user_data)
344 {
345   return tp_connection_manager_protocol_can_register (protocol);
346 }
347
348 static void
349 account_assistant_finish_enter_or_create_page (EmpathyAccountAssistant *self,
350     gboolean is_enter)
351 {
352   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
353   
354   if (is_enter)
355     {
356       gtk_label_set_label (GTK_LABEL (priv->first_label),
357           _("What kind of chat account do you have?"));
358       gtk_label_set_label (GTK_LABEL (priv->second_label),
359           _("If you have other accounts to set up, you can do "
360               "that at any time from the Edit menu."));
361       empathy_protocol_chooser_set_visible (
362           EMPATHY_PROTOCOL_CHOOSER (priv->chooser),
363           account_assistant_chooser_enter_details_filter_func, self);
364
365       gtk_assistant_set_page_title (GTK_ASSISTANT (self),
366           priv->enter_or_create_page, _("Enter your account details"));
367     }
368   else
369     {
370       gtk_label_set_label (GTK_LABEL (priv->first_label),
371           _("What kind of chat account do you want to create?"));
372       gtk_label_set_label (GTK_LABEL (priv->second_label),
373           _("You can register other accounts, or setup "
374               "an existing one at any time from the Edit menu."));
375       empathy_protocol_chooser_set_visible (
376           EMPATHY_PROTOCOL_CHOOSER (priv->chooser),
377           account_assistant_chooser_create_account_filter_func, self);
378
379       gtk_assistant_set_page_title (GTK_ASSISTANT (self),
380           priv->enter_or_create_page,
381           _("Enter the details for the new account"));
382     }
383     
384   g_signal_connect (priv->chooser, "changed",
385       G_CALLBACK (account_assistant_protocol_changed_cb), self);
386  
387   /* trigger show the first account widget */
388   account_assistant_protocol_changed_cb (GTK_COMBO_BOX (priv->chooser), self);
389 }
390
391 static gint
392 account_assistant_page_forward_func (gint current_page,
393     gpointer user_data)
394 {
395   EmpathyAccountAssistant *self = user_data;
396   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
397   gint retval;
398
399   retval = current_page;
400
401   if (current_page == 0)
402     {
403       if (priv->first_resp == RESPONSE_ENTER_ACCOUNT ||
404           priv->first_resp == RESPONSE_CREATE_ACCOUNT)
405         retval = PAGE_ENTER_CREATE;
406       if (priv->first_resp == RESPONSE_IMPORT)
407         retval = PAGE_IMPORT;
408     }
409
410   if (current_page == PAGE_ENTER_CREATE ||
411       current_page == PAGE_IMPORT)
412     {
413       /* don't forward anymore */
414       retval = -1;
415     }
416
417   return retval;
418 }
419
420 static void
421 account_assistant_radio_choice_toggled_cb (GtkToggleButton *button,
422     EmpathyAccountAssistant *self)
423 {
424   FirstPageResponse response;
425   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
426   GtkWidget *intro_page;
427
428   response = GPOINTER_TO_INT (g_object_get_data
429       (G_OBJECT (button), "response"));
430
431   priv->first_resp = response;
432
433   intro_page = gtk_assistant_get_nth_page (GTK_ASSISTANT (self),
434       PAGE_INTRO);
435
436   if (response == RESPONSE_SALUT_ONLY)
437     gtk_assistant_set_page_type (GTK_ASSISTANT (self), intro_page,
438         GTK_ASSISTANT_PAGE_SUMMARY);
439   else
440     gtk_assistant_set_page_type (GTK_ASSISTANT (self), intro_page,
441         GTK_ASSISTANT_PAGE_INTRO);
442 }
443
444 static GtkWidget *
445 account_assistant_build_introduction_page (EmpathyAccountAssistant *self)
446 {
447   GtkWidget *main_vbox, *hbox_1, *w, *vbox_1;
448   GtkWidget *radio = NULL;
449   GdkPixbuf *pix;
450   const gchar *str;
451
452   main_vbox = gtk_vbox_new (FALSE, 12);
453   gtk_widget_show (main_vbox);
454   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
455
456   hbox_1 = gtk_hbox_new (FALSE, 12);
457   gtk_box_pack_start (GTK_BOX (main_vbox), hbox_1, TRUE, TRUE, 0);
458   gtk_widget_show (hbox_1);
459
460   w = gtk_label_new (
461       _("With Empathy you can chat with people "
462         "online nearby and with friends and colleagues "
463         "who use Google Talk, AIM, Windows Live "
464         "and many other chat programs. With a microphone "
465         "or a webcam you can also have audio or video calls."));
466   gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
467   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
468   gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 0);
469   gtk_widget_show (w);
470
471   pix = empathy_pixbuf_from_icon_name_sized ("empathy", 80);
472   w = gtk_image_new_from_pixbuf (pix);
473   gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 6);
474   gtk_widget_show (w);
475
476   g_object_unref (pix);
477
478   w = gtk_label_new (_("Do you have an account you've been using "
479           "with another chat program?"));
480   gtk_misc_set_alignment (GTK_MISC (w), 0, 0);
481   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
482   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
483   gtk_widget_show (w);
484
485   w = gtk_alignment_new (0, 0, 0, 0);
486   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
487   gtk_box_pack_start (GTK_BOX (main_vbox), w, TRUE, TRUE, 0);
488   gtk_widget_show (w);
489
490   vbox_1 = gtk_vbox_new (TRUE, 0);
491   gtk_container_add (GTK_CONTAINER (w), vbox_1);
492   gtk_widget_show (vbox_1);
493
494   if (empathy_import_dialog_accounts_to_import ())
495     {
496       hbox_1 = gtk_hbox_new (FALSE, 0);
497       gtk_box_pack_start (GTK_BOX (vbox_1), hbox_1, TRUE, TRUE, 0);
498       gtk_widget_show (hbox_1);
499
500       radio = gtk_radio_button_new_with_label (NULL,
501           _("Yes, import my account details from "));
502       gtk_box_pack_start (GTK_BOX (hbox_1), radio, TRUE, TRUE, 0);
503       g_object_set_data (G_OBJECT (radio), "response",
504           GINT_TO_POINTER (RESPONSE_IMPORT));
505       gtk_widget_show (radio);
506
507       w = gtk_combo_box_new_text ();
508       gtk_combo_box_append_text (GTK_COMBO_BOX (w), "Pidgin");
509       gtk_box_pack_start (GTK_BOX (hbox_1), w, TRUE, TRUE, 0);
510       gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
511       gtk_widget_show (w);
512
513       g_signal_connect (radio, "clicked",
514           G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
515     }
516
517   str = _("Yes, I'll enter my account details now");
518
519   if (radio == NULL)
520     {      
521       radio = gtk_radio_button_new_with_label (NULL, str);
522       w = radio;
523     }
524   else
525     {
526       w = gtk_radio_button_new_with_label_from_widget (
527           GTK_RADIO_BUTTON (radio), str);
528     }
529
530   gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
531   g_object_set_data (G_OBJECT (w), "response",
532       GINT_TO_POINTER (RESPONSE_ENTER_ACCOUNT));
533   gtk_widget_show (w);
534
535   g_signal_connect (w, "clicked",
536       G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
537
538   w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
539       _("No, I want a new account"));
540   gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
541   g_object_set_data (G_OBJECT (w), "response",
542       GINT_TO_POINTER (RESPONSE_CREATE_ACCOUNT));
543   gtk_widget_show (w);
544
545   g_signal_connect (w, "clicked",
546       G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
547
548   w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
549       _("No, I just want to see people online nearby for now"));
550   gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
551   g_object_set_data (G_OBJECT (w), "response",
552       GINT_TO_POINTER (RESPONSE_SALUT_ONLY));
553   gtk_widget_show (w);
554
555   g_signal_connect (w, "clicked",
556       G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
557
558   return main_vbox;
559 }
560
561 static GtkWidget *
562 account_assistant_build_import_page (EmpathyAccountAssistant *self)
563 {
564   GtkWidget *main_vbox, *w, *import;
565   EmpathyImportWidget *iw;
566   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
567
568   main_vbox = gtk_vbox_new (FALSE, 12);
569   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
570   w = gtk_label_new (_("Select the accounts you want to import:"));
571   gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
572   gtk_widget_show (w);
573   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 6);
574
575   w = gtk_alignment_new (0, 0, 0, 0);
576   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
577   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
578   gtk_widget_show (w);
579
580   iw = empathy_import_widget_new ();
581   import = empathy_import_widget_get_widget (iw);
582   gtk_container_add (GTK_CONTAINER (w), import);
583   gtk_widget_show (import);
584
585   priv->iw = iw;
586
587   gtk_widget_show (main_vbox);
588
589   return main_vbox;
590 }
591
592 static GtkWidget *
593 account_assistant_build_enter_or_create_page (EmpathyAccountAssistant *self,
594     gboolean is_enter)
595 {
596   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
597   GtkWidget *main_vbox, *w, *chooser, *hbox;
598   PangoAttrList *list;
599
600   main_vbox = gtk_vbox_new (FALSE, 12);
601   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
602   gtk_widget_show (main_vbox);
603
604   w = gtk_label_new (NULL);
605   gtk_misc_set_alignment (GTK_MISC (w), 0, 0);
606   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
607   gtk_widget_show (w);
608   priv->first_label = w;
609
610   w = gtk_alignment_new (0, 0, 0, 0);
611   gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
612   gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
613   gtk_widget_show (w);
614
615   chooser = empathy_protocol_chooser_new ();
616   gtk_container_add (GTK_CONTAINER (w), chooser);
617   gtk_widget_show (chooser);
618   priv->chooser = chooser;
619
620   hbox = gtk_hbox_new (FALSE, 6);
621   gtk_box_pack_end (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
622   gtk_widget_show (hbox);
623
624   w = gtk_image_new_from_icon_name ("gtk-dialog-info", GTK_ICON_SIZE_BUTTON);
625   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
626   gtk_widget_show (w);
627
628   w = gtk_label_new (NULL);
629   gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
630   list = pango_attr_list_new ();
631   pango_attr_list_insert (list, pango_attr_scale_new (PANGO_SCALE_SMALL));
632   gtk_label_set_attributes (GTK_LABEL (w), list);
633   gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
634   gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
635   gtk_widget_show (w);
636   priv->second_label = w;
637   pango_attr_list_unref (list);
638
639   return main_vbox;
640 }
641
642 static void
643 account_assistant_close_cb (GtkAssistant *assistant,
644     gpointer user_data)
645 {
646   EmpathyAccountAssistantPriv *priv = GET_PRIV (assistant);
647
648   if (priv->is_creating)
649     return;
650
651   gtk_widget_destroy (GTK_WIDGET (assistant));
652 }
653
654 static void
655 impl_signal_apply (GtkAssistant *assistant)
656 {
657   EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (assistant);
658   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
659   gint current_page;
660
661   current_page = gtk_assistant_get_current_page (assistant);
662
663   if (current_page == RESPONSE_ENTER_ACCOUNT)
664     account_assistant_apply_account_and_finish (self);
665
666   if (current_page == RESPONSE_IMPORT)
667     empathy_import_widget_add_selected_accounts (priv->iw);
668 }
669
670 static void
671 impl_signal_cancel (GtkAssistant *assistant)
672 {
673   gtk_widget_destroy (GTK_WIDGET (assistant));
674 }
675
676 static void
677 impl_signal_prepare (GtkAssistant *assistant,
678     GtkWidget *current_page)
679 {
680   EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (assistant);
681   EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
682   gint current_idx;
683
684   current_idx = gtk_assistant_get_current_page (assistant);
685
686   if (current_idx == PAGE_ENTER_CREATE)
687     {
688       account_assistant_finish_enter_or_create_page (self,
689           priv->first_resp == RESPONSE_ENTER_ACCOUNT ?
690           TRUE : FALSE);
691     }
692 }
693
694 static void
695 do_get_property (GObject *object,
696     guint property_id,
697     GValue *value,
698     GParamSpec *pspec)
699 {
700   EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
701
702   switch (property_id)
703     {
704     case PROP_PARENT:
705       g_value_set_object (value, priv->parent_window);
706       break;
707     default:
708       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
709     }
710 }
711
712 static void
713 do_set_property (GObject *object,
714     guint property_id,
715     const GValue *value,
716     GParamSpec *pspec)
717 {
718   EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
719
720   switch (property_id)
721     {
722     case PROP_PARENT:
723       priv->parent_window = g_value_get_object (value);
724       break;
725     default:
726       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
727     }
728 }
729
730 static void
731 do_constructed (GObject *object)
732 {
733   EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
734
735   /* set us as transient for the parent window if any */
736   if (priv->parent_window)
737     gtk_window_set_transient_for (GTK_WINDOW (object),
738         priv->parent_window);
739
740   /* set the dialog hint, so this will be centered over the parent window */
741   gtk_window_set_type_hint (GTK_WINDOW (object), GDK_WINDOW_TYPE_HINT_DIALOG);
742 }
743
744 static void
745 do_dispose (GObject *obj)
746 {
747   EmpathyAccountAssistantPriv *priv = GET_PRIV (obj);
748
749   if (priv->dispose_run)
750     return;
751
752   priv->dispose_run = TRUE;
753
754   if (priv->settings != NULL)
755     {
756       g_object_unref (priv->settings);
757       priv->settings = NULL;
758     }
759
760   if (G_OBJECT_CLASS (empathy_account_assistant_parent_class)->dispose != NULL)
761     G_OBJECT_CLASS (empathy_account_assistant_parent_class)->dispose (obj);
762 }
763
764 static void
765 empathy_account_assistant_class_init (EmpathyAccountAssistantClass *klass)
766 {
767   GObjectClass *oclass = G_OBJECT_CLASS (klass);
768   GtkAssistantClass *gtkclass = GTK_ASSISTANT_CLASS (klass);
769   GParamSpec *param_spec;
770
771   oclass->get_property = do_get_property;
772   oclass->set_property = do_set_property;
773   oclass->constructed = do_constructed;
774   oclass->dispose = do_dispose;
775
776   gtkclass->apply = impl_signal_apply;
777   gtkclass->prepare = impl_signal_prepare;
778   gtkclass->cancel = impl_signal_cancel;
779
780   param_spec = g_param_spec_object ("parent-window",
781       "parent-window", "The parent window",
782       GTK_TYPE_WINDOW,
783       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
784   g_object_class_install_property (oclass, PROP_PARENT, param_spec);
785
786   g_type_class_add_private (klass, sizeof (EmpathyAccountAssistantPriv));
787 }
788
789 static void
790 empathy_account_assistant_init (EmpathyAccountAssistant *self)
791 {
792   EmpathyAccountAssistantPriv *priv;
793   GtkAssistant *assistant = GTK_ASSISTANT (self);
794   GtkWidget *page;
795
796   priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_ACCOUNT_ASSISTANT,
797       EmpathyAccountAssistantPriv);
798   self->priv = priv;
799
800   g_signal_connect (self, "close",
801       G_CALLBACK (account_assistant_close_cb), NULL);
802
803   gtk_assistant_set_forward_page_func (assistant,
804       account_assistant_page_forward_func, self, NULL);
805
806   /* first page (introduction) */
807   page = account_assistant_build_introduction_page (self);
808   gtk_assistant_append_page (assistant, page);
809   gtk_assistant_set_page_title (assistant, page,
810       _("Welcome to Empathy"));
811   gtk_assistant_set_page_type (assistant, page,
812       GTK_ASSISTANT_PAGE_INTRO);
813   gtk_assistant_set_page_complete (assistant, page, TRUE);
814
815   /* set a default answer */
816   priv->first_resp = RESPONSE_IMPORT;
817
818   /* second page (import accounts) */
819   page = account_assistant_build_import_page (self);
820   gtk_assistant_append_page (assistant, page);
821   gtk_assistant_set_page_title (assistant, page,
822       _("Import your existing accounts"));
823   gtk_assistant_set_page_complete (assistant, page, TRUE);
824   gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
825
826   /* third page (enter account details) */
827   page = account_assistant_build_enter_or_create_page (self, TRUE);
828   gtk_assistant_append_page (assistant, page);
829   gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
830   priv->enter_or_create_page = page;
831 }
832
833 GtkWidget *
834 empathy_account_assistant_new (GtkWindow *window)
835 {
836   return g_object_new (EMPATHY_TYPE_ACCOUNT_ASSISTANT, "parent-window",
837       window, NULL);
838 }