* src/gnome/modest-account-view-window.c:
[modest] / src / gnome / modest-account-assistant.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <glib/gi18n.h>
31 #include <gtk/gtk.h>
32 #include <camel/camel-url.h>
33 #include <widgets/modest-combo-box.h>
34 #include "modest-account-assistant.h"
35 #include "modest-store-widget.h"
36 #include "modest-transport-widget.h"
37 #include "modest-text-utils.h"
38 #include <modest-protocol-info.h>
39
40 #include <string.h>
41
42 /* 'private'/'protected' functions */
43 static void       modest_account_assistant_class_init    (ModestAccountAssistantClass *klass);
44 static void       modest_account_assistant_init          (ModestAccountAssistant *obj);
45 static void       modest_account_assistant_finalize      (GObject *obj);
46
47 /* list my signals */
48 enum {
49         /* MY_SIGNAL_1, */
50         /* MY_SIGNAL_2, */
51         LAST_SIGNAL
52 };
53
54 typedef struct _ModestAccountAssistantPrivate ModestAccountAssistantPrivate;
55 struct _ModestAccountAssistantPrivate {
56
57         ModestAccountMgr *account_mgr;
58
59         GtkWidget *account_name;
60         GtkWidget *fullname;
61         GtkWidget *email;
62        
63         GtkWidget *username;
64         GtkWidget *password;
65         
66         GtkWidget *store_widget;
67         GtkWidget *transport_widget;
68
69         GtkWidget *transport_holder;
70         GtkWidget *store_holder;
71
72         ModestPairList *receiving_transport_store_protos;
73         ModestPairList *sending_transport_store_protos;
74 };
75
76 #define MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
77                                                       MODEST_TYPE_ACCOUNT_ASSISTANT, \
78                                                       ModestAccountAssistantPrivate))
79 /* globals */
80 static GtkAssistantClass *parent_class = NULL;
81
82 /* uncomment the following if you have defined any signals */
83 /* static guint signals[LAST_SIGNAL] = {0}; */
84
85 GType
86 modest_account_assistant_get_type (void)
87 {
88         static GType my_type = 0;
89         if (!my_type) {
90                 static const GTypeInfo my_info = {
91                         sizeof(ModestAccountAssistantClass),
92                         NULL,           /* base init */
93                         NULL,           /* base finalize */
94                         (GClassInitFunc) modest_account_assistant_class_init,
95                         NULL,           /* class finalize */
96                         NULL,           /* class data */
97                         sizeof(ModestAccountAssistant),
98                         1,              /* n_preallocs */
99                         (GInstanceInitFunc) modest_account_assistant_init,
100                         NULL
101                 };
102                 my_type = g_type_register_static (GTK_TYPE_ASSISTANT,
103                                                   "ModestAccountAssistant",
104                                                   &my_info, 0);
105         }
106         return my_type;
107 }
108
109 static void
110 modest_account_assistant_class_init (ModestAccountAssistantClass *klass)
111 {
112         GObjectClass *gobject_class;
113         gobject_class = (GObjectClass*) klass;
114
115         parent_class            = g_type_class_peek_parent (klass);
116         gobject_class->finalize = modest_account_assistant_finalize;
117
118         g_type_class_add_private (gobject_class, sizeof(ModestAccountAssistantPrivate));
119
120         /* signal definitions go here, e.g.: */
121 /*      signals[MY_SIGNAL_1] = */
122 /*              g_signal_new ("my_signal_1",....); */
123 /*      signals[MY_SIGNAL_2] = */
124 /*              g_signal_new ("my_signal_2",....); */
125 /*      etc. */
126 }
127
128
129
130 static void
131 add_intro_page (ModestAccountAssistant *assistant)
132 {
133         GtkWidget *page, *label;
134         
135         page = gtk_vbox_new (FALSE, 12);
136         
137         label = gtk_label_new (_("mcen_ia_emailsetup_intro"));
138         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
139         gtk_box_pack_start (GTK_BOX(page), label, FALSE, FALSE, 0);
140         gtk_widget_set_size_request (label, 400, -1);
141         gtk_widget_show_all (page);
142         
143         gtk_assistant_append_page (GTK_ASSISTANT(assistant), page);
144                 
145         gtk_assistant_set_page_title (GTK_ASSISTANT(assistant), page,
146                                       _("mcen_ti_emailsetup_welcome"));
147         gtk_assistant_set_page_type (GTK_ASSISTANT(assistant), page,
148                                      GTK_ASSISTANT_PAGE_INTRO);
149         gtk_assistant_set_page_complete (GTK_ASSISTANT(assistant),
150                                          page, TRUE);
151
152         return page;
153 }
154
155
156 static void
157 set_current_page_complete (ModestAccountAssistant *self, gboolean complete)
158 {
159         GtkWidget *page;
160         gint pageno;
161
162         pageno = gtk_assistant_get_current_page (GTK_ASSISTANT(self));
163
164         if (pageno != -1) {
165                 page   = gtk_assistant_get_nth_page (GTK_ASSISTANT(self), pageno);
166                 gtk_assistant_set_page_complete (GTK_ASSISTANT(self), page, complete);
167         }
168 }
169
170
171 static void
172 identity_page_update_completeness (GtkEditable *editable,
173                                    ModestAccountAssistant *self)
174 {
175         ModestAccountAssistantPrivate *priv;
176         const gchar *txt;
177
178         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
179
180         txt = gtk_entry_get_text (GTK_ENTRY(priv->fullname));
181         if (!txt || strlen(txt) == 0) {
182                 set_current_page_complete (self, FALSE);
183                 return;
184         }
185
186         /* FIXME: regexp check for email address */
187         txt = gtk_entry_get_text (GTK_ENTRY(priv->email));
188         if (!modest_text_utils_validate_email_address (txt, NULL)) {
189                 set_current_page_complete (self, FALSE);
190                 return;
191         }
192
193         txt = gtk_entry_get_text (GTK_ENTRY(priv->username));
194         if (!txt || txt[0] == '\0') {
195                 set_current_page_complete (self, FALSE);
196                 return;
197         }
198         set_current_page_complete (self, TRUE);
199 }
200
201 static GtkWidget *
202 field_name_label (const gchar *text)
203 {
204         GtkWidget *label;
205         gchar *fixed_text;
206
207         fixed_text = g_strconcat (text, ":", NULL);
208         label = gtk_label_new (fixed_text);
209         g_free (fixed_text);
210         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
211
212         return label;
213 }
214
215 static void
216 add_identity_page (ModestAccountAssistant *self)
217 {
218         GtkWidget *page, *label, *table, *frame;
219         GtkWidget *alignment;
220         ModestAccountAssistantPrivate *priv;
221
222         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
223
224         priv->account_name = gtk_entry_new ();
225         gtk_entry_set_max_length (GTK_ENTRY (priv->fullname), 40);
226         priv->fullname = gtk_entry_new ();
227         gtk_entry_set_max_length (GTK_ENTRY (priv->fullname), 40);
228         priv->email    = gtk_entry_new ();
229         gtk_entry_set_width_chars (GTK_ENTRY (priv->email), 40);
230         priv->username = gtk_entry_new ();
231         gtk_entry_set_width_chars (GTK_ENTRY (priv->username), 40);
232         priv->password = gtk_entry_new ();
233         gtk_entry_set_width_chars (GTK_ENTRY (priv->password), 40);
234         gtk_entry_set_visibility (GTK_ENTRY (priv->password), FALSE);
235         
236         page = gtk_vbox_new (FALSE, 24);
237
238         label = gtk_label_new (
239                 _("Please enter below the name for the account you're creating."));
240         gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
241         gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
242         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 0.0);
243         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 0, 12, 12);
244         gtk_container_add (GTK_CONTAINER (alignment), label);
245         gtk_box_pack_start (GTK_BOX(page), alignment, FALSE, FALSE, 0);
246         
247         table = gtk_table_new (1,2, FALSE);
248         gtk_table_set_col_spacings (GTK_TABLE (table), 6);
249         gtk_table_set_row_spacings (GTK_TABLE (table), 1);
250         gtk_table_attach_defaults (GTK_TABLE(table),field_name_label (_("Account name")),
251                                    0,1,0,1);
252         gtk_table_attach_defaults (GTK_TABLE(table),priv->account_name,
253                                    1,2,0,1);
254         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 0.0);
255         gtk_container_add (GTK_CONTAINER (alignment), table);
256         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 0, 12, 0);
257         gtk_box_pack_start (GTK_BOX(page), alignment, FALSE, FALSE, 0);
258
259         frame = gtk_frame_new (NULL);
260         label = gtk_label_new (NULL);
261         gtk_label_set_markup (GTK_LABEL (label), _("<b>Public information </b>"));
262         gtk_frame_set_label_widget (GTK_FRAME (frame), label);
263         gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
264         table = gtk_table_new (2,2, FALSE);
265         gtk_table_set_col_spacings (GTK_TABLE (table), 6);
266         gtk_table_set_row_spacings (GTK_TABLE (table), 3);
267         gtk_table_attach_defaults (GTK_TABLE(table),field_name_label (_("Full name")),
268                                    0,1,0,1);
269         gtk_table_attach_defaults (GTK_TABLE(table),field_name_label (_("Email address")),
270                                    0,1,1,2);
271         gtk_table_attach_defaults (GTK_TABLE(table),priv->fullname,
272                                    1,2,0,1);
273         gtk_table_attach_defaults (GTK_TABLE(table),priv->email,
274                                    1,2,1,2);
275         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 0.0);
276         gtk_container_add (GTK_CONTAINER (alignment), table);
277         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
278         gtk_container_add (GTK_CONTAINER (frame), alignment);
279         gtk_box_pack_start (GTK_BOX(page), frame, FALSE, FALSE, 0);
280
281
282         frame = gtk_frame_new (NULL);
283         label = gtk_label_new (NULL);
284         gtk_label_set_markup (GTK_LABEL (label), _("<b>Server account </b>"));
285         gtk_frame_set_label_widget (GTK_FRAME (frame), label);
286         gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
287         table = gtk_table_new (2,2, FALSE);
288         gtk_table_set_col_spacings (GTK_TABLE (table), 6);
289         gtk_table_set_row_spacings (GTK_TABLE (table), 3);
290         gtk_table_attach_defaults (GTK_TABLE(table),field_name_label (_("User name")),
291                                    0,1,0,1);
292         gtk_table_attach_defaults (GTK_TABLE(table),field_name_label (_("Password")),
293                                    0,1,1,2);
294         gtk_table_attach_defaults (GTK_TABLE(table),priv->username,
295                                    1,2,0,1);
296         gtk_table_attach_defaults (GTK_TABLE(table),priv->password,
297                                    1,2,1,2);
298         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 0.0);
299         gtk_container_add (GTK_CONTAINER (alignment), table);
300         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
301         gtk_container_add (GTK_CONTAINER (frame), alignment);
302         gtk_box_pack_start (GTK_BOX(page), frame, FALSE, FALSE, 0);
303
304         g_signal_connect (G_OBJECT(priv->fullname), "changed",
305                           G_CALLBACK(identity_page_update_completeness),
306                           self);
307         g_signal_connect (G_OBJECT(priv->username), "changed",
308                           G_CALLBACK(identity_page_update_completeness),
309                           self);
310         g_signal_connect (G_OBJECT(priv->password), "changed",
311                           G_CALLBACK(identity_page_update_completeness),
312                           self);
313         g_signal_connect (G_OBJECT(priv->email), "changed",
314                           G_CALLBACK(identity_page_update_completeness),
315                           self);
316         g_signal_connect (G_OBJECT(priv->account_name), "changed",
317                           G_CALLBACK(identity_page_update_completeness),
318                           self);
319         
320         
321         alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
322         gtk_container_add (GTK_CONTAINER (alignment), page);
323         gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 12, 12, 12, 12);
324         gtk_widget_show_all (alignment);
325         gtk_assistant_append_page (GTK_ASSISTANT(self), alignment);
326         
327         gtk_assistant_set_page_title (GTK_ASSISTANT(self), alignment,
328                                       _("Identity"));
329         gtk_assistant_set_page_type (GTK_ASSISTANT(self), alignment,
330                                      GTK_ASSISTANT_PAGE_CONTENT);
331         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
332                                          alignment, FALSE);
333 }       
334
335
336 static void
337 receiving_page_update_completeness (GtkEditable *editable,
338                                     ModestAccountAssistant *self)
339 {
340         ModestAccountAssistantPrivate *priv;
341         const gchar *txt;
342
343         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
344
345         txt = modest_store_widget_get_username (MODEST_STORE_WIDGET (priv->store_widget));
346         if (!txt || strlen(txt) == 0) {
347                 set_current_page_complete (self, FALSE);
348                 return;
349         }
350
351         txt = modest_store_widget_get_servername (MODEST_STORE_WIDGET (priv->store_widget));
352         if (!txt || strlen(txt) == 0) {
353                 set_current_page_complete (self, FALSE);
354                 return;
355         }
356         set_current_page_complete (self, TRUE);
357 }
358
359 static void
360 on_receiving_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
361 {
362         ModestAccountAssistantPrivate *priv;
363         gchar *chosen;
364         ModestTransportStoreProtocol proto;
365         
366         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
367         chosen = gtk_combo_box_get_active_text (GTK_COMBO_BOX(combo));
368         if (priv->store_widget)
369                 gtk_container_remove (GTK_CONTAINER(priv->store_holder),
370                                       priv->store_widget);
371
372         proto = modest_protocol_info_get_transport_store_protocol (chosen);
373         
374         /* FIXME: we could have these widgets cached instead of
375            creating them every time */
376         priv->store_widget = modest_store_widget_new (proto);
377         if (proto == MODEST_PROTOCOL_STORE_POP || proto == MODEST_PROTOCOL_STORE_IMAP) {
378                 g_signal_connect (priv->store_widget, 
379                                   "data_changed", 
380                                   G_CALLBACK (receiving_page_update_completeness), 
381                                   self);
382                 set_current_page_complete (self, FALSE);
383         } else
384                 set_current_page_complete (self, TRUE);
385
386         gtk_container_add (GTK_CONTAINER(priv->store_holder),
387                            priv->store_widget);
388         
389         gtk_widget_show_all (priv->store_holder);
390         
391 }       
392
393 static void
394 add_receiving_page (ModestAccountAssistant *self)
395 {
396         GtkWidget *page, *box, *combo;
397         ModestAccountAssistantPrivate *priv;
398
399         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);      
400         page = gtk_vbox_new (FALSE, 6);
401
402         gtk_box_pack_start (GTK_BOX(page),
403                             gtk_label_new (
404                                     _("Please select among the following options")),
405                             FALSE, FALSE, 6);
406         box = gtk_hbox_new (FALSE, 6);
407         gtk_box_pack_start (GTK_BOX(box),
408                             gtk_label_new(_("Server type")),
409                             FALSE,FALSE,6);
410
411         /* Note: This ModestPairList* must exist for as long as the combo
412          * that uses it, because the ModestComboBox uses the ID opaquely, 
413          * so it can't know how to manage its memory. */
414         priv->receiving_transport_store_protos = 
415                 modest_protocol_info_get_transport_store_protocol_pair_list ();
416         combo = modest_combo_box_new (priv->receiving_transport_store_protos, g_str_equal);
417         
418         g_signal_connect (G_OBJECT(combo), "changed",
419                           G_CALLBACK(on_receiving_combo_box_changed), self);
420
421         gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,6);
422         gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 6);
423
424         gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
425
426         priv->store_holder = gtk_hbox_new (FALSE, 0);
427         gtk_box_pack_start (GTK_BOX(page), priv->store_holder,
428                             TRUE, TRUE, 0);
429
430         /* Force the selection */
431         on_receiving_combo_box_changed (GTK_COMBO_BOX (combo), self);
432         
433         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
434                 
435         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
436                                       _("Receiving mail"));
437         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
438                                      GTK_ASSISTANT_PAGE_CONTENT);
439         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
440                                          page, FALSE);
441         gtk_widget_show_all (page);
442 }
443
444
445
446
447 static void
448 on_sending_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
449 {
450         ModestAccountAssistantPrivate *priv;
451         gchar *chosen;
452         
453         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
454
455         chosen = gtk_combo_box_get_active_text (GTK_COMBO_BOX(combo));
456
457         if (priv->transport_widget)
458                 gtk_container_remove (GTK_CONTAINER(priv->transport_holder),
459                                       priv->transport_widget);
460         priv->transport_widget =
461                 modest_transport_widget_new (modest_protocol_info_get_transport_store_protocol(chosen));
462
463         gtk_container_add (GTK_CONTAINER(priv->transport_holder),
464                            priv->transport_widget);
465
466         gtk_widget_show_all (priv->transport_holder);
467 }
468
469
470
471 static void
472 add_sending_page (ModestAccountAssistant *self)
473 {
474         GtkWidget *page, *box, *combo;
475         ModestAccountAssistantPrivate *priv;
476
477         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
478         page = gtk_vbox_new (FALSE, 6);
479         
480         gtk_box_pack_start (GTK_BOX(page),
481                             gtk_label_new (
482                                     _("Please select among the following options")),
483                             FALSE, FALSE, 0);
484         box = gtk_hbox_new (FALSE, 0);
485         gtk_box_pack_start (GTK_BOX(box),
486                             gtk_label_new(_("Server type")),
487                             FALSE,FALSE,0);
488         
489         /* Note: This ModestPairList* must exist for as long as the combo
490          * that uses it, because the ModestComboBox uses the ID opaquely, 
491          * so it can't know how to manage its memory. */
492         priv->sending_transport_store_protos = modest_protocol_info_get_transport_store_protocol_pair_list ();
493         combo = modest_combo_box_new (priv->sending_transport_store_protos, g_str_equal);
494
495         g_signal_connect (G_OBJECT(combo), "changed",
496                           G_CALLBACK(on_sending_combo_box_changed), self);
497
498         gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,0);
499         gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 0);
500
501         gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
502
503         priv->transport_holder = gtk_hbox_new (FALSE, 0);
504         gtk_box_pack_start (GTK_BOX(page), priv->transport_holder,
505                             FALSE, FALSE, 0);
506
507         /* Force the selection */
508         on_sending_combo_box_changed (GTK_COMBO_BOX (combo), self);
509
510         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
511                 
512         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
513                                       _("Sending mail"));
514         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
515                                      GTK_ASSISTANT_PAGE_INTRO);
516         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
517                                          page, TRUE);
518         gtk_widget_show_all (page);
519 }
520
521
522
523 static void
524 add_final_page (ModestAccountAssistant *self)
525 {
526         GtkWidget *page, *box;
527         ModestAccountAssistantPrivate *priv;
528
529         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
530         page = gtk_vbox_new (FALSE, 6);
531         
532         gtk_box_pack_start (GTK_BOX(page),
533                             gtk_label_new (
534                                     _("We're almost done. Press 'Apply' to store this new account")),
535                             FALSE, FALSE, 6);
536         box = gtk_hbox_new (FALSE, 6);
537         priv->account_name =
538                 gtk_entry_new_with_max_length (40);
539         gtk_entry_set_text (GTK_ENTRY(priv->account_name),
540                             gtk_entry_get_text(GTK_ENTRY(priv->email)));
541         gtk_box_pack_start (GTK_BOX(box),gtk_label_new(_("Account name:")),
542                             FALSE,FALSE,6);
543         gtk_box_pack_start (GTK_BOX(box),priv->account_name , FALSE,FALSE,6);
544         
545         gtk_box_pack_start (GTK_BOX(page), box, FALSE, FALSE, 6);
546         
547         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
548                 
549         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
550                                       _("Account Management"));
551         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
552                                      GTK_ASSISTANT_PAGE_CONFIRM);
553
554         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
555                                          page, TRUE);
556         gtk_widget_show_all (page);
557 }
558
559
560 static void
561 modest_account_assistant_init (ModestAccountAssistant *obj)
562 {       
563         ModestAccountAssistantPrivate *priv;    
564         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(obj);       
565
566         priv->account_mgr       = NULL;
567
568         priv->store_widget      = NULL;
569         priv->transport_widget  = NULL;
570 }
571
572 static void
573 modest_account_assistant_finalize (GObject *obj)
574 {
575         ModestAccountAssistantPrivate *priv;
576                 
577         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(obj);
578         
579         if (priv->account_mgr) {
580                 g_object_unref (G_OBJECT(priv->account_mgr));
581                 priv->account_mgr = NULL;
582         }
583         
584         /* These had to stay alive for as long as the comboboxes that used them: */
585         modest_pair_list_free (priv->receiving_transport_store_protos);
586         modest_pair_list_free (priv->sending_transport_store_protos);
587
588         G_OBJECT_CLASS(parent_class)->finalize (obj);
589 }
590
591 static void
592 on_cancel (ModestAccountAssistant *self, gpointer user_data)
593 {
594         GtkWidget *label;
595         GtkWidget *dialog;
596         int response;
597         
598         label = gtk_label_new (_("Are you sure you want to cancel\n"
599                                  "setting up a new account?"));
600         
601         dialog = gtk_dialog_new_with_buttons (_("Cancel"),
602                                               GTK_WINDOW(self),
603                                               GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
604                                               GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
605                                               GTK_STOCK_NO,  GTK_RESPONSE_CANCEL,
606                                               NULL);
607         
608         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
609                             label, FALSE, FALSE, 6);
610
611         gtk_widget_show_all ((GTK_DIALOG(dialog)->vbox));
612         
613         gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
614         
615         response = gtk_dialog_run (GTK_DIALOG(dialog));
616         gtk_widget_destroy (dialog);
617
618         switch (response) {
619         case GTK_RESPONSE_ACCEPT:
620                 /* close the assistant */
621                 gtk_widget_hide (GTK_WIDGET(self));
622                 break;
623         case GTK_RESPONSE_CANCEL:
624                 /* don't do anything */
625                 break;
626         default: g_assert_not_reached ();
627
628         };                           
629 }
630
631 static const gchar*
632 get_account_name (ModestAccountAssistant *self)
633 {
634         ModestAccountAssistantPrivate *priv;
635         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
636
637         return gtk_entry_get_text (GTK_ENTRY(priv->account_name));
638 }
639
640 static const gchar*
641 get_fullname (ModestAccountAssistant *self)
642 {
643         ModestAccountAssistantPrivate *priv;
644         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
645
646         return gtk_entry_get_text (GTK_ENTRY(priv->fullname));
647 }
648
649
650
651 static const gchar*
652 get_email (ModestAccountAssistant *self)
653 {
654         ModestAccountAssistantPrivate *priv;
655         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
656
657         return gtk_entry_get_text (GTK_ENTRY(priv->email));
658 }
659
660
661 static void
662 on_close (ModestAccountAssistant *self, gpointer user_data)
663 {
664         gtk_widget_hide (GTK_WIDGET (self));
665 }
666
667
668 /*
669  * FIXME: hmmmm this a Camel internal thing, should move this
670  * somewhere else
671  */
672 static gchar*
673 get_account_uri (ModestTransportStoreProtocol proto, const gchar* path)
674 {
675         CamelURL *url;
676         gchar *uri;
677         
678         switch (proto) {
679         case MODEST_PROTOCOL_STORE_MBOX:
680                 url = camel_url_new ("mbox:", NULL); break;
681         case MODEST_PROTOCOL_STORE_MAILDIR:
682                 url = camel_url_new ("maildir:", NULL); break;
683         default:
684                 g_return_val_if_reached (NULL);
685         }
686         camel_url_set_path (url, path);
687         uri = camel_url_to_string (url, 0);
688         camel_url_free (url);
689
690         return uri;     
691 }
692
693 static gchar*
694 get_new_server_account_name (ModestAccountMgr* acc_mgr, ModestTransportStoreProtocol proto,
695                              const gchar* username, const gchar *servername)
696 {
697         gchar *name;
698         gint  i = 0;
699         
700         while (TRUE) {
701                 name = g_strdup_printf ("%s:%d",
702                                         modest_protocol_info_get_transport_store_protocol_name(proto), i++);
703                 if (modest_account_mgr_account_exists (acc_mgr, name, TRUE))
704                         g_free (name);
705                 else
706                         break;
707         }
708         return name;
709 }
710
711
712 static void
713 on_apply (ModestAccountAssistant *self, gpointer user_data)
714 {
715         ModestAccountAssistantPrivate *priv;
716         ModestTransportStoreProtocol proto = MODEST_PROTOCOL_TRANSPORT_STORE_UNKNOWN;
717         ModestAuthProtocol security = MODEST_PROTOCOL_CONNECTION_NORMAL;
718         ModestConnectionProtocol auth = MODEST_PROTOCOL_AUTH_NONE;
719         gchar *store_name, *transport_name;
720         const gchar *account_name, *username, *servername, *path;
721         ModestStoreWidget *store;
722         ModestTransportWidget *transport;
723
724         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
725
726         /* create server account -> store */
727         store = MODEST_STORE_WIDGET(priv->store_widget);
728         proto    = modest_store_widget_get_proto (store);
729         username = modest_store_widget_get_username (store);
730         servername = modest_store_widget_get_servername (store);
731         path       = modest_store_widget_get_path (store);
732         security = modest_store_widget_get_security (store);
733         auth = modest_store_widget_get_auth (store);
734         store_name = get_new_server_account_name (priv->account_mgr, proto,username, servername);
735
736         if (proto == MODEST_PROTOCOL_STORE_MAILDIR ||
737             proto == MODEST_PROTOCOL_STORE_MBOX) {
738                 gchar *uri = get_account_uri (proto, path);
739                 modest_account_mgr_add_server_account_uri (priv->account_mgr, store_name, proto, uri);
740                 g_free (uri);
741         } else
742                 modest_account_mgr_add_server_account (priv->account_mgr,
743                                                        store_name, 
744                                                        servername,
745                                                        0, /* FIXME: does this mean default?*/
746                                                        username,
747                                                        NULL, 
748                                                        proto, 
749                                                        security, 
750                                                        auth);
751                 
752         /* create server account -> transport */
753         transport = MODEST_TRANSPORT_WIDGET(priv->transport_widget);
754         proto = modest_transport_widget_get_proto (transport);
755         username   = NULL;
756         servername = NULL;
757         if (proto == MODEST_PROTOCOL_TRANSPORT_SMTP) {
758                 servername = modest_transport_widget_get_servername (transport);
759                 if (modest_transport_widget_get_requires_auth (transport))
760                         username = modest_transport_widget_get_username (transport);
761         }
762         
763         transport_name = get_new_server_account_name (priv->account_mgr, proto,username, servername);
764         modest_account_mgr_add_server_account (priv->account_mgr,
765                                                transport_name,  servername,
766                                                0, /* FIXME: does this mean default?*/
767                                                username, NULL,
768                                                proto, security, auth);
769
770         /* create account */
771         account_name = get_account_name (self);
772         modest_account_mgr_add_account (priv->account_mgr,
773                                         account_name,
774                                         account_name,
775                                         get_fullname (self),
776                                         get_email (self),
777                                         MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY,
778                                         store_name,
779                                         transport_name, TRUE);
780
781         /* Frees */     
782         g_free (store_name);
783         g_free (transport_name);
784 }
785
786
787
788 GtkWidget*
789 modest_account_assistant_new (ModestAccountMgr *account_mgr)
790 {
791         GObject *obj;
792         ModestAccountAssistant *self;
793         ModestAccountAssistantPrivate *priv;
794
795         g_return_val_if_fail (account_mgr, NULL);
796         
797         obj  = g_object_new(MODEST_TYPE_ACCOUNT_ASSISTANT, NULL);
798         self = MODEST_ACCOUNT_ASSISTANT(obj);
799
800         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
801
802         g_object_ref (account_mgr);
803         priv->account_mgr = account_mgr;
804
805         add_intro_page (self);
806         add_identity_page (self); 
807         add_receiving_page (self); 
808         add_sending_page (self);
809         add_final_page (self);
810
811         gtk_assistant_set_current_page (GTK_ASSISTANT(self), 0);
812         gtk_window_set_title (GTK_WINDOW(self),
813                               _("Modest Account Wizard"));
814         gtk_window_set_resizable (GTK_WINDOW(self), TRUE);      
815         gtk_window_set_default_size (GTK_WINDOW(self), 400, 400);
816         
817         gtk_window_set_modal (GTK_WINDOW(self), TRUE);
818
819         g_signal_connect (G_OBJECT(self), "apply",
820                           G_CALLBACK(on_apply), NULL);
821         g_signal_connect (G_OBJECT(self), "cancel",
822                           G_CALLBACK(on_cancel), NULL);
823         g_signal_connect (G_OBJECT(self), "close",
824                           G_CALLBACK(on_close), NULL);
825
826         return GTK_WIDGET(self);
827 }