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