1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
30 #include <glib/gi18n.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>
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);
54 typedef struct _ModestAccountAssistantPrivate ModestAccountAssistantPrivate;
55 struct _ModestAccountAssistantPrivate {
57 ModestAccountMgr *account_mgr;
59 GtkWidget *account_name;
63 GtkWidget *store_widget;
64 GtkWidget *transport_widget;
66 GtkWidget *transport_holder;
67 GtkWidget *store_holder;
70 #define MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
71 MODEST_TYPE_ACCOUNT_ASSISTANT, \
72 ModestAccountAssistantPrivate))
74 static GtkAssistantClass *parent_class = NULL;
76 /* uncomment the following if you have defined any signals */
77 /* static guint signals[LAST_SIGNAL] = {0}; */
80 modest_account_assistant_get_type (void)
82 static GType my_type = 0;
84 static const GTypeInfo my_info = {
85 sizeof(ModestAccountAssistantClass),
87 NULL, /* base finalize */
88 (GClassInitFunc) modest_account_assistant_class_init,
89 NULL, /* class finalize */
90 NULL, /* class data */
91 sizeof(ModestAccountAssistant),
93 (GInstanceInitFunc) modest_account_assistant_init,
96 my_type = g_type_register_static (GTK_TYPE_ASSISTANT,
97 "ModestAccountAssistant",
104 modest_account_assistant_class_init (ModestAccountAssistantClass *klass)
106 GObjectClass *gobject_class;
107 gobject_class = (GObjectClass*) klass;
109 parent_class = g_type_class_peek_parent (klass);
110 gobject_class->finalize = modest_account_assistant_finalize;
112 g_type_class_add_private (gobject_class, sizeof(ModestAccountAssistantPrivate));
114 /* signal definitions go here, e.g.: */
115 /* signals[MY_SIGNAL_1] = */
116 /* g_signal_new ("my_signal_1",....); */
117 /* signals[MY_SIGNAL_2] = */
118 /* g_signal_new ("my_signal_2",....); */
125 add_intro_page (ModestAccountAssistant *assistant)
127 GtkWidget *page, *label;
129 page = gtk_vbox_new (FALSE, 6);
131 label = gtk_label_new (
132 _("Welcome to the account assistant\n\n"
133 "It will help to set up a new e-mail account\n"));
134 gtk_box_pack_start (GTK_BOX(page), label, FALSE, FALSE, 6);
135 gtk_widget_show_all (page);
137 gtk_assistant_append_page (GTK_ASSISTANT(assistant), page);
139 gtk_assistant_set_page_title (GTK_ASSISTANT(assistant), page,
140 _("Modest Account Assistant"));
141 gtk_assistant_set_page_type (GTK_ASSISTANT(assistant), page,
142 GTK_ASSISTANT_PAGE_INTRO);
143 gtk_assistant_set_page_complete (GTK_ASSISTANT(assistant),
149 set_current_page_complete (ModestAccountAssistant *self, gboolean complete)
154 pageno = gtk_assistant_get_current_page (GTK_ASSISTANT(self));
157 page = gtk_assistant_get_nth_page (GTK_ASSISTANT(self), pageno);
158 gtk_assistant_set_page_complete (GTK_ASSISTANT(self), page, complete);
164 identity_page_update_completeness (GtkEditable *editable,
165 ModestAccountAssistant *self)
167 ModestAccountAssistantPrivate *priv;
170 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
172 txt = gtk_entry_get_text (GTK_ENTRY(priv->fullname));
173 if (!txt || strlen(txt) == 0) {
174 set_current_page_complete (self, FALSE);
178 /* FIXME: regexp check for email address */
179 txt = gtk_entry_get_text (GTK_ENTRY(priv->email));
180 if (!modest_text_utils_validate_email_address (txt))
181 set_current_page_complete (self, FALSE);
183 set_current_page_complete (self, TRUE);
188 add_identity_page (ModestAccountAssistant *self)
190 GtkWidget *page, *label, *table;
191 ModestAccountAssistantPrivate *priv;
193 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
195 priv->fullname = gtk_entry_new_with_max_length (40);
196 priv->email = gtk_entry_new_with_max_length (40);
198 page = gtk_vbox_new (FALSE, 6);
200 label = gtk_label_new (
201 _("Please enter your name and your e-mail address below.\n\n"));
202 gtk_box_pack_start (GTK_BOX(page), label, FALSE, FALSE, 6);
204 table = gtk_table_new (2,2, FALSE);
205 gtk_table_attach_defaults (GTK_TABLE(table),gtk_label_new (_("Full name")),
207 gtk_table_attach_defaults (GTK_TABLE(table),gtk_label_new (_("E-mail address")),
209 gtk_table_attach_defaults (GTK_TABLE(table),priv->fullname,
211 gtk_table_attach_defaults (GTK_TABLE(table),priv->email,
214 g_signal_connect (G_OBJECT(priv->fullname), "changed",
215 G_CALLBACK(identity_page_update_completeness),
217 g_signal_connect (G_OBJECT(priv->email), "changed",
218 G_CALLBACK(identity_page_update_completeness),
221 gtk_box_pack_start (GTK_BOX(page), table, FALSE, FALSE, 6);
222 gtk_widget_show_all (page);
224 gtk_assistant_append_page (GTK_ASSISTANT(self), page);
226 gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
228 gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
229 GTK_ASSISTANT_PAGE_INTRO);
230 gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
236 receiving_page_update_completeness (GtkEditable *editable,
237 ModestAccountAssistant *self)
239 ModestAccountAssistantPrivate *priv;
242 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
244 txt = modest_store_widget_get_username (MODEST_STORE_WIDGET (priv->store_widget));
245 if (!txt || strlen(txt) == 0) {
246 set_current_page_complete (self, FALSE);
250 txt = modest_store_widget_get_servername (MODEST_STORE_WIDGET (priv->store_widget));
251 if (!txt || strlen(txt) == 0) {
252 set_current_page_complete (self, FALSE);
255 set_current_page_complete (self, TRUE);
259 on_receiving_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
261 ModestAccountAssistantPrivate *priv;
263 ModestProtocol proto;
265 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
266 chosen = gtk_combo_box_get_active_text (GTK_COMBO_BOX(combo));
267 if (priv->store_widget)
268 gtk_container_remove (GTK_CONTAINER(priv->store_holder),
271 proto = modest_protocol_info_get_protocol (chosen);
273 /* FIXME: we could have these widgets cached instead of
274 creating them every time */
275 priv->store_widget = modest_store_widget_new (proto);
276 if (proto == MODEST_PROTOCOL_STORE_POP || proto == MODEST_PROTOCOL_STORE_IMAP) {
277 g_signal_connect (priv->store_widget,
279 G_CALLBACK (receiving_page_update_completeness),
281 set_current_page_complete (self, FALSE);
283 set_current_page_complete (self, TRUE);
285 gtk_container_add (GTK_CONTAINER(priv->store_holder),
288 gtk_widget_show_all (priv->store_holder);
293 add_receiving_page (ModestAccountAssistant *self)
295 GtkWidget *page, *box, *combo;
296 ModestPairList *protos;
297 ModestAccountAssistantPrivate *priv;
299 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
300 page = gtk_vbox_new (FALSE, 6);
302 gtk_box_pack_start (GTK_BOX(page),
304 _("Please select among the following options")),
306 box = gtk_hbox_new (FALSE, 6);
307 gtk_box_pack_start (GTK_BOX(box),
308 gtk_label_new(_("Server type")),
311 protos = modest_protocol_info_get_protocol_pair_list (MODEST_PROTOCOL_TYPE_STORE);
312 combo = modest_combo_box_new (protos, g_str_equal);
313 modest_pair_list_free (protos);
315 g_signal_connect (G_OBJECT(combo), "changed",
316 G_CALLBACK(on_receiving_combo_box_changed), self);
318 gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,6);
319 gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 6);
321 gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
323 priv->store_holder = gtk_hbox_new (FALSE, 0);
324 gtk_box_pack_start (GTK_BOX(page), priv->store_holder,
327 /* Force the selection */
328 on_receiving_combo_box_changed (GTK_COMBO_BOX (combo), self);
330 gtk_assistant_append_page (GTK_ASSISTANT(self), page);
332 gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
333 _("Receiving mail"));
334 gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
335 GTK_ASSISTANT_PAGE_INTRO);
336 gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
338 gtk_widget_show_all (page);
345 on_sending_combo_box_changed (GtkComboBox *combo, ModestAccountAssistant *self)
347 ModestAccountAssistantPrivate *priv;
350 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
352 chosen = gtk_combo_box_get_active_text (GTK_COMBO_BOX(combo));
354 if (priv->transport_widget)
355 gtk_container_remove (GTK_CONTAINER(priv->transport_holder),
356 priv->transport_widget);
357 priv->transport_widget =
358 modest_transport_widget_new (modest_protocol_info_get_protocol(chosen));
360 gtk_container_add (GTK_CONTAINER(priv->transport_holder),
361 priv->transport_widget);
363 gtk_widget_show_all (priv->transport_holder);
369 add_sending_page (ModestAccountAssistant *self)
371 GtkWidget *page, *box, *combo;
372 ModestPairList *protos;
373 ModestAccountAssistantPrivate *priv;
375 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
376 page = gtk_vbox_new (FALSE, 6);
378 gtk_box_pack_start (GTK_BOX(page),
380 _("Please select among the following options")),
382 box = gtk_hbox_new (FALSE, 0);
383 gtk_box_pack_start (GTK_BOX(box),
384 gtk_label_new(_("Server type")),
387 protos = modest_protocol_info_get_protocol_pair_list (MODEST_PROTOCOL_TYPE_TRANSPORT);
388 combo = modest_combo_box_new (protos, g_str_equal);
389 modest_pair_list_free (protos);
391 g_signal_connect (G_OBJECT(combo), "changed",
392 G_CALLBACK(on_sending_combo_box_changed), self);
394 gtk_box_pack_start (GTK_BOX(box), combo, FALSE,FALSE,0);
395 gtk_box_pack_start (GTK_BOX(page), box, FALSE,FALSE, 0);
397 gtk_box_pack_start (GTK_BOX(page), gtk_hseparator_new(), FALSE, FALSE, 0);
399 priv->transport_holder = gtk_hbox_new (FALSE, 0);
400 gtk_box_pack_start (GTK_BOX(page), priv->transport_holder,
403 /* Force the selection */
404 on_sending_combo_box_changed (GTK_COMBO_BOX (combo), self);
406 gtk_assistant_append_page (GTK_ASSISTANT(self), page);
408 gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
410 gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
411 GTK_ASSISTANT_PAGE_INTRO);
412 gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
414 gtk_widget_show_all (page);
420 add_final_page (ModestAccountAssistant *self)
422 GtkWidget *page, *box;
423 ModestAccountAssistantPrivate *priv;
425 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
426 page = gtk_vbox_new (FALSE, 6);
428 gtk_box_pack_start (GTK_BOX(page),
430 _("We're almost done. Press 'Apply' to store this new account")),
432 box = gtk_hbox_new (FALSE, 6);
434 gtk_entry_new_with_max_length (40);
435 gtk_entry_set_text (GTK_ENTRY(priv->account_name),
436 gtk_entry_get_text(GTK_ENTRY(priv->email)));
437 gtk_box_pack_start (GTK_BOX(box),gtk_label_new(_("Account name:")),
439 gtk_box_pack_start (GTK_BOX(box),priv->account_name , FALSE,FALSE,6);
441 gtk_box_pack_start (GTK_BOX(page), box, FALSE, FALSE, 6);
443 gtk_assistant_append_page (GTK_ASSISTANT(self), page);
445 gtk_assistant_set_page_title (GTK_ASSISTANT(self), page,
446 _("Account Management"));
447 gtk_assistant_set_page_type (GTK_ASSISTANT(self), page,
448 GTK_ASSISTANT_PAGE_CONFIRM);
450 gtk_assistant_set_page_complete (GTK_ASSISTANT(self),
452 gtk_widget_show_all (page);
457 modest_account_assistant_init (ModestAccountAssistant *obj)
459 ModestAccountAssistantPrivate *priv;
460 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(obj);
462 priv->account_mgr = NULL;
464 priv->store_widget = NULL;
465 priv->transport_widget = NULL;
469 modest_account_assistant_finalize (GObject *obj)
471 ModestAccountAssistantPrivate *priv;
473 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(obj);
475 if (priv->account_mgr) {
476 g_object_unref (G_OBJECT(priv->account_mgr));
477 priv->account_mgr = NULL;
480 G_OBJECT_CLASS(parent_class)->finalize (obj);
484 on_cancel (ModestAccountAssistant *self, gpointer user_data)
490 label = gtk_label_new (_("Are you sure you want to cancel\n"
491 "setting up a new account?"));
493 dialog = gtk_dialog_new_with_buttons (_("Cancel"),
495 GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
496 GTK_STOCK_YES, GTK_RESPONSE_ACCEPT,
497 GTK_STOCK_NO, GTK_RESPONSE_CANCEL,
500 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
501 label, FALSE, FALSE, 6);
503 gtk_widget_show_all ((GTK_DIALOG(dialog)->vbox));
505 gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
507 response = gtk_dialog_run (GTK_DIALOG(dialog));
508 gtk_widget_destroy (dialog);
511 case GTK_RESPONSE_ACCEPT:
512 /* close the assistant */
513 gtk_widget_hide (GTK_WIDGET(self));
515 case GTK_RESPONSE_CANCEL:
516 /* don't do anything */
518 default: g_assert_not_reached ();
524 get_account_name (ModestAccountAssistant *self)
526 ModestAccountAssistantPrivate *priv;
527 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
529 return gtk_entry_get_text (GTK_ENTRY(priv->account_name));
533 get_fullname (ModestAccountAssistant *self)
535 ModestAccountAssistantPrivate *priv;
536 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
538 return gtk_entry_get_text (GTK_ENTRY(priv->fullname));
544 get_email (ModestAccountAssistant *self)
546 ModestAccountAssistantPrivate *priv;
547 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
549 return gtk_entry_get_text (GTK_ENTRY(priv->email));
554 on_close (ModestAccountAssistant *self, gpointer user_data)
556 gtk_widget_hide (GTK_WIDGET (self));
561 * FIXME: hmmmm this a Camel internal thing, should move this
565 get_account_uri (ModestProtocol proto, const gchar* path)
571 case MODEST_PROTOCOL_STORE_MBOX:
572 url = camel_url_new ("mbox:", NULL); break;
573 case MODEST_PROTOCOL_STORE_MAILDIR:
574 url = camel_url_new ("maildir:", NULL); break;
576 g_return_val_if_reached (NULL);
578 camel_url_set_path (url, path);
579 uri = camel_url_to_string (url, 0);
580 camel_url_free (url);
586 get_new_server_account_name (ModestAccountMgr* acc_mgr, ModestProtocol proto,
587 const gchar* username, const gchar *servername)
593 name = g_strdup_printf ("%s:%d",
594 modest_protocol_info_get_protocol_name(proto), i++);
595 if (modest_account_mgr_account_exists (acc_mgr, name, TRUE))
605 on_apply (ModestAccountAssistant *self, gpointer user_data)
607 ModestAccountAssistantPrivate *priv;
608 ModestProtocol proto, security, auth;
609 gchar *store_name, *transport_name;
610 const gchar *account_name, *username, *servername, *path;
611 ModestStoreWidget *store;
612 ModestTransportWidget *transport;
614 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
616 /* create server account -> store */
617 store = MODEST_STORE_WIDGET(priv->store_widget);
618 proto = modest_store_widget_get_proto (store);
619 username = modest_store_widget_get_username (store);
620 servername = modest_store_widget_get_servername (store);
621 path = modest_store_widget_get_path (store);
622 security = modest_store_widget_get_security (store);
623 auth = modest_store_widget_get_auth (store);
624 store_name = get_new_server_account_name (priv->account_mgr, proto,username, servername);
626 if (proto == MODEST_PROTOCOL_STORE_MAILDIR ||
627 proto == MODEST_PROTOCOL_STORE_MBOX) {
628 gchar *uri = get_account_uri (proto, path);
629 modest_account_mgr_add_server_account_uri (priv->account_mgr, store_name, proto, uri);
632 modest_account_mgr_add_server_account (priv->account_mgr, store_name, servername,
633 username, NULL, proto, security, auth);
635 /* create server account -> transport */
636 transport = MODEST_TRANSPORT_WIDGET(priv->transport_widget);
637 proto = modest_transport_widget_get_proto (transport);
640 if (proto == MODEST_PROTOCOL_TRANSPORT_SMTP) {
641 servername = modest_transport_widget_get_servername (transport);
642 if (modest_transport_widget_get_requires_auth (transport))
643 username = modest_transport_widget_get_username (transport);
646 transport_name = get_new_server_account_name (priv->account_mgr, proto,username, servername);
647 modest_account_mgr_add_server_account (priv->account_mgr,
648 transport_name, servername,
650 proto, security, auth);
653 account_name = get_account_name (self);
654 modest_account_mgr_add_account (priv->account_mgr,
658 modest_account_mgr_set_string (priv->account_mgr,
660 MODEST_ACCOUNT_FULLNAME,
661 get_fullname(self), FALSE);
662 modest_account_mgr_set_string (priv->account_mgr,
664 MODEST_ACCOUNT_EMAIL,
665 get_email(self), FALSE);
669 g_free (transport_name);
675 modest_account_assistant_new (ModestAccountMgr *account_mgr)
678 ModestAccountAssistant *self;
679 ModestAccountAssistantPrivate *priv;
681 g_return_val_if_fail (account_mgr, NULL);
683 obj = g_object_new(MODEST_TYPE_ACCOUNT_ASSISTANT, NULL);
684 self = MODEST_ACCOUNT_ASSISTANT(obj);
686 priv = MODEST_ACCOUNT_ASSISTANT_GET_PRIVATE(self);
688 g_object_ref (account_mgr);
689 priv->account_mgr = account_mgr;
691 add_intro_page (self);
692 add_identity_page (self);
693 add_receiving_page (self);
694 add_sending_page (self);
695 add_final_page (self);
697 gtk_assistant_set_current_page (GTK_ASSISTANT(self), 0);
698 gtk_window_set_title (GTK_WINDOW(self),
699 _("Modest Account Wizard"));
700 gtk_window_set_resizable (GTK_WINDOW(self), TRUE);
701 gtk_window_set_default_size (GTK_WINDOW(self), 400, 400);
703 gtk_window_set_modal (GTK_WINDOW(self), TRUE);
705 g_signal_connect (G_OBJECT(self), "apply",
706 G_CALLBACK(on_apply), NULL);
707 g_signal_connect (G_OBJECT(self), "cancel",
708 G_CALLBACK(on_cancel), NULL);
709 g_signal_connect (G_OBJECT(self), "close",
710 G_CALLBACK(on_close), NULL);
712 return GTK_WIDGET(self);