* make it compile again with latest Tinymail; does not work yet though.
[modest] / src / gtk / 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 "modest-account-assistant.h"
31 #include "modest-store-widget.h"
32 #include "modest-transport-widget.h"
33
34 #include <string.h>
35
36 /* 'private'/'protected' functions */
37 static void       modest_account_assistant_class_init    (ModestAccountAssistantClass *klass);
38 static void       modest_account_assistant_init          (ModestAccountAssistant *obj);
39 static void       modest_account_assistant_finalize      (GObject *obj);
40
41 /* list my signals */
42 enum {
43         /* MY_SIGNAL_1, */
44         /* MY_SIGNAL_2, */
45         LAST_SIGNAL
46 };
47
48 typedef struct _ModestAccountAssistantPrivate ModestAccountAssistantPrivate;
49 struct _ModestAccountAssistantPrivate {
50
51         ModestWidgetFactory *factory;
52         ModestAccountMgr *account_mgr;
53
54         GtkWidget *account_name;
55         GtkWidget *fullname;
56         GtkWidget *email;
57         
58         GtkWidget *store_widget;
59         GtkWidget *transport_widget;
60
61         GtkWidget *transport_holder;
62         GtkWidget *store_holder;        
63 };
64
65 #define MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
66                                                       MODEST_TYPE_ACCOUNT_ASSISTANT, \
67                                                       ModestAccountAssistantPrivate))
68 /* globals */
69 static GtkAssistantClass *parent_class = NULL;
70
71 /* uncomment the following if you have defined any signals */
72 /* static guint signals[LAST_SIGNAL] = {0}; */
73
74 GType
75 modest_account_assistant_get_type (void)
76 {
77         static GType my_type = 0;
78         if (!my_type) {
79                 static const GTypeInfo my_info = {
80                         sizeof(ModestAccountAssistantClass),
81                         NULL,           /* base init */
82                         NULL,           /* base finalize */
83                         (GClassInitFunc) modest_account_assistant_class_init,
84                         NULL,           /* class finalize */
85                         NULL,           /* class data */
86                         sizeof(ModestAccountAssistant),
87                         1,              /* n_preallocs */
88                         (GInstanceInitFunc) modest_account_assistant_init,
89                         NULL
90                 };
91                 my_type = g_type_register_static (GTK_TYPE_ASSISTANT,
92                                                   "ModestAccountAssistant",
93                                                   &my_info, 0);
94         }
95         return my_type;
96 }
97
98 static void
99 modest_account_assistant_class_init (ModestAccountAssistantClass *klass)
100 {
101         GObjectClass *gobject_class;
102         gobject_class = (GObjectClass*) klass;
103
104         parent_class            = g_type_class_peek_parent (klass);
105         gobject_class->finalize = modest_account_assistant_finalize;
106
107         g_type_class_add_private (gobject_class, sizeof(ModestAccountAssistantPrivate));
108
109         /* signal definitions go here, e.g.: */
110 /*      signals[MY_SIGNAL_1] = */
111 /*              g_signal_new ("my_signal_1",....); */
112 /*      signals[MY_SIGNAL_2] = */
113 /*              g_signal_new ("my_signal_2",....); */
114 /*      etc. */
115 }
116
117
118
119 static void
120 add_intro_page (ModestAccountAssistant *assistant)
121 {
122         GtkWidget *page, *label;
123         
124         page = gtk_vbox_new (FALSE, 6);
125         
126         label = gtk_label_new (
127                 _("Welcome to the account assistant\n\n"
128                   "It will help to set up a new e-mail account\n"));
129         gtk_box_pack_start (GTK_BOX(page), label, FALSE, FALSE, 6);
130         gtk_widget_show_all (page);
131         
132         gtk_assistant_append_page (GTK_ASSISTANT(assistant), page);
133                 
134         gtk_assistant_set_page_title (GTK_ASSISTANT(assistant), page,
135                                       _("Modest Account Assistant"));
136         gtk_assistant_set_page_type (GTK_ASSISTANT(assistant), page,
137                                      GTK_ASSISTANT_PAGE_INTRO);
138         gtk_assistant_set_page_complete (GTK_ASSISTANT(assistant),
139                                          page, TRUE);
140 }
141
142
143 static void
144 set_current_page_complete (ModestAccountAssistant *self, gboolean complete)
145 {
146         GtkWidget *page;
147         gint pageno;
148
149         pageno = gtk_assistant_get_current_page (GTK_ASSISTANT(self));
150         page   = gtk_assistant_get_nth_page (GTK_ASSISTANT(self), pageno);
151
152         gtk_assistant_set_page_complete (GTK_ASSISTANT(self), page, complete);
153 }
154
155
156 static void
157 identity_page_update_completeness (GtkEditable *editable,
158                                    ModestAccountAssistant *self)
159 {
160         ModestAccountAssistantPrivate *priv;
161         const gchar *txt;
162
163         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
164
165         txt = gtk_entry_get_text (GTK_ENTRY(priv->fullname));
166         if (!txt || strlen(txt) == 0) {
167                 set_current_page_complete (self, FALSE);
168                 return;
169         }
170
171         /* FIXME: regexp check for email address */
172         txt = gtk_entry_get_text (GTK_ENTRY(priv->email));
173         if (!txt || strlen(txt) == 0) {
174                 set_current_page_complete (self, FALSE);
175                 return;
176         }
177         set_current_page_complete (self, TRUE);
178 }
179
180
181 static void
182 add_identity_page (ModestAccountAssistant *self)
183 {
184         GtkWidget *page, *label, *table;
185         ModestAccountAssistantPrivate *priv;
186
187         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
188
189         priv->fullname = gtk_entry_new_with_max_length (40);
190         priv->email    = gtk_entry_new_with_max_length (40);
191         
192         page = gtk_vbox_new (FALSE, 6);
193
194         label = gtk_label_new (
195                 _("Please enter your name and your e-mail address below.\n\n"));
196         gtk_box_pack_start (GTK_BOX(page), label, FALSE, FALSE, 6);
197         
198         table = gtk_table_new (2,2, FALSE);
199         gtk_table_attach_defaults (GTK_TABLE(table),gtk_label_new (_("Full name")),
200                                    0,1,0,1);
201         gtk_table_attach_defaults (GTK_TABLE(table),gtk_label_new (_("E-mail address")),
202                                    0,1,1,2);
203         gtk_table_attach_defaults (GTK_TABLE(table),priv->fullname,
204                                    1,2,0,1);
205         gtk_table_attach_defaults (GTK_TABLE(table),priv->email,
206                                    1,2,1,2);
207
208         g_signal_connect (G_OBJECT(priv->fullname), "changed",
209                           G_CALLBACK(identity_page_update_completeness),
210                           self);
211         g_signal_connect (G_OBJECT(priv->email), "changed",
212                           G_CALLBACK(identity_page_update_completeness),
213                           self);
214         
215         gtk_box_pack_start (GTK_BOX(page), table, FALSE, FALSE, 6);
216         gtk_widget_show_all (page);
217         
218         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
219         
220         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
221                                       _("Identity"));
222         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
223                                      GTK_ASSISTANT_PAGE_INTRO);
224         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
225                                          page, FALSE);
226 }       
227
228
229 static void
230 on_receiving_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
231 {
232         ModestAccountAssistantPrivate *priv;
233         gchar *chosen;
234         
235         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
236         chosen = gtk_combo_box_get_active_text (GTK_COMBO_BOX(combo));
237
238         if (priv->store_widget)
239                 gtk_container_remove (GTK_CONTAINER(priv->store_holder),
240                                       priv->store_widget);
241         
242         priv->store_widget = modest_store_widget_new (priv->factory, chosen);
243
244         gtk_container_add (GTK_CONTAINER(priv->store_holder),
245                            priv->store_widget);
246         
247         gtk_widget_show_all (priv->store_holder);
248         
249 }       
250
251 static void
252 add_receiving_page (ModestAccountAssistant *self)
253 {
254         GtkWidget *page, *box, *combo;
255
256         ModestAccountAssistantPrivate *priv;
257
258         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);      
259         page = gtk_vbox_new (FALSE, 6);
260
261         gtk_box_pack_start (GTK_BOX(page),
262                             gtk_label_new (
263                                     _("Please select among the following options")),
264                             FALSE, FALSE, 6);
265         box = gtk_hbox_new (FALSE, 6);
266         gtk_box_pack_start (GTK_BOX(box),
267                             gtk_label_new(_("Server type")),
268                             FALSE,FALSE,6);
269
270         combo = modest_widget_factory_get_combo_box (priv->factory,
271                                                      MODEST_COMBO_BOX_TYPE_STORE_PROTOS);
272         g_signal_connect (G_OBJECT(combo), "changed",
273                           G_CALLBACK(on_receiving_combo_box_changed), self);
274
275         gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,6);
276         gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 6);
277         
278         gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
279
280         priv->store_holder = gtk_hbox_new (FALSE, 0);
281         gtk_box_pack_start (GTK_BOX(page), priv->store_holder,
282                             TRUE, TRUE, 0);
283         
284         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
285                 
286         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
287                                       _("Receiving mail"));
288         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
289                                      GTK_ASSISTANT_PAGE_INTRO);
290         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
291                                          page, TRUE);
292         gtk_widget_show_all (page);
293 }
294
295
296
297
298 static void
299 on_sending_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
300 {
301         ModestAccountAssistantPrivate *priv;
302         gchar *chosen;
303         
304         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
305
306         chosen = gtk_combo_box_get_active_text (GTK_COMBO_BOX(combo));
307
308         if (priv->transport_widget)
309                 gtk_container_remove (GTK_CONTAINER(priv->transport_holder),
310                                       priv->transport_widget);
311         
312         priv->transport_widget = modest_transport_widget_new (priv->factory,
313                                                               chosen);
314
315         gtk_container_add (GTK_CONTAINER(priv->transport_holder),
316                            priv->transport_widget);
317
318         gtk_widget_show_all (priv->transport_holder);
319 }
320
321
322
323 static void
324 add_sending_page (ModestAccountAssistant *self)
325 {
326         GtkWidget *page, *box, *combo;
327
328         ModestAccountAssistantPrivate *priv;
329
330         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
331         page = gtk_vbox_new (FALSE, 6);
332         
333         gtk_box_pack_start (GTK_BOX(page),
334                             gtk_label_new (
335                                     _("Please select among the following options")),
336                             FALSE, FALSE, 0);
337         box = gtk_hbox_new (FALSE, 0);
338         gtk_box_pack_start (GTK_BOX(box),
339                             gtk_label_new(_("Server type")),
340                             FALSE,FALSE,0);
341
342         combo = modest_widget_factory_get_combo_box (priv->factory,
343                                                      MODEST_COMBO_BOX_TYPE_TRANSPORT_PROTOS);
344         g_signal_connect (G_OBJECT(combo), "changed",
345                           G_CALLBACK(on_sending_combo_box_changed), self);
346
347         gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,0);
348         gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 0);
349         
350         gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
351
352         priv->transport_holder = gtk_hbox_new (FALSE, 0);
353         gtk_box_pack_start (GTK_BOX(page), priv->transport_holder,
354                             FALSE, FALSE, 0);
355         
356         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
357                 
358         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
359                                       _("Sending mail"));
360         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
361                                      GTK_ASSISTANT_PAGE_INTRO);
362         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
363                                          page, TRUE);
364         gtk_widget_show_all (page);
365 }
366
367
368
369 static void
370 add_final_page (ModestAccountAssistant *self)
371 {
372         GtkWidget *page, *box;
373         ModestAccountAssistantPrivate *priv;
374
375         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
376         page = gtk_vbox_new (FALSE, 6);
377         
378         gtk_box_pack_start (GTK_BOX(page),
379                             gtk_label_new (
380                                     _("We're almost done. Press 'Apply' to store this new account")),
381                             FALSE, FALSE, 6);
382         box = gtk_hbox_new (FALSE, 6);
383         priv->account_name =
384                 gtk_entry_new_with_max_length (40);
385         gtk_entry_set_text (GTK_ENTRY(priv->account_name),
386                             gtk_entry_get_text(GTK_ENTRY(priv->email)));
387         gtk_box_pack_start (GTK_BOX(box),gtk_label_new(_("Account name:")),
388                             FALSE,FALSE,6);
389         gtk_box_pack_start (GTK_BOX(box),priv->account_name , FALSE,FALSE,6);
390         
391         gtk_box_pack_start (GTK_BOX(page), box, FALSE, FALSE, 6);
392         
393         gtk_assistant_append_page (GTK_ASSISTANT(self), page);
394                 
395         gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
396                                       _("Account Management"));
397         gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
398                                      GTK_ASSISTANT_PAGE_CONFIRM);
399
400         gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
401                                          page, TRUE);
402         gtk_widget_show_all (page);
403 }
404         
405
406
407
408 static void
409 modest_account_assistant_init (ModestAccountAssistant *obj)
410 {       
411         ModestAccountAssistantPrivate *priv;
412                 
413         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(obj);       
414         priv->factory           = NULL;
415         priv->account_mgr       = NULL;
416
417         priv->store_widget      = NULL;
418         priv->transport_widget  = NULL;
419 }
420
421 static void
422 modest_account_assistant_finalize (GObject *obj)
423 {
424         ModestAccountAssistantPrivate *priv;
425                 
426         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(obj);
427
428         if (priv->factory) {
429                 g_object_unref (G_OBJECT(priv->factory));
430                 priv->factory = NULL;
431         }
432         
433         if (priv->account_mgr) {
434                 g_object_unref (G_OBJECT(priv->account_mgr));
435                 priv->account_mgr = NULL;
436         }
437
438
439
440         G_OBJECT_CLASS(parent_class)->finalize (obj);
441 }
442
443 static void
444 on_cancel (ModestAccountAssistant *self, gpointer user_data)
445 {
446         GtkWidget *label;
447         GtkWidget *dialog;
448         int response;
449         
450         label = gtk_label_new (_("Are you sure you want to cancel\n"
451                                  "setting up a new account?"));
452         
453         dialog = gtk_dialog_new_with_buttons (_("Cancel"),
454                                               GTK_WINDOW(self),
455                                               GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
456                                               GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
457                                               GTK_STOCK_NO,  GTK_RESPONSE_CANCEL,
458                                               NULL);
459         
460         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
461                             label, FALSE, FALSE, 6);
462
463         gtk_widget_show_all ((GTK_DIALOG(dialog)->vbox));
464         
465         gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
466         
467         response = gtk_dialog_run (GTK_DIALOG(dialog));
468         gtk_widget_destroy (dialog);
469
470         switch (response) {
471         case GTK_RESPONSE_ACCEPT:
472                 /* close the assistant */
473                 gtk_widget_destroy (GTK_WIDGET(self));
474                 break;
475         case GTK_RESPONSE_CANCEL:
476                 /* don't do anything */
477                 break;
478         default: g_assert_not_reached ();
479
480         };                           
481 }
482
483 static const gchar*
484 get_account_name (ModestAccountAssistant *self)
485 {
486         ModestAccountAssistantPrivate *priv;
487         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
488
489         return gtk_entry_get_text (GTK_ENTRY(priv->account_name));
490 }
491
492 static const gchar*
493 get_fullname (ModestAccountAssistant *self)
494 {
495         ModestAccountAssistantPrivate *priv;
496         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
497
498         return gtk_entry_get_text (GTK_ENTRY(priv->fullname));
499 }
500
501
502
503 static const gchar*
504 get_email (ModestAccountAssistant *self)
505 {
506         ModestAccountAssistantPrivate *priv;
507         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
508
509         return gtk_entry_get_text (GTK_ENTRY(priv->email));
510 }
511
512
513
514 static void
515 on_apply (ModestAccountAssistant *self, gpointer user_data)
516 {
517         ModestAccountAssistantPrivate *priv;
518         gchar *store_name;
519         const gchar *account_name;
520         ModestStoreWidget *store;
521
522         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
523
524         /* create account */
525
526         /* create server account -> store */
527         store = MODEST_STORE_WIDGET(priv->store_widget);
528         store_name = g_strdup_printf ("%s:%s@%s",
529                                       modest_store_widget_get_proto (store),
530                                       modest_store_widget_get_username (store),
531                                       modest_store_widget_get_servername (store));
532         
533         modest_account_mgr_add_server_account (priv->account_mgr,
534                                                 store_name,
535                                                 modest_store_widget_get_servername (store),
536                                                 modest_store_widget_get_username (store),
537                                                 NULL,
538                                                 modest_store_widget_get_proto (store));
539
540         /* create server account -> transport */
541         account_name = get_account_name (self);
542         modest_account_mgr_add_account (priv->account_mgr,
543                                         account_name,
544                                         store_name,
545                                         NULL, NULL);
546         modest_account_mgr_set_string (priv->account_mgr,
547                                        account_name,
548                                        MODEST_ACCOUNT_FULLNAME,
549                                        get_fullname(self), FALSE, NULL);
550         modest_account_mgr_set_string (priv->account_mgr,
551                                        account_name,
552                                        MODEST_ACCOUNT_EMAIL,
553                                        get_email(self), FALSE, NULL);
554         
555         g_free (store_name);
556 }
557
558
559
560 GtkWidget*
561 modest_account_assistant_new (ModestAccountMgr *account_mgr, ModestWidgetFactory *factory)
562 {
563         GObject *obj;
564         ModestAccountAssistant *self;
565         ModestAccountAssistantPrivate *priv;
566                 
567         g_return_val_if_fail (factory, NULL);
568         g_return_val_if_fail (account_mgr, NULL);
569         
570         obj  = g_object_new(MODEST_TYPE_ACCOUNT_ASSISTANT, NULL);
571         self = MODEST_ACCOUNT_ASSISTANT(obj);
572
573         priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
574         
575         g_object_ref (factory);
576         priv->factory = factory;
577         
578         g_object_ref (account_mgr);
579         priv->account_mgr = account_mgr;
580
581         add_intro_page (self);
582         add_identity_page (self); 
583         add_receiving_page (self); 
584         add_sending_page (self);
585         add_final_page (self);
586
587         gtk_assistant_set_current_page (GTK_ASSISTANT(self), 0);
588         gtk_window_set_title (GTK_WINDOW(self),
589                               _("Modest Account Wizard"));
590         gtk_window_set_resizable (GTK_WINDOW(self), TRUE);      
591         gtk_window_set_default_size (GTK_WINDOW(self), 400, 400);
592         
593         gtk_window_set_modal (GTK_WINDOW(self), TRUE);
594
595         g_signal_connect (G_OBJECT(self), "apply",
596                           G_CALLBACK(on_apply), NULL);
597         g_signal_connect (G_OBJECT(self), "cancel",
598                           G_CALLBACK(on_cancel), NULL);
599
600         return GTK_WIDGET(self);
601 }