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