source: trunk/third/evolution/mail/mail-account-gui.c @ 21336

Revision 21336, 78.5 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21335, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 *  Authors:
4 *    Dan Winship <danw@ximian.com>
5 *    Jeffrey Stedfast <fejj@ximian.com>
6 *
7 *  Copyright 2001 Ximian, Inc. (www.ximian.com)
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <glib.h>
30
31#include <string.h>
32#include <stdarg.h>
33#include <sys/stat.h>
34
35#include <gconf/gconf-client.h>
36
37#include <gtk/gtkentry.h>
38#include <gtk/gtktogglebutton.h>
39#include <gtk/gtktextbuffer.h>
40#include <gtk/gtktextview.h>
41#include <gtk/gtkcheckbutton.h>
42#include <gtk/gtkspinbutton.h>
43#include <gtk/gtkmenuitem.h>
44#include <gtk/gtkoptionmenu.h>
45#include <gtk/gtknotebook.h>
46#include <gtk/gtkhbox.h>
47#include <gtk/gtkdialog.h>
48#include <gtk/gtkstock.h>
49#ifdef USE_GTKFILECHOOSER
50#include <gtk/gtkfilechooser.h>
51#include <gtk/gtkradiobutton.h>
52#include <libgnomeui/gnome-file-entry.h>
53#endif
54
55#include <e-util/e-account-list.h>
56#include <e-util/e-signature-list.h>
57
58#include <widgets/misc/e-error.h>
59
60#include "em-account-prefs.h"
61#include "em-folder-selection-button.h"
62#include "mail-account-gui.h"
63#include "mail-session.h"
64#include "mail-send-recv.h"
65#include "mail-signature-editor.h"
66#include "mail-component.h"
67#include "em-utils.h"
68#include "em-composer-prefs.h"
69#include "mail-config.h"
70#include "mail-ops.h"
71#include "mail-mt.h"
72
73#if defined (HAVE_NSS)
74#include "smime/gui/e-cert-selector.h"
75#endif
76
77#define d(x)
78
79static void save_service (MailAccountGuiService *gsvc, GHashTable *extra_conf, EAccountService *service);
80static void service_changed (GtkEntry *entry, gpointer user_data);
81
82struct {
83        char *label;
84        char *value;
85} ssl_options[] = {
86        { N_("Always"), "always" },
87        { N_("Whenever Possible"), "when-possible" },
88        { N_("Never"), "never" }
89};
90
91static int num_ssl_options = sizeof (ssl_options) / sizeof (ssl_options[0]);
92
93static gboolean
94is_email (const char *address)
95{
96        /* This is supposed to check if the address's domain could be
97           an FQDN but alas, it's not worth the pain and suffering. */
98        const char *at;
99       
100        at = strchr (address, '@');
101        /* make sure we have an '@' and that it's not the first or last char */
102        if (!at || at == address || *(at + 1) == '\0')
103                return FALSE;
104       
105        return TRUE;
106}
107
108static GtkWidget *
109get_focused_widget (GtkWidget *def, ...)
110{
111        GtkWidget *widget, *ret = NULL;
112        va_list args;
113       
114        va_start (args, def);
115        widget = va_arg (args, GtkWidget *);
116        while (widget) {
117                if (GTK_WIDGET_HAS_FOCUS (widget)) {
118                        ret = widget;
119                        break;
120                }
121               
122                widget = va_arg (args, GtkWidget *);
123        }
124        va_end (args);
125       
126        if (ret)
127                return ret;
128        else
129                return def;
130}
131
132gboolean
133mail_account_gui_identity_complete (MailAccountGui *gui, GtkWidget **incomplete)
134{
135        const char *text;
136       
137        text = gtk_entry_get_text (gui->full_name);
138        if (!text || !*text) {
139                if (incomplete)
140                        *incomplete = get_focused_widget (GTK_WIDGET (gui->full_name),
141                                                          GTK_WIDGET (gui->email_address),
142                                                          GTK_WIDGET (gui->reply_to),
143                                                          NULL);
144                return FALSE;
145        }
146       
147        text = gtk_entry_get_text (gui->email_address);
148        if (!text || !is_email (text)) {
149                if (incomplete)
150                        *incomplete = get_focused_widget (GTK_WIDGET (gui->email_address),
151                                                          GTK_WIDGET (gui->full_name),
152                                                          GTK_WIDGET (gui->reply_to),
153                                                          NULL);
154                return FALSE;
155        }
156       
157        /* make sure that if the reply-to field is filled in, that it is valid */
158        text = gtk_entry_get_text (gui->reply_to);
159        if (text && *text && !is_email (text)) {
160                if (incomplete)
161                        *incomplete = get_focused_widget (GTK_WIDGET (gui->reply_to),
162                                                          GTK_WIDGET (gui->email_address),
163                                                          GTK_WIDGET (gui->full_name),
164                                                          NULL);
165                return FALSE;
166        }
167       
168        return TRUE;
169}
170
171static void
172auto_detected_foreach (gpointer key, gpointer value, gpointer user_data)
173{
174        g_free (key);
175        g_free (value);
176}
177
178static void
179check_button_state (GtkToggleButton *button, gpointer data)
180{
181        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button)))
182                gtk_widget_set_sensitive (GTK_WIDGET (data), TRUE);
183        else
184                gtk_widget_set_sensitive (GTK_WIDGET (data), FALSE);
185}
186
187
188static gboolean
189populate_text_entry (GtkTextView *view, const char *filename)
190{
191        FILE *fd;
192        char *filebuf;
193        GtkTextIter iter;
194        GtkTextBuffer *buffer;
195        int count;
196
197        g_return_val_if_fail (filename != NULL , FALSE);
198
199        fd = fopen (filename, "r");
200       
201        if (!fd) {
202                /* FIXME: Should never come here */
203                return FALSE;
204        }
205       
206        filebuf = g_malloc (1024);
207
208        buffer =  gtk_text_buffer_new (NULL);
209        gtk_text_buffer_get_start_iter (buffer, &iter);
210
211        while (!feof (fd) && !ferror (fd)) {
212                count = fread (filebuf, 1, sizeof (filebuf), fd);
213                gtk_text_buffer_insert (buffer, &iter, filebuf, count);
214        }
215        gtk_text_view_set_buffer (GTK_TEXT_VIEW (view),
216                                        GTK_TEXT_BUFFER (buffer));
217        fclose (fd);
218        g_free (filebuf);
219        return TRUE;
220}
221
222static gboolean
223display_license (CamelProvider *prov)
224{
225        GladeXML *xml;
226        GtkWidget *top_widget;
227        GtkTextView *text_entry;
228        GtkButton *button_yes, *button_no;
229        GtkCheckButton *check_button;
230        GtkResponseType response = GTK_RESPONSE_NONE;
231        GtkLabel *top_label;
232        char *label_text, *dialog_title;
233        gboolean status;
234       
235        xml = glade_xml_new (EVOLUTION_GLADEDIR "/mail-dialogs.glade", "lic_dialog", NULL);
236       
237        top_widget = glade_xml_get_widget (xml, "lic_dialog");
238        text_entry = GTK_TEXT_VIEW (glade_xml_get_widget (xml, "textview1"));
239        if (!(status = populate_text_entry (GTK_TEXT_VIEW (text_entry), prov->license_file)))
240                goto failed;
241       
242        gtk_text_view_set_editable (GTK_TEXT_VIEW (text_entry), FALSE);
243       
244        button_yes = GTK_BUTTON (glade_xml_get_widget (xml, "lic_yes_button"));
245        gtk_widget_set_sensitive (GTK_WIDGET (button_yes), FALSE);
246       
247        button_no = GTK_BUTTON (glade_xml_get_widget (xml, "lic_no_button"));
248       
249        check_button = GTK_CHECK_BUTTON (glade_xml_get_widget (xml, "lic_checkbutton"));
250       
251        top_label = GTK_LABEL (glade_xml_get_widget (xml, "lic_top_label"));
252       
253        label_text = g_strdup_printf (_("\nPlease read carefully the license agreement\n"
254                                        "for %s displayed below\n"
255                                        "and tick the check box for accepting it\n"), prov->license);
256       
257        gtk_label_set_label (top_label, label_text);
258       
259        dialog_title = g_strdup_printf (_("%s License Agreement"), prov->license);
260       
261        gtk_window_set_title (GTK_WINDOW (top_widget), dialog_title);
262       
263        g_signal_connect (check_button, "toggled", G_CALLBACK (check_button_state), button_yes);
264       
265        response = gtk_dialog_run (GTK_DIALOG (top_widget));
266       
267        g_free (label_text);
268        g_free (dialog_title);
269       
270 failed:
271        gtk_widget_destroy (top_widget);
272        g_object_unref (xml);
273       
274        return (response == GTK_RESPONSE_ACCEPT);
275}
276
277static gboolean
278service_complete (MailAccountGuiService *service, GHashTable *extra_config, GtkWidget **incomplete)
279{
280        const CamelProvider *prov = service->provider;
281        GtkWidget *path;
282        const char *text;
283       
284        if (!prov)
285                return TRUE;
286       
287        /* transports don't have a path */
288        if (service->path)
289                path = GTK_WIDGET (service->path);
290        else
291                path = NULL;
292       
293        if (CAMEL_PROVIDER_NEEDS (prov, CAMEL_URL_PART_HOST)) {
294                text = gtk_entry_get_text (service->hostname);
295                if (!text || !*text) {
296                        if (incomplete)
297                                *incomplete = get_focused_widget (GTK_WIDGET (service->hostname),
298                                                                  GTK_WIDGET (service->username),
299                                                                  path,
300                                                                  NULL);
301                        return FALSE;
302                }
303        }
304       
305        if (CAMEL_PROVIDER_NEEDS (prov, CAMEL_URL_PART_USER)) {
306                text = gtk_entry_get_text (service->username);
307                if (!text || !*text) {
308                        if (incomplete)
309                                *incomplete = get_focused_widget (GTK_WIDGET (service->username),
310                                                                  GTK_WIDGET (service->hostname),
311                                                                  path,
312                                                                  NULL);
313                        return FALSE;
314                }
315        }
316       
317        if (CAMEL_PROVIDER_NEEDS (prov, CAMEL_URL_PART_PATH)) {
318                if (!path) {
319                        d(printf ("aagh, transports aren't supposed to have paths.\n"));
320                        return TRUE;
321                }
322               
323                text = gtk_entry_get_text (service->path);
324                if (!text || !*text) {
325                        if (incomplete)
326                                *incomplete = get_focused_widget (GTK_WIDGET (service->path),
327                                                                  GTK_WIDGET (service->hostname),
328                                                                  GTK_WIDGET (service->username),
329                                                                  NULL);
330                        return FALSE;
331                }
332        }
333       
334        return TRUE;
335}
336
337static gboolean
338mail_account_gui_check_for_license (CamelProvider *prov)
339{
340        GConfClient *gconf;
341        gboolean accepted = TRUE, status;
342        GSList * providers_list, *l, *n;
343        char *provider;
344
345        if (prov->flags & CAMEL_PROVIDER_HAS_LICENSE) {
346                gconf = mail_config_get_gconf_client ();
347               
348                providers_list = gconf_client_get_list (gconf, "/apps/evolution/mail/licenses", GCONF_VALUE_STRING, NULL);
349               
350                for (l = providers_list, accepted = FALSE; l && !accepted; l = g_slist_next (l))
351                        accepted = (strcmp ((char *)l->data, prov->protocol) == 0);
352                if (!accepted) {
353                        /* Since the license is not yet accepted, pop-up a
354                         * dialog to display the license agreement and check
355                         * if the user accepts it
356                         */
357
358                        if ((accepted = display_license (prov)) == TRUE) {
359                                provider = g_strdup (prov->protocol);
360                                providers_list = g_slist_append (providers_list,
361                                                 provider);
362                                status = gconf_client_set_list (gconf,
363                                                "/apps/evolution/mail/licenses",
364                                                GCONF_VALUE_STRING,
365                                                 providers_list, NULL);
366                        }
367                }
368                l = providers_list;
369                while (l) {
370                        n = g_slist_next (l);
371                        g_free (l->data);
372                        g_slist_free_1 (l);
373                        l = n;
374                }
375        }
376        return accepted;
377}
378
379gboolean
380mail_account_gui_source_complete (MailAccountGui *gui, GtkWidget **incomplete)
381{
382        return service_complete (&gui->source, gui->extra_config, incomplete);
383}
384
385void
386mail_account_gui_auto_detect_extra_conf (MailAccountGui *gui)
387{
388        MailAccountGuiService *service = &gui->source;
389        CamelProvider *prov = service->provider;
390        GHashTable *auto_detected;
391        GtkWidget *path;
392        CamelURL *url;
393        char *text;
394        const char *tmp;
395
396        if (!prov)
397                return;
398       
399        /* transports don't have a path */
400        if (service->path)
401                path = GTK_WIDGET (service->path);
402        else
403                path = NULL;
404       
405        url = g_new0 (CamelURL, 1);
406        camel_url_set_protocol (url, prov->protocol);
407       
408        if (CAMEL_PROVIDER_ALLOWS (prov, CAMEL_URL_PART_HOST)) {
409                text = g_strdup (gtk_entry_get_text (service->hostname));
410                if (*text) {
411                        char *port;
412                       
413                        port = strchr (text, ':');
414                        if (port) {
415                                *port++ = '\0';
416                                camel_url_set_port (url, atoi (port));
417                        }
418                       
419                        camel_url_set_host (url, text);
420                }
421                g_free (text);
422        }
423       
424        if (CAMEL_PROVIDER_ALLOWS (prov, CAMEL_URL_PART_USER)) {
425                text = g_strdup (gtk_entry_get_text (service->username));
426                g_strstrip (text);
427                camel_url_set_user (url, text);
428                g_free (text);
429        }
430       
431        if (path && CAMEL_PROVIDER_ALLOWS (prov, CAMEL_URL_PART_PATH)) {
432                tmp = gtk_entry_get_text (service->path);
433                if (tmp && *tmp)
434                        camel_url_set_path (url, tmp);
435        }
436       
437        camel_provider_auto_detect (prov, url, &auto_detected, NULL);
438        camel_url_free (url);
439       
440        if (auto_detected) {
441                CamelProviderConfEntry *entries;
442                GtkToggleButton *toggle;
443                GtkSpinButton *spin;
444                GtkEntry *entry;
445                char *value;
446                int i;
447               
448                entries = service->provider->extra_conf;
449               
450                for (i = 0; entries[i].type != CAMEL_PROVIDER_CONF_END; i++) {
451                        GtkWidget *enable_widget = NULL;
452
453                        if (!entries[i].name)
454                                continue;
455                       
456                        value = g_hash_table_lookup (auto_detected, entries[i].name);
457                        if (!value)
458                                continue;
459                       
460                        switch (entries[i].type) {
461                        case CAMEL_PROVIDER_CONF_CHECKBOX:
462                                toggle = g_hash_table_lookup (gui->extra_config, entries[i].name);
463                                gtk_toggle_button_set_active (toggle, atoi (value));
464                                enable_widget = (GtkWidget *)toggle;
465                                break;
466                               
467                        case CAMEL_PROVIDER_CONF_ENTRY:
468                                entry = g_hash_table_lookup (gui->extra_config, entries[i].name);
469                                if (value)
470                                        gtk_entry_set_text (entry, value);
471                                enable_widget = (GtkWidget *)entry;
472                                break;
473                               
474                        case CAMEL_PROVIDER_CONF_CHECKSPIN:
475                        {
476                                gboolean enable;
477                                double val;
478                                char *name;
479                               
480                                toggle = g_hash_table_lookup (gui->extra_config, entries[i].name);
481                                name = g_strdup_printf ("%s_value", entries[i].name);
482                                spin = g_hash_table_lookup (gui->extra_config, name);
483                                g_free (name);
484                               
485                                enable = *value++ == 'y';
486                                gtk_toggle_button_set_active (toggle, enable);
487                                g_assert (*value == ':');
488                                val = strtod (++value, NULL);
489                                gtk_spin_button_set_value (spin, val);
490                                enable_widget = (GtkWidget *)spin;
491                        }
492                        break;
493                        default:
494                                break;
495                        }
496
497                        if (enable_widget)
498                                gtk_widget_set_sensitive(enable_widget, e_account_writable_option(gui->account, prov->protocol, entries[i].name));
499
500                }
501               
502                g_hash_table_foreach (auto_detected, auto_detected_foreach, NULL);
503                g_hash_table_destroy (auto_detected);
504        }
505}
506
507gboolean
508mail_account_gui_transport_complete (MailAccountGui *gui, GtkWidget **incomplete)
509{
510        if (!gui->transport.provider) {
511                if (incomplete)
512                        *incomplete = GTK_WIDGET (gui->transport.type);
513                return FALSE;
514        }
515
516        /* If it's both source and transport, there's nothing extra to
517         * configure on the transport page.
518         */
519        if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (gui->transport.provider)) {
520                if (gui->transport.provider == gui->source.provider)
521                        return TRUE;
522                if (incomplete)
523                        *incomplete = GTK_WIDGET (gui->transport.type);
524                return FALSE;
525        }
526       
527        if (!service_complete (&gui->transport, NULL, incomplete))
528                return FALSE;
529       
530        /* FIXME? */
531        if (gtk_toggle_button_get_active (gui->transport.needs_auth) &&
532            CAMEL_PROVIDER_ALLOWS (gui->transport.provider, CAMEL_URL_PART_USER)) {
533                const char *text = gtk_entry_get_text (gui->transport.username);
534               
535                if (!text || !*text) {
536                        if (incomplete)
537                                *incomplete = get_focused_widget (GTK_WIDGET (gui->transport.username),
538                                                                  GTK_WIDGET (gui->transport.hostname),
539                                                                  NULL);
540                        return FALSE;
541                }
542        }
543       
544        return TRUE;
545}
546
547gboolean
548mail_account_gui_management_complete (MailAccountGui *gui, GtkWidget **incomplete)
549{
550        const char *text;
551       
552        text = gtk_entry_get_text (gui->account_name);
553        if (text && *text)
554                return TRUE;
555       
556        if (incomplete)
557                *incomplete = GTK_WIDGET (gui->account_name);
558       
559        return FALSE;
560}
561
562
563static void
564service_authtype_changed (GtkWidget *widget, gpointer user_data)
565{
566        MailAccountGuiService *service = user_data;
567        CamelServiceAuthType *authtype;
568       
569        service->authitem = widget;
570        authtype = g_object_get_data ((GObject *) widget, "authtype");
571       
572        gtk_widget_set_sensitive (GTK_WIDGET (service->remember), authtype->need_password);
573}
574
575static void
576build_auth_menu (MailAccountGuiService *service, GList *all_authtypes,
577                 GList *supported_authtypes, gboolean check_supported)
578{
579        GtkWidget *menu, *item, *first = NULL;
580        CamelServiceAuthType *current, *authtype, *sauthtype;
581        int history = 0, i;
582        GList *l, *s;
583       
584        if (service->authitem)
585                current = g_object_get_data ((GObject *) service->authitem, "authtype");
586        else
587                current = NULL;
588       
589        service->authitem = NULL;
590       
591        menu = gtk_menu_new ();
592       
593        for (l = all_authtypes, i = 0; l; l = l->next, i++) {
594                authtype = l->data;
595               
596                item = gtk_menu_item_new_with_label (authtype->name);
597                for (s = supported_authtypes; s; s = s->next) {
598                        sauthtype = s->data;
599                        if (!strcmp (authtype->name, sauthtype->name))
600                                break;
601                }
602               
603                if (check_supported && !s) {
604                        gtk_widget_set_sensitive (item, FALSE);
605                } else if (current && !strcmp (authtype->name, current->name)) {
606                        first = item;
607                        history = i;
608                } else if (!first) {
609                        first = item;
610                        history = i;
611                }
612               
613                g_object_set_data ((GObject *) item, "authtype", authtype);
614                g_signal_connect (item, "activate", G_CALLBACK (service_authtype_changed), service);
615               
616                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
617               
618                gtk_widget_show (item);
619        }
620       
621        gtk_option_menu_remove_menu (service->authtype);
622        gtk_option_menu_set_menu (service->authtype, menu);
623       
624        if (first) {
625                gtk_option_menu_set_history (service->authtype, history);
626                g_signal_emit_by_name (first, "activate");
627        }
628}
629
630static void
631transport_provider_set_available (MailAccountGui *gui, CamelProvider *provider,
632                                  gboolean available)
633{
634        GtkWidget *menuitem;
635       
636        menuitem = g_object_get_data ((GObject *) gui->transport.type, provider->protocol);
637        g_return_if_fail (menuitem != NULL);
638       
639        gtk_widget_set_sensitive (menuitem, available);
640       
641        if (available) {
642                gpointer number = g_object_get_data ((GObject *) menuitem, "number");
643               
644                g_signal_emit_by_name (menuitem, "activate");
645                gtk_option_menu_set_history (gui->transport.type, GPOINTER_TO_UINT (number));
646        }
647}
648
649static void
650source_type_changed (GtkWidget *widget, gpointer user_data)
651{
652        MailAccountGui *gui = user_data;
653        GtkWidget *file_entry, *label, *frame, *dwidget = NULL;
654        CamelProvider *provider;
655        gboolean writeable;
656        gboolean license_accepted = TRUE;
657       
658        provider = g_object_get_data ((GObject *) widget, "provider");
659       
660        /* If the previously-selected provider has a linked transport,
661         * disable it.
662         */
663        if (gui->source.provider &&
664            CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (gui->source.provider))
665                transport_provider_set_available (gui, gui->source.provider, FALSE);
666       
667        gui->source.provider = provider;
668       
669        if (gui->source.provider) {
670                writeable = e_account_writable_option (gui->account, gui->source.provider->protocol, "auth");
671                gtk_widget_set_sensitive ((GtkWidget *) gui->source.authtype, writeable);
672                gtk_widget_set_sensitive ((GtkWidget *) gui->source.check_supported, writeable);
673               
674                writeable = e_account_writable_option (gui->account, gui->source.provider->protocol, "use_ssl");
675                gtk_widget_set_sensitive ((GtkWidget *) gui->source.use_ssl, writeable);
676               
677                writeable = e_account_writable (gui->account, E_ACCOUNT_SOURCE_SAVE_PASSWD);
678                gtk_widget_set_sensitive ((GtkWidget *) gui->source.remember, writeable);
679        }
680       
681        if (provider)
682                gtk_label_set_text (gui->source.description, provider->description);
683        else
684                gtk_label_set_text (gui->source.description, "");
685       
686        if (gui->source.provider)       
687                license_accepted = mail_account_gui_check_for_license (gui->source.provider);
688
689        frame = glade_xml_get_widget (gui->xml, "source_frame");
690        if (provider && license_accepted) {
691                gtk_widget_show (frame);
692               
693                /* hostname */
694                label = glade_xml_get_widget (gui->xml, "source_host_label");
695               
696                if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_HOST)) {
697                        dwidget = GTK_WIDGET (gui->source.hostname);
698                        gtk_widget_show (GTK_WIDGET (gui->source.hostname));
699                        gtk_widget_show (label);
700                } else {
701                        gtk_widget_hide (GTK_WIDGET (gui->source.hostname));
702                        gtk_widget_hide (label);
703                }
704               
705                /* username */
706                label = glade_xml_get_widget (gui->xml, "source_user_label");
707               
708                if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_USER)) {
709                        if (!dwidget)
710                                dwidget = GTK_WIDGET (gui->source.username);
711                        gtk_widget_show (GTK_WIDGET (gui->source.username));
712                        gtk_widget_show (label);
713                } else {
714                        gtk_widget_hide (GTK_WIDGET (gui->source.username));
715                        gtk_widget_hide (label);
716                }
717               
718                /* path */
719                label = glade_xml_get_widget (gui->xml, "source_path_label");
720                file_entry = glade_xml_get_widget (gui->xml, "source_path_entry");
721               
722                if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_PATH)) {
723                        if (!dwidget)
724                                dwidget = GTK_WIDGET (gui->source.path);
725                       
726                        gtk_widget_show (GTK_WIDGET (file_entry));
727                        gtk_widget_show (label);
728                } else {
729                        gtk_entry_set_text (gui->source.path, "");
730                        gtk_widget_hide (GTK_WIDGET (file_entry));
731                        gtk_widget_hide (label);
732                }
733               
734                /* ssl */
735#ifdef HAVE_SSL
736                gtk_widget_hide (gui->source.no_ssl);
737                if (provider && provider->flags & CAMEL_PROVIDER_SUPPORTS_SSL) {
738                        gtk_widget_show (gui->source.ssl_frame);
739                        gtk_widget_show (gui->source.ssl_hbox);
740                } else {
741                        gtk_widget_hide (gui->source.ssl_frame);
742                        gtk_widget_hide (gui->source.ssl_hbox);
743                }
744#else
745                gtk_widget_hide (gui->source.ssl_hbox);
746                gtk_widget_show (gui->source.no_ssl);
747#endif
748               
749                /* auth */
750                frame = glade_xml_get_widget (gui->xml, "source_auth_frame");
751                if (provider && CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_AUTH)) {
752                        build_auth_menu (&gui->source, provider->authtypes, NULL, FALSE);
753                        gtk_widget_show (frame);
754                } else
755                        gtk_widget_hide (frame);
756        } else {
757                gtk_widget_hide (frame);
758                frame = glade_xml_get_widget (gui->xml, "source_auth_frame");
759                gtk_widget_hide (frame);
760        }
761       
762        g_signal_emit_by_name (gui->source.username, "changed");
763       
764        if (dwidget)
765                gtk_widget_grab_focus (dwidget);
766       
767        mail_account_gui_build_extra_conf (gui, gui && gui->account && gui->account->source ? gui->account->source->url : NULL);
768       
769        if (provider && CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider))
770                transport_provider_set_available (gui, provider, TRUE);
771}
772
773
774static void
775transport_needs_auth_toggled (GtkToggleButton *toggle, gpointer data)
776{
777        MailAccountGui *gui = data;
778        gboolean need = gtk_toggle_button_get_active (toggle);
779        GtkWidget *widget;
780       
781        widget = glade_xml_get_widget (gui->xml, "transport_auth_frame");
782        gtk_widget_set_sensitive (widget, need);
783        if (need)
784                service_changed (NULL, &gui->transport);
785}
786
787static void
788transport_type_changed (GtkWidget *widget, gpointer user_data)
789{
790        MailAccountGui *gui = user_data;
791        CamelProvider *provider;
792        GtkWidget *label, *frame;
793        gboolean writeable;
794       
795        provider = g_object_get_data ((GObject *) widget, "provider");
796        gui->transport.provider = provider;
797       
798        if (gui->transport.provider) {
799                writeable = e_account_writable_option (gui->account, gui->transport.provider->protocol, "auth");
800                gtk_widget_set_sensitive ((GtkWidget *) gui->transport.authtype, writeable);
801                gtk_widget_set_sensitive ((GtkWidget *) gui->transport.check_supported, writeable);
802               
803                writeable = e_account_writable_option (gui->account, gui->transport.provider->protocol, "use_ssl");
804                gtk_widget_set_sensitive ((GtkWidget *) gui->transport.use_ssl, writeable);
805               
806                writeable = e_account_writable (gui->account, E_ACCOUNT_TRANSPORT_SAVE_PASSWD);
807                gtk_widget_set_sensitive ((GtkWidget *) gui->transport.remember, writeable);
808        }
809       
810        /* description */
811        gtk_label_set_text (gui->transport.description, provider->description);
812       
813        frame = glade_xml_get_widget (gui->xml, "transport_frame");
814        if (!CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider) &&
815            (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_HOST) ||
816             (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_AUTH) &&
817              !CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_AUTH)))) {
818                gtk_widget_show (frame);
819               
820                label = glade_xml_get_widget (gui->xml, "transport_host_label");
821                if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_HOST)) {
822                        gtk_widget_show (GTK_WIDGET (gui->transport.hostname));
823                        gtk_widget_show (label);
824                } else {
825                        gtk_widget_hide (GTK_WIDGET (gui->transport.hostname));
826                        gtk_widget_hide (label);
827                }
828               
829                /* ssl */
830#ifdef HAVE_SSL
831                gtk_widget_hide (gui->transport.no_ssl);
832                if (provider && provider->flags & CAMEL_PROVIDER_SUPPORTS_SSL) {
833                        gtk_widget_show (gui->transport.ssl_frame);
834                        gtk_widget_show (gui->transport.ssl_hbox);
835                } else {
836                        gtk_widget_hide (gui->transport.ssl_frame);
837                        gtk_widget_hide (gui->transport.ssl_hbox);
838                }
839#else
840                gtk_widget_hide (gui->transport.ssl_hbox);
841                gtk_widget_show (gui->transport.no_ssl);
842#endif
843               
844                /* auth */
845                if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_AUTH) &&
846                    !CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_AUTH))
847                        gtk_widget_show (GTK_WIDGET (gui->transport.needs_auth));
848                else
849                        gtk_widget_hide (GTK_WIDGET (gui->transport.needs_auth));
850        } else
851                gtk_widget_hide (frame);
852       
853        frame = glade_xml_get_widget (gui->xml, "transport_auth_frame");
854        if (!CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider) &&
855            CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_AUTH)) {
856                gtk_widget_show (frame);
857               
858                label = glade_xml_get_widget (gui->xml, "transport_user_label");
859                if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_USER)) {
860                        gtk_widget_show (GTK_WIDGET (gui->transport.username));
861                        gtk_widget_show (label);
862                } else {
863                        gtk_widget_hide (GTK_WIDGET (gui->transport.username));
864                        gtk_widget_hide (label);
865                }
866               
867                build_auth_menu (&gui->transport, provider->authtypes, NULL, FALSE);
868                transport_needs_auth_toggled (gui->transport.needs_auth, gui);
869        } else
870                gtk_widget_hide (frame);
871       
872        g_signal_emit_by_name (gui->transport.hostname, "changed");
873}
874
875static void
876service_changed (GtkEntry *entry, gpointer user_data)
877{
878        MailAccountGuiService *service = user_data;
879       
880        gtk_widget_set_sensitive (GTK_WIDGET (service->check_supported),
881                                  service_complete (service, NULL, NULL));
882}
883
884/* the fun of async ... */
885struct _service_check_data {
886        MailAccountGuiService *gsvc;
887        GtkWidget *dialog;
888        GtkWidget *window;
889
890        int id;
891        gulong destroy_id;
892        int destroyed:1;
893};
894
895static void
896service_check_done(const char *url, CamelProviderType type, GList *types, void *data)
897{
898        struct _service_check_data *sd = data;
899
900        if (!sd->destroyed) {
901                gtk_widget_set_sensitive(sd->window, TRUE);
902                build_auth_menu(sd->gsvc, sd->gsvc->provider->authtypes, types, TRUE);
903        }
904
905        if (sd->dialog) {
906                gtk_widget_destroy(sd->dialog);
907                sd->dialog = NULL;
908        }
909
910        if (sd->destroy_id)
911                g_signal_handler_disconnect(sd->window, sd->destroy_id);
912
913        g_free(sd);
914}
915
916static void
917service_check_response(GtkDialog *d, int button, struct _service_check_data *sd)
918{
919        mail_msg_cancel(sd->id);
920
921        gtk_widget_destroy(sd->dialog);
922        sd->dialog = NULL;
923}
924
925static void
926service_check_destroy(GtkWindow *w, struct _service_check_data *sd)
927{
928        sd->destroy_id = 0;
929        sd->destroyed = TRUE;
930        mail_msg_cancel(sd->id);
931}
932
933static void
934service_check_supported (GtkButton *button, gpointer user_data)
935{
936        MailAccountGuiService *gsvc = user_data;
937        EAccountService *service;
938        GtkWidget *dialog;
939        GtkWidget *authitem;
940        struct _service_check_data *sd;
941
942        sd = g_malloc0(sizeof(*sd));
943        sd->id = -1;
944        sd->gsvc = gsvc;
945
946        /* This is sort of a hack, when checking for supported AUTH
947           types we don't want to use whatever authtype is selected
948           because it may not be available. */
949        service = g_malloc0(sizeof(*service));
950        authitem = gsvc->authitem;
951        gsvc->authitem = NULL;
952        save_service (gsvc, NULL, service);
953        gsvc->authitem = authitem;
954
955        sd->window = gtk_widget_get_toplevel((GtkWidget *)button);
956        sd->destroy_id = g_signal_connect(sd->window, "destroy", G_CALLBACK(service_check_destroy), sd);
957
958        gtk_widget_set_sensitive(sd->window, FALSE);
959        dialog = gtk_dialog_new_with_buttons(_("Connecting to server..."),
960                                             (GtkWindow *)sd->window,
961                                             GTK_DIALOG_DESTROY_WITH_PARENT,
962                                             GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
963                                             NULL);
964        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
965                           gtk_label_new(_("Connecting to server...")),
966                           TRUE, TRUE, 10);
967        g_signal_connect(dialog, "response", G_CALLBACK(service_check_response), sd);
968        gtk_widget_show_all(dialog);
969
970        sd->dialog = dialog;
971        sd->id = mail_check_service(service->url, gsvc->provider_type, service_check_done, sd);
972
973        g_free (service->url);
974        g_free (service);
975}
976
977
978static void
979toggle_sensitivity (GtkToggleButton *toggle, GtkWidget *widget)
980{
981        gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (toggle));
982}
983
984/* Returns true if the widget is enabled */
985static gboolean
986setup_toggle (GtkWidget *widget, const char *depname, MailAccountGui *gui)
987{
988        GtkToggleButton *toggle;
989       
990        if (!strcmp (depname, "UNIMPLEMENTED")) {
991                gtk_widget_set_sensitive (widget, FALSE);
992                return FALSE;
993        }
994       
995        toggle = g_hash_table_lookup (gui->extra_config, depname);
996        g_signal_connect (toggle, "toggled", G_CALLBACK (toggle_sensitivity), widget);
997        toggle_sensitivity (toggle, widget);
998
999        return gtk_toggle_button_get_active(toggle);
1000}
1001
1002void
1003mail_account_gui_build_extra_conf (MailAccountGui *gui, const char *url_string)
1004{
1005        CamelURL *url;
1006        GtkWidget *mailcheck_frame, *mailcheck_hbox;
1007        GtkWidget *hostname_label, *username_label, *path_label;
1008        GtkWidget *hostname, *username, *path;
1009        GtkTable *main_table, *cur_table;
1010        CamelProviderConfEntry *entries;
1011        GList *child, *next;
1012        char *name;
1013        int i, rows;
1014       
1015        if (url_string)
1016                url = camel_url_new (url_string, NULL);
1017        else
1018                url = NULL;
1019       
1020        hostname_label = glade_xml_get_widget (gui->xml, "source_host_label");
1021        gtk_label_set_text_with_mnemonic (GTK_LABEL (hostname_label), _("_Host:"));
1022        hostname = glade_xml_get_widget (gui->xml, "source_host");
1023       
1024        username_label = glade_xml_get_widget (gui->xml, "source_user_label");
1025        gtk_label_set_text_with_mnemonic (GTK_LABEL (username_label), _("User_name:"));
1026        username = glade_xml_get_widget (gui->xml, "source_user");
1027       
1028        path_label = glade_xml_get_widget (gui->xml, "source_path_label");
1029        gtk_label_set_text_with_mnemonic (GTK_LABEL (path_label), _("_Path:"));
1030        path = glade_xml_get_widget (gui->xml, "source_path");
1031       
1032        /* Remove the contents of the extra_table except for the
1033         * mailcheck_frame.
1034         */
1035        main_table = (GtkTable *) glade_xml_get_widget (gui->xml, "extra_table");
1036        gtk_container_set_border_width ((GtkContainer *) main_table, 12);
1037        gtk_table_set_row_spacings (main_table, 6);
1038        gtk_table_set_col_spacings (main_table, 8);
1039        mailcheck_frame = glade_xml_get_widget (gui->xml, "extra_mailcheck_frame");
1040        child = gtk_container_get_children (GTK_CONTAINER (main_table));
1041        while (child != NULL) {
1042                next = child->next;
1043                if (child->data != (gpointer) mailcheck_frame)
1044                        gtk_container_remove (GTK_CONTAINER (main_table), child->data);
1045                g_list_free_1 (child);
1046                child = next;
1047        }
1048       
1049        gtk_table_resize (main_table, 1, 2);
1050       
1051        /* Remove any additional mailcheck items. */
1052        cur_table = (GtkTable *) glade_xml_get_widget (gui->xml, "extra_mailcheck_table");
1053        gtk_container_set_border_width ((GtkContainer *) cur_table, 12);
1054        gtk_table_set_row_spacings (cur_table, 6);
1055        gtk_table_set_col_spacings (cur_table, 8);
1056        mailcheck_hbox = glade_xml_get_widget (gui->xml, "extra_mailcheck_hbox");
1057        child = gtk_container_get_children (GTK_CONTAINER (cur_table));
1058        while (child != NULL) {
1059                next = child->next;
1060                if (child->data != (gpointer) mailcheck_hbox)
1061                        gtk_container_remove (GTK_CONTAINER (cur_table), child->data);
1062                g_list_free_1 (child);
1063                child = next;
1064        }
1065       
1066        gtk_table_resize (cur_table, 1, 2);
1067
1068        if (!gui->source.provider) {
1069                gtk_widget_set_sensitive (GTK_WIDGET (main_table), FALSE);
1070                if (url)
1071                        camel_url_free (url);
1072                return;
1073        } else
1074                gtk_widget_set_sensitive(GTK_WIDGET(main_table), e_account_writable(gui->account, E_ACCOUNT_SOURCE_URL));
1075       
1076        /* Set up our hash table. */
1077        if (gui->extra_config)
1078                g_hash_table_destroy (gui->extra_config);
1079        gui->extra_config = g_hash_table_new (g_str_hash, g_str_equal);
1080       
1081        entries = gui->source.provider->extra_conf;
1082        if (!entries)
1083                goto done;
1084       
1085        cur_table = main_table;
1086        rows = main_table->nrows;
1087        for (i = 0; ; i++) {
1088                GtkWidget *enable_widget = NULL;
1089                int enabled = TRUE;
1090               
1091                switch (entries[i].type) {
1092                case CAMEL_PROVIDER_CONF_SECTION_START:
1093                {
1094                        GtkWidget *frame, *label;
1095                        char *markup;
1096                       
1097                        if (entries[i].name && !strcmp (entries[i].name, "mailcheck")) {
1098                                cur_table = (GtkTable *) glade_xml_get_widget (gui->xml, "extra_mailcheck_table");
1099                                rows = cur_table->nrows;
1100                                break;
1101                        }
1102                       
1103                        markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", entries[i].text);
1104                        label = gtk_label_new (NULL);
1105                        gtk_label_set_markup ((GtkLabel *) label, markup);
1106                        gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_LEFT);
1107                        gtk_label_set_use_markup ((GtkLabel *) label, TRUE);
1108                        gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
1109                        gtk_widget_show (label);
1110                        g_free (markup);
1111                       
1112                        cur_table = (GtkTable *) gtk_table_new (0, 2, FALSE);
1113                        gtk_container_set_border_width ((GtkContainer *) cur_table, 12);
1114                        gtk_table_set_row_spacings (cur_table, 6);
1115                        gtk_table_set_col_spacings (cur_table, 8);
1116                        gtk_widget_show ((GtkWidget *) cur_table);
1117                       
1118                        frame = gtk_vbox_new (FALSE, 0);
1119                        gtk_box_pack_start ((GtkBox *) frame, label, FALSE, FALSE, 0);
1120                        gtk_box_pack_start ((GtkBox *) frame, (GtkWidget *) cur_table, FALSE, FALSE, 0);
1121                        gtk_widget_show (frame);
1122                       
1123                        gtk_table_attach (main_table, frame, 0, 2,
1124                                          rows, rows + 1,
1125                                          GTK_EXPAND | GTK_FILL, 0, 0, 0);
1126                       
1127                        rows = 0;
1128                       
1129                        break;
1130                }
1131                case CAMEL_PROVIDER_CONF_SECTION_END:
1132                        cur_table = main_table;
1133                        rows = main_table->nrows;
1134                        break;
1135                       
1136                case CAMEL_PROVIDER_CONF_LABEL:
1137                        if (entries[i].name && entries[i].text) {
1138                                GtkWidget *label;
1139                               
1140                                if (!strcmp (entries[i].name, "username")) {
1141                                        gtk_label_set_text_with_mnemonic (GTK_LABEL (username_label), entries[i].text);
1142                                        enable_widget = username_label;
1143                                } else if (!strcmp (entries[i].name, "hostname")) {
1144                                        gtk_label_set_text_with_mnemonic (GTK_LABEL (hostname_label), entries[i].text);
1145                                        enable_widget = hostname_label;
1146                                } else if (!strcmp (entries[i].name, "path")) {
1147                                        gtk_label_set_text_with_mnemonic (GTK_LABEL (path_label), entries[i].text);
1148                                        enable_widget = path_label;
1149                                } else {
1150                                        /* make a new label */
1151                                        label = gtk_label_new (entries[i].text);
1152                                        gtk_table_resize (cur_table, cur_table->nrows + 1, 2);
1153                                        gtk_table_attach (cur_table, label, 0, 2, rows, rows + 1,
1154                                                          GTK_EXPAND | GTK_FILL, 0, 0, 0);
1155                                        rows++;
1156                                        enable_widget = label;
1157                                }
1158                        }
1159                        break;
1160                       
1161                case CAMEL_PROVIDER_CONF_CHECKBOX:
1162                {
1163                        GtkWidget *checkbox;
1164                        gboolean active;
1165                       
1166                        checkbox = gtk_check_button_new_with_label (entries[i].text);
1167                        if (url)
1168                                active = camel_url_get_param (url, entries[i].name) != NULL;
1169                        else
1170                                active = atoi (entries[i].value);
1171                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), active);
1172                       
1173                        gtk_table_attach (cur_table, checkbox, 0, 2, rows, rows + 1,
1174                                          GTK_EXPAND | GTK_FILL, 0, 0, 0);
1175                        rows++;
1176                        g_hash_table_insert (gui->extra_config, entries[i].name, checkbox);
1177                        if (entries[i].depname)
1178                                enabled = setup_toggle(checkbox, entries[i].depname, gui);
1179
1180                        enable_widget = checkbox;
1181                        break;
1182                }
1183               
1184                case CAMEL_PROVIDER_CONF_ENTRY:
1185                {
1186                        GtkWidget *label, *entry;
1187                        const char *text;
1188                       
1189                        if (!strcmp (entries[i].name, "username")) {
1190                                gtk_label_set_text_with_mnemonic (GTK_LABEL (username_label), entries[i].text);
1191                                label = username_label;
1192                                entry = username;
1193                        } else if (!strcmp (entries[i].name, "hostname")) {
1194                                gtk_label_set_text_with_mnemonic (GTK_LABEL (hostname_label), entries[i].text);
1195                                label = hostname_label;
1196                                entry = hostname;
1197                        } else if (!strcmp (entries[i].name, "path")) {
1198                                gtk_label_set_text_with_mnemonic (GTK_LABEL (path_label), entries[i].text);
1199                                label = path_label;
1200                                entry = path;
1201                        } else {
1202                                /* make a new text entry with label */
1203                                label = gtk_label_new (entries[i].text);
1204                                gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
1205                                entry = gtk_entry_new ();
1206                               
1207                                gtk_table_attach (cur_table, label, 0, 1, rows, rows + 1,
1208                                                  GTK_FILL, 0, 0, 0);
1209                                gtk_table_attach (cur_table, entry, 1, 2, rows, rows + 1,
1210                                                  GTK_EXPAND | GTK_FILL, 0, 0, 0);
1211                                rows++;
1212                        }
1213                       
1214                        if (url)
1215                                text = camel_url_get_param (url, entries[i].name);
1216                        else
1217                                text = entries[i].value;
1218                       
1219                        if (text)
1220                                gtk_entry_set_text (GTK_ENTRY (entry), text);
1221                       
1222                        if (entries[i].depname) {
1223                                setup_toggle (entry, entries[i].depname, gui);
1224                                enabled = setup_toggle (label, entries[i].depname, gui);
1225                        }
1226                       
1227                        g_hash_table_insert (gui->extra_config, entries[i].name, entry);
1228                       
1229                        enable_widget = entry;
1230                        break;
1231                }
1232               
1233                case CAMEL_PROVIDER_CONF_CHECKSPIN:
1234                {
1235                        GtkWidget *hbox, *checkbox, *spin, *label;
1236                        GtkObject *adj;
1237                        char *data, *pre, *post, *p;
1238                        double min, def, max;
1239                        gboolean enable;
1240                       
1241                        /* FIXME: this is pretty fucked... */
1242                        data = entries[i].text;
1243                        p = strstr (data, "%s");
1244                        g_return_if_fail (p != NULL);
1245                       
1246                        pre = g_strndup (data, p - data);
1247                        post = p + 2;
1248                       
1249                        data = entries[i].value;
1250                        enable = *data++ == 'y';
1251                        g_return_if_fail (*data == ':');
1252                        min = strtod (data + 1, &data);
1253                        g_return_if_fail (*data == ':');
1254                        def = strtod (data + 1, &data);
1255                        g_return_if_fail (*data == ':');
1256                        max = strtod (data + 1, NULL);
1257                       
1258                        if (url) {
1259                                const char *val;
1260                               
1261                                val = camel_url_get_param (url, entries[i].name);
1262                                if (!val)
1263                                        enable = FALSE;
1264                                else {
1265                                        enable = TRUE;
1266                                        def = atof (val);
1267                                }
1268                        }
1269                       
1270                        hbox = gtk_hbox_new (FALSE, 0);
1271                        checkbox = gtk_check_button_new_with_label (pre);
1272                        g_free (pre);
1273                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), enable);
1274                        adj = gtk_adjustment_new (def, min, max, 1, 1, 1);
1275                        spin = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0);
1276                        label = gtk_label_new (post);
1277                       
1278                        gtk_box_pack_start (GTK_BOX (hbox), checkbox, FALSE, TRUE, 0);
1279                        gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, FALSE, 0);
1280                        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 4);
1281                       
1282                        gtk_table_attach (cur_table, hbox, 0, 2, rows, rows + 1,
1283                                          GTK_EXPAND | GTK_FILL, 0, 0, 0);
1284                        rows++;
1285                        g_hash_table_insert (gui->extra_config, entries[i].name, checkbox);
1286                        name = g_strdup_printf ("%s_value", entries[i].name);
1287                        g_hash_table_insert (gui->extra_config, name, spin);
1288                        if (entries[i].depname) {
1289                                setup_toggle (checkbox, entries[i].depname, gui);
1290                                setup_toggle (spin, entries[i].depname, gui);
1291                                enabled = setup_toggle (label, entries[i].depname, gui);
1292                        }
1293                       
1294                        enable_widget = hbox;
1295                        break;
1296                }
1297
1298                case CAMEL_PROVIDER_CONF_HIDDEN:
1299                        break;
1300
1301                case CAMEL_PROVIDER_CONF_END:
1302                        goto done;
1303                }
1304               
1305                if (enabled && enable_widget)
1306                        gtk_widget_set_sensitive(enable_widget, e_account_writable_option(gui->account, gui->source.provider->protocol, entries[i].name));
1307        }
1308       
1309 done:
1310        gtk_widget_show_all (GTK_WIDGET (main_table));
1311        if (url)
1312                camel_url_free (url);
1313}
1314
1315static void
1316extract_values (MailAccountGuiService *source, GHashTable *extra_config, CamelURL *url)
1317{
1318        CamelProviderConfEntry *entries;
1319        GtkToggleButton *toggle;
1320        GtkEntry *entry;
1321        GtkSpinButton *spin;
1322        char *name;
1323        int i;
1324       
1325        if (!source->provider || !source->provider->extra_conf)
1326                return;
1327        entries = source->provider->extra_conf;
1328       
1329        for (i = 0; ; i++) {
1330                if (entries[i].depname) {
1331                        toggle = g_hash_table_lookup (extra_config, entries[i].depname);
1332                        if (!toggle || !gtk_toggle_button_get_active (toggle))
1333                                continue;
1334                }
1335               
1336                switch (entries[i].type) {
1337                case CAMEL_PROVIDER_CONF_CHECKBOX:
1338                        toggle = g_hash_table_lookup (extra_config, entries[i].name);
1339                        if (gtk_toggle_button_get_active (toggle))
1340                                camel_url_set_param (url, entries[i].name, "");
1341                        break;
1342                       
1343                case CAMEL_PROVIDER_CONF_ENTRY:
1344                        if (strcmp (entries[i].name, "username") == 0
1345                            || strcmp (entries[i].name, "hostname") == 0
1346                            || strcmp (entries[i].name, "path") == 0) {
1347                                break;
1348                        }
1349                        entry = g_hash_table_lookup (extra_config, entries[i].name);
1350                        camel_url_set_param (url, entries[i].name, gtk_entry_get_text (entry));
1351                        break;
1352                       
1353                case CAMEL_PROVIDER_CONF_CHECKSPIN:
1354                        toggle = g_hash_table_lookup (extra_config, entries[i].name);
1355                        if (!gtk_toggle_button_get_active (toggle))
1356                                break;
1357                        name = g_strdup_printf ("%s_value", entries[i].name);
1358                        spin = g_hash_table_lookup (extra_config, name);
1359                        g_free (name);
1360                        name = g_strdup_printf ("%d", gtk_spin_button_get_value_as_int (spin));
1361                        camel_url_set_param (url, entries[i].name, name);
1362                        g_free (name);
1363                        break;
1364
1365                case CAMEL_PROVIDER_CONF_HIDDEN:
1366                        if (entries[i].value)
1367                                camel_url_set_param (url, entries[i].name, entries[i].value);
1368                        break;
1369
1370                case CAMEL_PROVIDER_CONF_END:
1371                        return;
1372                       
1373                default:
1374                        break;
1375                }
1376        }
1377}
1378
1379static void
1380folder_selected (EMFolderSelectionButton *button, gpointer user_data)
1381{
1382        char **folder_name = user_data;
1383       
1384        g_free (*folder_name);
1385        *folder_name = g_strdup(em_folder_selection_button_get_selection(button));
1386}
1387
1388static void
1389default_folders_clicked (GtkButton *button, gpointer user_data)
1390{
1391        MailAccountGui *gui = user_data;
1392       
1393        /* Drafts folder */
1394        g_free (gui->drafts_folder_uri);
1395        gui->drafts_folder_uri = g_strdup(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS));
1396        em_folder_selection_button_set_selection((EMFolderSelectionButton *)gui->drafts_folder_button, gui->drafts_folder_uri);
1397       
1398        /* Sent folder */
1399        g_free (gui->sent_folder_uri);
1400        gui->sent_folder_uri = g_strdup(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT));
1401        em_folder_selection_button_set_selection((EMFolderSelectionButton *)gui->sent_folder_button, gui->sent_folder_uri);
1402}
1403
1404GtkWidget *mail_account_gui_folder_selector_button_new (char *widget_name, char *string1, char *string2, int int1, int int2);
1405
1406GtkWidget *
1407mail_account_gui_folder_selector_button_new (char *widget_name,
1408                                             char *string1, char *string2,
1409                                             int int1, int int2)
1410{
1411        return (GtkWidget *)em_folder_selection_button_new(_("Select Folder"), NULL);
1412}
1413
1414static gboolean
1415setup_service (MailAccountGui *gui, MailAccountGuiService *gsvc, EAccountService *service)
1416{
1417        CamelURL *url = camel_url_new (service->url, NULL);
1418        gboolean has_auth = FALSE;
1419       
1420        if (url == NULL || gsvc->provider == NULL)
1421                return FALSE;
1422       
1423        if (url->user && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_USER))
1424                gtk_entry_set_text (gsvc->username, url->user);
1425       
1426        if (url->host && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_HOST)) {
1427                char *hostname;
1428               
1429                if (url->port)
1430                        hostname = g_strdup_printf ("%s:%d", url->host, url->port);
1431                else
1432                        hostname = g_strdup (url->host);
1433               
1434                gtk_entry_set_text (gsvc->hostname, hostname);
1435                g_free (hostname);
1436        }
1437       
1438        if (url->path && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_PATH))
1439                gtk_entry_set_text (gsvc->path, url->path);
1440       
1441        if (gsvc->provider->flags & CAMEL_PROVIDER_SUPPORTS_SSL) {
1442                GList *children, *item;
1443                const char *use_ssl;
1444                int i;
1445               
1446                use_ssl = camel_url_get_param (url, "use_ssl");
1447                if (!use_ssl)
1448                        use_ssl = "never";
1449                else if (!*use_ssl)  /* old config code just used an empty string as the value */
1450                        use_ssl = "always";
1451               
1452                children = gtk_container_get_children(GTK_CONTAINER (gtk_option_menu_get_menu (gsvc->use_ssl)));
1453                for (item = children, i = 0; item; item = item->next, i++) {
1454                        if (!strcmp (use_ssl, ssl_options[i].value)) {
1455                                gtk_option_menu_set_history (gsvc->use_ssl, i);
1456                                g_signal_emit_by_name (item->data, "activate", gsvc);
1457                                break;
1458                        }
1459                }
1460        }
1461       
1462        if (url->authmech && CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_AUTH)) {
1463                GList *children, *item;
1464                CamelServiceAuthType *authtype;
1465                int i;
1466               
1467                children = gtk_container_get_children(GTK_CONTAINER (gtk_option_menu_get_menu (gsvc->authtype)));
1468                for (item = children, i = 0; item; item = item->next, i++) {
1469                        authtype = g_object_get_data ((GObject *) item->data, "authtype");
1470                        if (!authtype)
1471                                continue;
1472                        if (!strcmp (authtype->authproto, url->authmech)) {
1473                                gtk_option_menu_set_history (gsvc->authtype, i);
1474                                g_signal_emit_by_name (item->data, "activate");
1475                                break;
1476                        }
1477                }
1478                g_list_free (children);
1479               
1480                has_auth = TRUE;
1481        }
1482        camel_url_free (url);
1483       
1484        gtk_toggle_button_set_active (gsvc->remember, service->save_passwd);
1485
1486        gtk_widget_set_sensitive((GtkWidget *)gsvc->authtype, e_account_writable_option(gui->account, gsvc->provider->protocol, "auth"));
1487        gtk_widget_set_sensitive((GtkWidget *)gsvc->use_ssl, e_account_writable_option(gui->account, gsvc->provider->protocol, "use_ssl"));
1488       
1489        return has_auth;
1490}
1491
1492static gint
1493provider_compare (const CamelProvider *p1, const CamelProvider *p2)
1494{
1495        /* sort providers based on "location" (ie. local or remote) */
1496        if (p1->flags & CAMEL_PROVIDER_IS_REMOTE) {
1497                if (p2->flags & CAMEL_PROVIDER_IS_REMOTE)
1498                        return 0;
1499                return -1;
1500        } else {
1501                if (p2->flags & CAMEL_PROVIDER_IS_REMOTE)
1502                        return 1;
1503                return 0;
1504        }
1505}
1506
1507static void
1508ssl_option_activate (GtkWidget *widget, gpointer user_data)
1509{
1510        MailAccountGuiService *service = user_data;
1511       
1512        service->ssl_selected = widget;
1513}
1514
1515static void
1516construct_ssl_menu (MailAccountGuiService *service)
1517{
1518        GtkWidget *menu, *item = NULL;
1519        int i;
1520       
1521        menu = gtk_menu_new ();
1522       
1523        for (i = 0; i < num_ssl_options; i++) {
1524                item = gtk_menu_item_new_with_label (_(ssl_options[i].label));
1525                g_object_set_data ((GObject *) item, "use_ssl", ssl_options[i].value);
1526                g_signal_connect (item, "activate", G_CALLBACK (ssl_option_activate), service);
1527                gtk_widget_show (item);
1528                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1529        }
1530       
1531        gtk_option_menu_remove_menu (service->use_ssl);
1532        gtk_option_menu_set_menu (service->use_ssl, menu);
1533       
1534        gtk_option_menu_set_history (service->use_ssl, i - 1);
1535        g_signal_emit_by_name (item, "activate", service);
1536}
1537
1538static void
1539sig_activate (GtkWidget *item, MailAccountGui *gui)
1540{
1541        ESignature *sig;
1542       
1543        sig = g_object_get_data ((GObject *) item, "sig");
1544       
1545        gui->sig_uid = sig ? sig->uid : NULL;
1546}
1547
1548static void
1549signature_added (ESignatureList *signatures, ESignature *sig, MailAccountGui *gui)
1550{
1551        GtkWidget *menu, *item;
1552       
1553        menu = gtk_option_menu_get_menu (gui->sig_menu);
1554        if (sig->autogen)
1555                item = gtk_menu_item_new_with_label (_("Autogenerated"));
1556        else
1557                item = gtk_menu_item_new_with_label (sig->name);
1558        g_object_set_data ((GObject *) item, "sig", sig);
1559        g_signal_connect (item, "activate", G_CALLBACK (sig_activate), gui);
1560        gtk_widget_show (item);
1561       
1562        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1563       
1564        gtk_option_menu_set_history (gui->sig_menu, g_list_length (GTK_MENU_SHELL (menu)->children));
1565}
1566
1567static void
1568signature_removed (ESignatureList *signatures, ESignature *sig, MailAccountGui *gui)
1569{
1570        GtkWidget *menu;
1571        ESignature *cur;
1572        GList *items;
1573       
1574        if (gui->sig_uid == sig->uid)
1575                gui->sig_uid = NULL;
1576       
1577        menu = gtk_option_menu_get_menu (gui->sig_menu);
1578        items = GTK_MENU_SHELL (menu)->children;
1579        while (items != NULL) {
1580                cur = g_object_get_data (items->data, "sig");
1581                if (cur == sig) {
1582                        gtk_widget_destroy (items->data);
1583                        break;
1584                }
1585                items = items->next;
1586        }
1587}
1588
1589static void
1590menu_item_set_label (GtkMenuItem *item, const char *label)
1591{
1592        GtkWidget *widget;
1593       
1594        widget = gtk_bin_get_child ((GtkBin *) item);
1595        if (GTK_IS_LABEL (widget))
1596                gtk_label_set_text ((GtkLabel *) widget, label);
1597}
1598
1599static void
1600signature_changed (ESignatureList *signatures, ESignature *sig, MailAccountGui *gui)
1601{
1602        GtkWidget *menu;
1603        ESignature *cur;
1604        GList *items;
1605       
1606        menu = gtk_option_menu_get_menu (gui->sig_menu);
1607        items = GTK_MENU_SHELL (menu)->children;
1608        while (items != NULL) {
1609                cur = g_object_get_data (items->data, "sig");
1610                if (cur == sig) {
1611                        menu_item_set_label (items->data, sig->name);
1612                        break;
1613                }
1614                items = items->next;
1615        }
1616}
1617
1618static void
1619clear_menu (GtkWidget *menu)
1620{
1621        while (GTK_MENU_SHELL (menu)->children)
1622                gtk_container_remove (GTK_CONTAINER (menu), GTK_MENU_SHELL (menu)->children->data);
1623}
1624
1625static void
1626sig_fill_menu (MailAccountGui *gui)
1627{
1628        ESignatureList *signatures;
1629        GtkWidget *menu, *item;
1630        EIterator *it;
1631       
1632        menu = gtk_option_menu_get_menu (gui->sig_menu);
1633        clear_menu (menu);
1634       
1635        item = gtk_menu_item_new_with_label (_("None"));
1636        gtk_widget_show (item);
1637        g_signal_connect (item, "activate", G_CALLBACK (sig_activate), gui);
1638        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1639       
1640        signatures = mail_config_get_signatures ();
1641        it = e_list_get_iterator ((EList *) signatures);
1642       
1643        while (e_iterator_is_valid (it)) {
1644                ESignature *sig;
1645               
1646                sig = (ESignature *) e_iterator_get (it);
1647                signature_added (signatures, sig, gui);
1648                e_iterator_next (it);
1649        }
1650       
1651        g_object_unref (it);
1652       
1653        gui->sig_added_id = g_signal_connect (signatures, "signature-added", G_CALLBACK (signature_added), gui);
1654        gui->sig_removed_id = g_signal_connect (signatures, "signature-removed", G_CALLBACK (signature_removed), gui);
1655        gui->sig_changed_id = g_signal_connect (signatures, "signature-changed", G_CALLBACK (signature_changed), gui);
1656       
1657        gtk_option_menu_set_history (gui->sig_menu, 0);
1658}
1659
1660static void
1661sig_switch_to_list (GtkWidget *w, MailAccountGui *gui)
1662{
1663        gtk_window_set_transient_for (GTK_WINDOW (gtk_widget_get_toplevel (w)), NULL);
1664        gdk_window_raise (GTK_WIDGET (gui->dialog)->window);
1665        gtk_notebook_set_current_page (GTK_NOTEBOOK (glade_xml_get_widget (gui->dialog->gui, "notebook")), 3);
1666}
1667
1668static void
1669sig_add_new_signature (GtkWidget *w, MailAccountGui *gui)
1670{
1671        GConfClient *gconf;
1672        gboolean send_html;
1673        GtkWidget *parent;
1674       
1675        if (!gui->dialog)
1676                return;
1677       
1678        sig_switch_to_list (w, gui);
1679       
1680        gconf = mail_config_get_gconf_client ();
1681        send_html = gconf_client_get_bool (gconf, "/apps/evolution/mail/composer/send_html", NULL);
1682       
1683        parent = gtk_widget_get_toplevel (w);
1684        parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
1685       
1686        em_composer_prefs_new_signature ((GtkWindow *) parent, send_html);
1687}
1688
1689static void
1690select_account_signature (MailAccountGui *gui)
1691{
1692        ESignature *sig, *cur;
1693        GtkWidget *menu;
1694        GList *items;
1695        int i = 0;
1696       
1697        if (!gui->account->id->sig_uid || !(sig = mail_config_get_signature_by_uid (gui->account->id->sig_uid)))
1698                return;
1699       
1700        menu = gtk_option_menu_get_menu (gui->sig_menu);
1701        items = GTK_MENU_SHELL (menu)->children;
1702        while (items != NULL) {
1703                cur = g_object_get_data (items->data, "sig");
1704                if (cur == sig) {
1705                        gtk_option_menu_set_history (gui->sig_menu, i);
1706                        gtk_menu_item_activate (items->data);
1707                        break;
1708                }
1709                items = items->next;
1710                i++;
1711        }
1712}
1713
1714static void
1715prepare_signatures (MailAccountGui *gui)
1716{
1717        GtkWidget *button;
1718       
1719        gui->sig_menu = (GtkOptionMenu *) glade_xml_get_widget (gui->xml, "sigOption");
1720        sig_fill_menu (gui);
1721       
1722        button = glade_xml_get_widget (gui->xml, "sigAddNew");
1723        g_signal_connect (button, "clicked", G_CALLBACK (sig_add_new_signature), gui);
1724       
1725        if (!gui->dialog) {
1726                gtk_widget_hide (glade_xml_get_widget (gui->xml, "sigLabel"));
1727                gtk_widget_hide (glade_xml_get_widget (gui->xml, "sigOption"));
1728                gtk_widget_hide (glade_xml_get_widget (gui->xml, "sigAddNew"));
1729        }
1730       
1731        select_account_signature (gui);
1732}
1733
1734#if defined (HAVE_NSS)
1735static void
1736smime_changed(MailAccountGui *gui)
1737{
1738        int act;
1739        const char *tmp;
1740
1741        tmp = gtk_entry_get_text(gui->smime_sign_key);
1742        act = tmp && tmp[0];
1743        gtk_widget_set_sensitive((GtkWidget *)gui->smime_sign_key_clear, act);
1744        gtk_widget_set_sensitive((GtkWidget *)gui->smime_sign_default, act);
1745        if (!act)
1746                gtk_toggle_button_set_active(gui->smime_sign_default, FALSE);
1747
1748        tmp = gtk_entry_get_text(gui->smime_encrypt_key);
1749        act = tmp && tmp[0];
1750        gtk_widget_set_sensitive((GtkWidget *)gui->smime_encrypt_key_clear, act);
1751        gtk_widget_set_sensitive((GtkWidget *)gui->smime_encrypt_default, act);
1752        gtk_widget_set_sensitive((GtkWidget *)gui->smime_encrypt_to_self, act);
1753        if (!act) {
1754                gtk_toggle_button_set_active(gui->smime_encrypt_default, FALSE);
1755                gtk_toggle_button_set_active(gui->smime_encrypt_to_self, FALSE);
1756        }
1757}
1758
1759static void
1760smime_sign_key_selected(GtkWidget *dialog, const char *key, MailAccountGui *gui)
1761{
1762        if (key != NULL) {
1763                gtk_entry_set_text(gui->smime_sign_key, key);
1764                smime_changed(gui);
1765        }
1766
1767        gtk_widget_destroy(dialog);
1768}
1769
1770static void
1771smime_sign_key_select(GtkWidget *button, MailAccountGui *gui)
1772{
1773        GtkWidget *w;
1774
1775        w = e_cert_selector_new(E_CERT_SELECTOR_SIGNER, gtk_entry_get_text(gui->smime_sign_key));
1776        gtk_window_set_modal((GtkWindow *)w, TRUE);
1777        gtk_window_set_transient_for((GtkWindow *)w, (GtkWindow *)gui->dialog);
1778        g_signal_connect(w, "selected", G_CALLBACK(smime_sign_key_selected), gui);
1779        gtk_widget_show(w);
1780}
1781
1782static void
1783smime_sign_key_clear(GtkWidget *w, MailAccountGui *gui)
1784{
1785        gtk_entry_set_text(gui->smime_sign_key, "");
1786        smime_changed(gui);
1787}
1788
1789static void
1790smime_encrypt_key_selected(GtkWidget *dialog, const char *key, MailAccountGui *gui)
1791{
1792        if (key != NULL) {
1793                gtk_entry_set_text(gui->smime_encrypt_key, key);
1794                smime_changed(gui);
1795        }
1796
1797        gtk_widget_destroy(dialog);
1798}
1799
1800static void
1801smime_encrypt_key_select(GtkWidget *button, MailAccountGui *gui)
1802{
1803        GtkWidget *w;
1804
1805        w = e_cert_selector_new(E_CERT_SELECTOR_SIGNER, gtk_entry_get_text(gui->smime_encrypt_key));
1806        gtk_window_set_modal((GtkWindow *)w, TRUE);
1807        gtk_window_set_transient_for((GtkWindow *)w, (GtkWindow *)gui->dialog);
1808        g_signal_connect(w, "selected", G_CALLBACK(smime_encrypt_key_selected), gui);
1809        gtk_widget_show(w);
1810}
1811
1812static void
1813smime_encrypt_key_clear(GtkWidget *w, MailAccountGui *gui)
1814{
1815        gtk_entry_set_text(gui->smime_encrypt_key, "");
1816        smime_changed(gui);
1817}
1818#endif
1819
1820#ifdef USE_GTKFILECHOOSER
1821static void
1822select_file_toggled (GtkToggleButton *toggle, GtkFileChooser *chooser)
1823{
1824        GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
1825       
1826        if (gtk_toggle_button_get_active (toggle))
1827                action = GTK_FILE_CHOOSER_ACTION_OPEN;
1828       
1829        gtk_file_chooser_set_action (chooser, action);
1830}
1831
1832static void
1833browse_clicked (GnomeFileEntry *fentry, MailAccountGui *gui)
1834{
1835        GtkWidget *check;
1836        struct stat st;
1837        char *path;
1838       
1839        if (GTK_IS_FILE_CHOOSER (fentry->fsw)) {
1840                check = gtk_check_button_new_with_label (_("Select a file"));
1841                g_signal_connect (check, "toggled", G_CALLBACK (select_file_toggled), fentry->fsw);
1842                gtk_widget_show (check);
1843                gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (fentry->fsw), check);
1844               
1845                path = gnome_file_entry_get_full_path (fentry, TRUE);
1846                if (path && stat (path, &st) == 0 && S_ISREG (st.st_mode))
1847                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
1848                else
1849                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), FALSE);
1850                gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (check));
1851                g_free (path);
1852        }
1853       
1854        g_signal_handlers_disconnect_by_func (fentry, G_CALLBACK (fentry), gui);
1855}
1856#endif /* USE_GTKFILECHOOSER */
1857
1858MailAccountGui *
1859mail_account_gui_new (EAccount *account, EMAccountPrefs *dialog)
1860{
1861        MailAccountGui *gui;
1862        GtkWidget *fileentry;
1863       
1864        g_object_ref (account);
1865       
1866        gui = g_new0 (MailAccountGui, 1);
1867        gui->account = account;
1868        gui->dialog = dialog;
1869        gui->xml = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config.glade", NULL, NULL);
1870       
1871#ifdef USE_GTKFILECHOOSER
1872        /* KLUDGE: If this Evolution was built with GtkFileChooser support, the user
1873         * won't be able to create some types of local accounts because GtkFileChooser
1874         * must be set to allow selection of one or the other of file vs folder.
1875         * However, some providers allow the selection of files *or* folders. */
1876        fileentry = glade_xml_get_widget (gui->xml, "source_path_entry");
1877        g_signal_connect_after (fileentry, "browse-clicked", G_CALLBACK (browse_clicked), gui);
1878#endif
1879       
1880        /* Management */
1881        gui->account_name = GTK_ENTRY (glade_xml_get_widget (gui->xml, "management_name"));
1882        gui->default_account = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "management_default"));
1883        if (account->name)
1884                gtk_entry_set_text (gui->account_name, account->name);
1885        if (!mail_config_get_default_account ()
1886            || (account == mail_config_get_default_account ()))
1887                gtk_toggle_button_set_active (gui->default_account, TRUE);
1888       
1889        /* Identity */
1890        gui->full_name = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_full_name"));
1891        gui->email_address = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_address"));
1892        gui->reply_to = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_reply_to"));
1893        gui->organization = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_organization"));
1894       
1895        if (account->id->name)
1896                gtk_entry_set_text (gui->full_name, account->id->name);
1897        if (account->id->address)
1898                gtk_entry_set_text (gui->email_address, account->id->address);
1899        if (account->id->reply_to)
1900                gtk_entry_set_text (gui->reply_to, account->id->reply_to);
1901        if (account->id->organization)
1902                gtk_entry_set_text (gui->organization, account->id->organization);
1903       
1904        prepare_signatures (gui);
1905       
1906        /* Source */
1907        gui->source.provider_type = CAMEL_PROVIDER_STORE;
1908        gui->source.container = glade_xml_get_widget(gui->xml, "source_vbox");
1909        gui->source.type = GTK_OPTION_MENU (glade_xml_get_widget (gui->xml, "source_type_omenu"));
1910        gui->source.description = GTK_LABEL (glade_xml_get_widget (gui->xml, "source_description"));
1911        gui->source.hostname = GTK_ENTRY (glade_xml_get_widget (gui->xml, "source_host"));
1912        g_signal_connect (gui->source.hostname, "changed",
1913                          G_CALLBACK (service_changed), &gui->source);
1914        gui->source.username = GTK_ENTRY (glade_xml_get_widget (gui->xml, "source_user"));
1915        g_signal_connect (gui->source.username, "changed",
1916                          G_CALLBACK (service_changed), &gui->source);
1917        gui->source.path = GTK_ENTRY (glade_xml_get_widget (gui->xml, "source_path"));
1918        g_signal_connect (gui->source.path, "changed",
1919                          G_CALLBACK (service_changed), &gui->source);
1920        gui->source.ssl_frame = glade_xml_get_widget (gui->xml, "source_security_frame");
1921        gtk_widget_hide (gui->source.ssl_frame);
1922        gui->source.ssl_hbox = glade_xml_get_widget (gui->xml, "source_ssl_hbox");
1923        gui->source.use_ssl = GTK_OPTION_MENU (glade_xml_get_widget (gui->xml, "source_use_ssl"));
1924        construct_ssl_menu (&gui->source);
1925        gui->source.no_ssl = glade_xml_get_widget (gui->xml, "source_ssl_disabled");
1926        gui->source.authtype = GTK_OPTION_MENU (glade_xml_get_widget (gui->xml, "source_auth_omenu"));
1927        gui->source.remember = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "source_remember_password"));
1928        gui->source.check_supported = GTK_BUTTON (glade_xml_get_widget (gui->xml, "source_check_supported"));
1929        g_signal_connect (gui->source.check_supported, "clicked",
1930                          G_CALLBACK (service_check_supported), &gui->source);
1931        gui->source_auto_check = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "extra_auto_check"));
1932        gui->source_auto_check_min = GTK_SPIN_BUTTON (glade_xml_get_widget (gui->xml, "extra_auto_check_min"));
1933       
1934        /* Transport */
1935        gui->transport.provider_type = CAMEL_PROVIDER_TRANSPORT;
1936        gui->transport.container = glade_xml_get_widget(gui->xml, "transport_vbox");
1937        gui->transport.type = GTK_OPTION_MENU (glade_xml_get_widget (gui->xml, "transport_type_omenu"));
1938        gui->transport.description = GTK_LABEL (glade_xml_get_widget (gui->xml, "transport_description"));
1939        gui->transport.hostname = GTK_ENTRY (glade_xml_get_widget (gui->xml, "transport_host"));
1940        g_signal_connect (gui->transport.hostname, "changed",
1941                          G_CALLBACK (service_changed), &gui->transport);
1942        gui->transport.username = GTK_ENTRY (glade_xml_get_widget (gui->xml, "transport_user"));
1943        g_signal_connect (gui->transport.username, "changed",
1944                          G_CALLBACK (service_changed), &gui->transport);
1945        gui->transport.ssl_frame = glade_xml_get_widget (gui->xml, "transport_security_frame");
1946        gtk_widget_hide (gui->transport.ssl_frame);
1947        gui->transport.ssl_hbox = glade_xml_get_widget (gui->xml, "transport_ssl_hbox");
1948        gui->transport.use_ssl = GTK_OPTION_MENU (glade_xml_get_widget (gui->xml, "transport_use_ssl"));
1949        construct_ssl_menu (&gui->transport);
1950        gui->transport.no_ssl = glade_xml_get_widget (gui->xml, "transport_ssl_disabled");
1951        gui->transport.needs_auth = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "transport_needs_auth"));
1952        g_signal_connect (gui->transport.needs_auth, "toggled",
1953                          G_CALLBACK (transport_needs_auth_toggled), gui);
1954        gui->transport.authtype = GTK_OPTION_MENU (glade_xml_get_widget (gui->xml, "transport_auth_omenu"));
1955        gui->transport.remember = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "transport_remember_password"));
1956        gui->transport.check_supported = GTK_BUTTON (glade_xml_get_widget (gui->xml, "transport_check_supported"));
1957        g_signal_connect (gui->transport.check_supported, "clicked",
1958                          G_CALLBACK (service_check_supported), &gui->transport);
1959       
1960        /* Drafts folder */
1961        gui->drafts_folder_button = GTK_BUTTON (glade_xml_get_widget (gui->xml, "drafts_button"));
1962        g_signal_connect (gui->drafts_folder_button, "selected", G_CALLBACK (folder_selected), &gui->drafts_folder_uri);
1963        if (account->drafts_folder_uri)
1964                gui->drafts_folder_uri = em_uri_to_camel (account->drafts_folder_uri);
1965        else
1966                gui->drafts_folder_uri = g_strdup(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS));
1967        em_folder_selection_button_set_selection((EMFolderSelectionButton *)gui->drafts_folder_button, gui->drafts_folder_uri);
1968        gtk_widget_show ((GtkWidget *) gui->drafts_folder_button);
1969       
1970        /* Sent folder */
1971        gui->sent_folder_button = GTK_BUTTON (glade_xml_get_widget (gui->xml, "sent_button"));
1972        g_signal_connect (gui->sent_folder_button, "selected", G_CALLBACK (folder_selected), &gui->sent_folder_uri);
1973        if (account->sent_folder_uri)
1974                gui->sent_folder_uri = em_uri_to_camel (account->sent_folder_uri);
1975        else
1976                gui->sent_folder_uri = g_strdup(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT));
1977        em_folder_selection_button_set_selection((EMFolderSelectionButton *)gui->sent_folder_button, gui->sent_folder_uri);
1978        gtk_widget_show ((GtkWidget *) gui->sent_folder_button);
1979       
1980        /* Special Folders "Reset Defaults" button */
1981        gui->restore_folders_button = (GtkButton *)glade_xml_get_widget (gui->xml, "default_folders_button");
1982        g_signal_connect (gui->restore_folders_button, "clicked", G_CALLBACK (default_folders_clicked), gui);
1983       
1984        /* Always Cc */
1985        gui->always_cc = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "always_cc"));
1986        gtk_toggle_button_set_active (gui->always_cc, account->always_cc);
1987        gui->cc_addrs = GTK_ENTRY (glade_xml_get_widget (gui->xml, "cc_addrs"));
1988        if (account->cc_addrs)
1989                gtk_entry_set_text (gui->cc_addrs, account->cc_addrs);
1990       
1991        /* Always Bcc */
1992        gui->always_bcc = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "always_bcc"));
1993        gtk_toggle_button_set_active (gui->always_bcc, account->always_bcc);
1994        gui->bcc_addrs = GTK_ENTRY (glade_xml_get_widget (gui->xml, "bcc_addrs"));
1995        if (account->bcc_addrs)
1996                gtk_entry_set_text (gui->bcc_addrs, account->bcc_addrs);
1997       
1998        /* Security */
1999        gui->pgp_key = GTK_ENTRY (glade_xml_get_widget (gui->xml, "pgp_key"));
2000        if (account->pgp_key)
2001                gtk_entry_set_text (gui->pgp_key, account->pgp_key);
2002        gui->pgp_encrypt_to_self = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_encrypt_to_self"));
2003        gtk_toggle_button_set_active (gui->pgp_encrypt_to_self, account->pgp_encrypt_to_self);
2004        gui->pgp_always_sign = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_always_sign"));
2005        gtk_toggle_button_set_active (gui->pgp_always_sign, account->pgp_always_sign);
2006        gui->pgp_no_imip_sign = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_no_imip_sign"));
2007        gtk_toggle_button_set_active (gui->pgp_no_imip_sign, account->pgp_no_imip_sign);
2008        gui->pgp_always_trust = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "pgp_always_trust"));
2009        gtk_toggle_button_set_active (gui->pgp_always_trust, account->pgp_always_trust);
2010       
2011#if defined (HAVE_NSS)
2012        gui->smime_sign_key = (GtkEntry *)glade_xml_get_widget (gui->xml, "smime_sign_key");
2013        if (account->smime_sign_key)
2014                gtk_entry_set_text(gui->smime_sign_key, account->smime_sign_key);
2015        gui->smime_sign_key_select = (GtkButton *)glade_xml_get_widget (gui->xml, "smime_sign_key_select");
2016        gui->smime_sign_key_clear = (GtkButton *)glade_xml_get_widget (gui->xml, "smime_sign_key_clear");
2017        g_signal_connect(gui->smime_sign_key_select, "clicked", G_CALLBACK(smime_sign_key_select), gui);
2018        g_signal_connect(gui->smime_sign_key_clear, "clicked", G_CALLBACK(smime_sign_key_clear), gui);
2019
2020        gui->smime_sign_default = (GtkToggleButton *)glade_xml_get_widget (gui->xml, "smime_sign_default");
2021        gtk_toggle_button_set_active(gui->smime_sign_default, account->smime_sign_default);
2022
2023        gui->smime_encrypt_key = (GtkEntry *)glade_xml_get_widget (gui->xml, "smime_encrypt_key");
2024        if (account->smime_encrypt_key)
2025                gtk_entry_set_text(gui->smime_encrypt_key, account->smime_encrypt_key);
2026        gui->smime_encrypt_key_select = (GtkButton *)glade_xml_get_widget (gui->xml, "smime_encrypt_key_select");
2027        gui->smime_encrypt_key_clear = (GtkButton *)glade_xml_get_widget (gui->xml, "smime_encrypt_key_clear");
2028        g_signal_connect(gui->smime_encrypt_key_select, "clicked", G_CALLBACK(smime_encrypt_key_select), gui);
2029        g_signal_connect(gui->smime_encrypt_key_clear, "clicked", G_CALLBACK(smime_encrypt_key_clear), gui);
2030
2031        gui->smime_encrypt_default = (GtkToggleButton *)glade_xml_get_widget (gui->xml, "smime_encrypt_default");
2032        gtk_toggle_button_set_active(gui->smime_encrypt_default, account->smime_encrypt_default);
2033        gui->smime_encrypt_to_self = (GtkToggleButton *)glade_xml_get_widget (gui->xml, "smime_encrypt_to_self");
2034        gtk_toggle_button_set_active(gui->smime_encrypt_to_self, account->smime_encrypt_to_self);
2035        smime_changed(gui);
2036#else
2037        {
2038                /* Since we don't have NSS, hide the S/MIME config options */
2039                GtkWidget *frame;
2040               
2041                frame = glade_xml_get_widget (gui->xml, "smime_vbox");
2042                gtk_widget_destroy (frame);
2043        }
2044#endif /* HAVE_NSS */
2045
2046        return gui;
2047}
2048
2049void
2050mail_account_gui_setup (MailAccountGui *gui, GtkWidget *top)
2051{
2052        GtkWidget *stores, *transports, *item, *none;
2053        GtkWidget *fstore = NULL, *ftransport = NULL;
2054        int si = 0, hstore = 0, ti = 0, htransport = 0;
2055        int max_width = 0;
2056        char *max_authname = NULL;
2057        char *source_proto, *transport_proto;
2058        GList *providers, *l;
2059        gboolean writeable;
2060       
2061        printf("account gui setup\n");
2062       
2063        if (gui->account->source && gui->account->source->url) {
2064                source_proto = gui->account->source->url;
2065                source_proto = g_strndup (source_proto, strcspn (source_proto, ":"));
2066        } else
2067                source_proto = NULL;
2068       
2069        if (gui->account->transport && gui->account->transport->url) {
2070                transport_proto = gui->account->transport->url;
2071                transport_proto = g_strndup (transport_proto, strcspn (transport_proto, ":"));
2072        } else
2073                transport_proto = NULL;
2074       
2075        /* Construct source/transport option menus */
2076        stores = gtk_menu_new ();
2077        transports = gtk_menu_new ();
2078
2079        /* add a "None" option to the stores menu */
2080        none = item = gtk_menu_item_new_with_label (_("None"));
2081        g_object_set_data ((GObject *) item, "provider", NULL);
2082        g_signal_connect (item, "activate", G_CALLBACK (source_type_changed), gui);
2083        gtk_menu_shell_append(GTK_MENU_SHELL(stores), item);
2084        gtk_widget_show (item);
2085        si++;
2086
2087        providers = camel_provider_list(TRUE);
2088       
2089        /* sort the providers, remote first */
2090        providers = g_list_sort (providers, (GCompareFunc) provider_compare);
2091       
2092        for (l = providers; l; l = l->next) {
2093                CamelProvider *provider = l->data;
2094               
2095                if (!(!strcmp (provider->domain, "mail") || !strcmp (provider->domain, "news")))
2096                        continue;
2097               
2098                item = NULL;
2099                if (provider->object_types[CAMEL_PROVIDER_STORE] && provider->flags & CAMEL_PROVIDER_IS_SOURCE) {
2100                        item = gtk_menu_item_new_with_label (provider->name);
2101                        g_object_set_data ((GObject *) gui->source.type, provider->protocol, item);
2102                        g_object_set_data ((GObject *) item, "provider", provider);
2103                        g_object_set_data ((GObject *) item, "number", GUINT_TO_POINTER (si));
2104                        g_signal_connect (item, "activate", G_CALLBACK (source_type_changed), gui);
2105                       
2106                        gtk_menu_shell_append(GTK_MENU_SHELL(stores), item);
2107                       
2108                        gtk_widget_show (item);
2109                       
2110                        if (!fstore) {
2111                                fstore = item;
2112                                hstore = si;
2113                        }
2114                       
2115                        if (source_proto && !g_ascii_strcasecmp (provider->protocol, source_proto)) {
2116                                fstore = item;
2117                                hstore = si;
2118                        }
2119                       
2120                        si++;
2121                }
2122               
2123                if (provider->object_types[CAMEL_PROVIDER_TRANSPORT]) {
2124                        item = gtk_menu_item_new_with_label (provider->name);
2125                        g_object_set_data ((GObject *) gui->transport.type, provider->protocol, item);
2126                        g_object_set_data ((GObject *) item, "provider", provider);
2127                        g_object_set_data ((GObject *) item, "number", GUINT_TO_POINTER (ti));
2128                        g_signal_connect (item, "activate", G_CALLBACK (transport_type_changed), gui);
2129                       
2130                        gtk_menu_shell_append(GTK_MENU_SHELL(transports), item);
2131                       
2132                        gtk_widget_show (item);
2133                       
2134                        if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider))
2135                                gtk_widget_set_sensitive (item, FALSE);
2136                       
2137                        if (!ftransport
2138                            && !CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) {
2139                                ftransport = item;
2140                                htransport = ti;
2141                        }
2142                       
2143                        if (transport_proto && !g_ascii_strcasecmp (provider->protocol, transport_proto)) {
2144                                ftransport = item;
2145                                htransport = ti;
2146                        }
2147                       
2148                        ti++;
2149                }
2150               
2151                if (item && provider->authtypes) {
2152                        /*GdkFont *font = GTK_WIDGET (item)->style->font;*/
2153                        CamelServiceAuthType *at;
2154                        int width;
2155                        GList *a;
2156                       
2157                        for (a = provider->authtypes; a; a = a->next) {
2158                                at = a->data;
2159                               
2160                                /* Just using string length is probably good enough,
2161                                   as we only use the width of the widget, not the string */
2162                                /*width = gdk_string_width (font, at->name);*/
2163                                width = strlen(at->name) * 14;
2164                                if (width > max_width) {
2165                                        max_authname = at->name;
2166                                        max_width = width;
2167                                }
2168                        }
2169                }
2170        }
2171        g_list_free (providers);
2172       
2173        if (!fstore || !source_proto) {
2174                fstore = none;
2175                hstore = 0;
2176        }
2177       
2178        /* set the menus on the optionmenus */
2179        gtk_option_menu_remove_menu (gui->source.type);
2180        gtk_option_menu_set_menu (gui->source.type, stores);
2181       
2182        gtk_option_menu_remove_menu (gui->transport.type);
2183        gtk_option_menu_set_menu (gui->transport.type, transports);
2184       
2185        /* Force the authmenus to the width of the widest element */
2186        if (max_authname) {
2187                GtkWidget *menu;
2188                GtkRequisition size_req;
2189               
2190                menu = gtk_menu_new ();
2191                item = gtk_menu_item_new_with_label (max_authname);
2192                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2193                gtk_widget_show_all (menu);
2194                gtk_option_menu_set_menu (gui->source.authtype, menu);
2195                gtk_widget_show (GTK_WIDGET (gui->source.authtype));
2196                gtk_widget_size_request (GTK_WIDGET (gui->source.authtype),
2197                                         &size_req);
2198               
2199                gtk_widget_set_size_request (GTK_WIDGET (gui->source.authtype),
2200                                      size_req.width, -1);
2201                gtk_widget_set_size_request (GTK_WIDGET (gui->transport.authtype),
2202                                      size_req.width, -1);
2203        }
2204       
2205        if (top != NULL) {
2206                gtk_widget_show (top);
2207        }
2208       
2209        if (fstore) {
2210                g_signal_emit_by_name (fstore, "activate");
2211                gtk_option_menu_set_history (gui->source.type, hstore);
2212        }
2213       
2214        if (ftransport) {
2215                g_signal_emit_by_name (ftransport, "activate");
2216                gtk_option_menu_set_history (gui->transport.type, htransport);
2217        }
2218       
2219        if (source_proto) {
2220                setup_service (gui, &gui->source, gui->account->source);
2221                gui->source.provider_type = CAMEL_PROVIDER_STORE;
2222                g_free (source_proto);
2223                if (gui->account->source->auto_check) {
2224                        gtk_toggle_button_set_active (gui->source_auto_check, TRUE);
2225                        gtk_spin_button_set_value (gui->source_auto_check_min,
2226                                                   gui->account->source->auto_check_time);
2227                }
2228        }
2229       
2230        if (transport_proto) {
2231                if (setup_service (gui, &gui->transport, gui->account->transport))
2232                        gtk_toggle_button_set_active (gui->transport.needs_auth, TRUE);
2233                gui->transport.provider_type = CAMEL_PROVIDER_TRANSPORT;
2234                g_free (transport_proto);
2235        }
2236
2237        /* FIXME: drive by table?? */
2238        if (!e_account_writable (gui->account, E_ACCOUNT_SOURCE_URL)) {
2239                gtk_widget_set_sensitive (gui->source.container, FALSE);
2240        } else {
2241                gtk_widget_set_sensitive (gui->source.container, TRUE);
2242               
2243                if (gui->source.provider) {
2244                        writeable = e_account_writable_option (gui->account, gui->source.provider->protocol, "auth");
2245                        gtk_widget_set_sensitive ((GtkWidget *) gui->source.authtype, writeable);
2246                        gtk_widget_set_sensitive ((GtkWidget *) gui->source.check_supported, writeable);
2247                       
2248                        writeable = e_account_writable_option (gui->account, gui->source.provider->protocol, "use_ssl");
2249                        gtk_widget_set_sensitive ((GtkWidget *) gui->source.use_ssl, writeable);
2250                       
2251                        writeable = e_account_writable (gui->account, E_ACCOUNT_SOURCE_SAVE_PASSWD);
2252                        gtk_widget_set_sensitive ((GtkWidget *) gui->source.remember, writeable);
2253                }
2254        }
2255       
2256        if (!e_account_writable (gui->account, E_ACCOUNT_TRANSPORT_URL)) {
2257                gtk_widget_set_sensitive (gui->transport.container, FALSE);
2258        } else {
2259                gtk_widget_set_sensitive (gui->transport.container, TRUE);
2260               
2261                if (gui->transport.provider) {
2262                        writeable = e_account_writable_option (gui->account, gui->transport.provider->protocol, "auth");
2263                        gtk_widget_set_sensitive ((GtkWidget *) gui->transport.authtype, writeable);
2264                        gtk_widget_set_sensitive ((GtkWidget *) gui->transport.check_supported, writeable);
2265                       
2266                        writeable = e_account_writable_option (gui->account, gui->transport.provider->protocol, "use_ssl");
2267                        gtk_widget_set_sensitive ((GtkWidget *) gui->transport.use_ssl, writeable);
2268                       
2269                        writeable = e_account_writable (gui->account, E_ACCOUNT_TRANSPORT_SAVE_PASSWD);
2270                        gtk_widget_set_sensitive ((GtkWidget *) gui->transport.remember, writeable);
2271                }
2272        }
2273
2274        gtk_widget_set_sensitive((GtkWidget *)gui->drafts_folder_button, e_account_writable(gui->account, E_ACCOUNT_DRAFTS_FOLDER_URI));
2275        gtk_widget_set_sensitive((GtkWidget *)gui->sent_folder_button, e_account_writable(gui->account, E_ACCOUNT_SENT_FOLDER_URI));
2276        gtk_widget_set_sensitive((GtkWidget *)gui->restore_folders_button,
2277                                 e_account_writable(gui->account, E_ACCOUNT_SENT_FOLDER_URI)
2278                                 || e_account_writable(gui->account, E_ACCOUNT_DRAFTS_FOLDER_URI));
2279        gtk_widget_set_sensitive((GtkWidget *)gui->sig_menu, e_account_writable(gui->account, E_ACCOUNT_ID_SIGNATURE));
2280        gtk_widget_set_sensitive(glade_xml_get_widget(gui->xml, "sigAddNew"),
2281                                 gconf_client_key_is_writable(mail_config_get_gconf_client(),
2282                                                              "/apps/evolution/mail/signatures", NULL));
2283        gtk_widget_set_sensitive((GtkWidget *)gui->source_auto_check, e_account_writable(gui->account, E_ACCOUNT_SOURCE_AUTO_CHECK));
2284        gtk_widget_set_sensitive((GtkWidget *)gui->source_auto_check_min, e_account_writable(gui->account, E_ACCOUNT_SOURCE_AUTO_CHECK_TIME));
2285}
2286
2287static void
2288save_service (MailAccountGuiService *gsvc, GHashTable *extra_config, EAccountService *service)
2289{
2290        CamelURL *url;
2291        const char *str;
2292       
2293        if (!gsvc->provider) {
2294                g_free (service->url);
2295                service->url = NULL;
2296                return;
2297        }
2298       
2299        url = g_new0 (CamelURL, 1);
2300        url->protocol = g_strdup (gsvc->provider->protocol);
2301       
2302        if (CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_USER)) {
2303                str = gtk_entry_get_text (gsvc->username);
2304                if (str && *str)
2305                        url->user = g_strstrip (g_strdup (str));
2306        }
2307       
2308        if (CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_AUTH) && url->user) {
2309                if (gsvc->needs_auth == NULL || gtk_toggle_button_get_active(gsvc->needs_auth)) {
2310                        CamelServiceAuthType *authtype;
2311               
2312                        authtype = g_object_get_data(G_OBJECT(gsvc->authitem), "authtype");
2313                        if (authtype && authtype->authproto && *authtype->authproto)
2314                                url->authmech = g_strdup (authtype->authproto);
2315                }
2316
2317                if (gsvc->remember)
2318                        service->save_passwd = gtk_toggle_button_get_active (gsvc->remember);
2319        }
2320       
2321        if (CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_HOST)) {
2322                char *pport;
2323               
2324                str = gtk_entry_get_text (gsvc->hostname);
2325                if (str && *str) {
2326                        pport = strchr (str, ':');
2327                        if (pport) {
2328                                url->host = g_strndup (str, pport - str);
2329                                url->port = atoi (pport + 1);
2330                        } else
2331                                url->host = g_strdup (str);
2332                }
2333        }
2334       
2335        if (CAMEL_PROVIDER_ALLOWS (gsvc->provider, CAMEL_URL_PART_PATH)) {
2336                str = gtk_entry_get_text (gsvc->path);
2337                if (str && *str)
2338                        url->path = g_strdup (str);
2339        }
2340       
2341        if (gsvc->provider->flags & CAMEL_PROVIDER_SUPPORTS_SSL) {
2342                const char *use_ssl;
2343               
2344                use_ssl = g_object_get_data(G_OBJECT(gsvc->ssl_selected), "use_ssl");
2345               
2346                /* set the value to either "always" or "when-possible"
2347                   but don't bother setting it for "never" */
2348                if (strcmp (use_ssl, "never"))
2349                        camel_url_set_param (url, "use_ssl", use_ssl);
2350        }
2351       
2352        if (extra_config)
2353                extract_values (gsvc, extra_config, url);
2354       
2355        g_free (service->url);
2356        service->url = camel_url_to_string (url, 0);
2357       
2358        /* Temporary until keep_on_server moves into the POP provider */
2359        if (camel_url_get_param (url, "keep_on_server"))
2360                service->keep_on_server = TRUE;
2361       
2362        camel_url_free (url);
2363}
2364
2365static void
2366add_new_store (char *uri, CamelStore *store, void *user_data)
2367{
2368        MailComponent *component = mail_component_peek ();
2369        EAccount *account = user_data;
2370       
2371        if (store == NULL)
2372                return;
2373       
2374        mail_component_add_store (component, store, account->name);
2375}
2376
2377gboolean
2378mail_account_gui_save (MailAccountGui *gui)
2379{
2380        EAccount *account, *new;
2381        CamelProvider *provider = NULL;
2382        gboolean is_new = FALSE;
2383        const char *new_name;
2384        gboolean is_storage;
2385       
2386        if (!mail_account_gui_identity_complete (gui, NULL) ||
2387            !mail_account_gui_source_complete (gui, NULL) ||
2388            !mail_account_gui_transport_complete (gui, NULL) ||
2389            !mail_account_gui_management_complete (gui, NULL))
2390                return FALSE;
2391       
2392        new = gui->account;
2393       
2394        /* this would happen at an inconvenient time in the druid,
2395         * but the druid performs its own check so this can't happen
2396         * here. */
2397       
2398        new_name = gtk_entry_get_text (gui->account_name);
2399        account = mail_config_get_account_by_name (new_name);
2400       
2401        if (account && account != new) {
2402                e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)gui->account_name),
2403                            "mail:account-notunique", NULL);
2404                return FALSE;
2405        }
2406       
2407        account = new;
2408       
2409        new = e_account_new ();
2410        new->name = g_strdup (new_name);
2411        new->enabled = account->enabled;
2412       
2413        /* construct the identity */
2414        new->id->name = g_strdup (gtk_entry_get_text (gui->full_name));
2415        new->id->address = g_strdup (gtk_entry_get_text (gui->email_address));
2416        new->id->reply_to = g_strdup (gtk_entry_get_text (gui->reply_to));
2417        new->id->organization = g_strdup (gtk_entry_get_text (gui->organization));
2418       
2419        /* signatures */
2420        new->id->sig_uid = g_strdup (gui->sig_uid);
2421       
2422        /* source */
2423        save_service (&gui->source, gui->extra_config, new->source);
2424        if (new->source->url)
2425                provider = camel_provider_get(new->source->url, NULL);
2426       
2427        new->source->auto_check = gtk_toggle_button_get_active (gui->source_auto_check);
2428        if (new->source->auto_check)
2429                new->source->auto_check_time = gtk_spin_button_get_value_as_int (gui->source_auto_check_min);
2430       
2431        /* transport */
2432        if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (gui->transport.provider)) {
2433                /* The transport URI is the same as the source URI. */
2434                save_service (&gui->source, gui->extra_config, new->transport);
2435        } else
2436                save_service (&gui->transport, NULL, new->transport);
2437       
2438        /* Check to make sure that the Drafts folder uri is "valid" before assigning it */
2439        if (gui->drafts_folder_uri != NULL
2440            && (mail_config_get_account_by_source_url (gui->drafts_folder_uri) ||
2441                !strncmp (gui->drafts_folder_uri, "mbox:", 5))) {
2442                new->drafts_folder_uri = em_uri_from_camel (gui->drafts_folder_uri);
2443        } else {
2444                /* assign defaults - the uri is unknown to us (probably pointed to an old source url) */
2445                new->drafts_folder_uri = em_uri_from_camel(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_DRAFTS));
2446        }
2447       
2448        /* Check to make sure that the Sent folder uri is "valid" before assigning it */
2449        if (gui->sent_folder_uri != NULL
2450            && (mail_config_get_account_by_source_url (gui->sent_folder_uri) ||
2451                !strncmp (gui->sent_folder_uri, "mbox:", 5))) {
2452                new->sent_folder_uri = em_uri_from_camel (gui->sent_folder_uri);
2453        } else {
2454                /* assign defaults - the uri is unknown to us (probably pointed to an old source url) */
2455                new->sent_folder_uri = em_uri_from_camel(mail_component_get_folder_uri(NULL, MAIL_COMPONENT_FOLDER_SENT));
2456        }
2457       
2458        new->always_cc = gtk_toggle_button_get_active (gui->always_cc);
2459        new->cc_addrs = g_strdup (gtk_entry_get_text (gui->cc_addrs));
2460        new->always_bcc = gtk_toggle_button_get_active (gui->always_bcc);
2461        new->bcc_addrs = g_strdup (gtk_entry_get_text (gui->bcc_addrs));
2462       
2463        new->pgp_key = g_strdup (gtk_entry_get_text (gui->pgp_key));
2464        new->pgp_encrypt_to_self = gtk_toggle_button_get_active (gui->pgp_encrypt_to_self);
2465        new->pgp_always_sign = gtk_toggle_button_get_active (gui->pgp_always_sign);
2466        new->pgp_no_imip_sign = gtk_toggle_button_get_active (gui->pgp_no_imip_sign);
2467        new->pgp_always_trust = gtk_toggle_button_get_active (gui->pgp_always_trust);
2468       
2469#if defined (HAVE_NSS)
2470        new->smime_sign_default = gtk_toggle_button_get_active (gui->smime_sign_default);
2471        new->smime_sign_key = g_strdup (gtk_entry_get_text (gui->smime_sign_key));
2472       
2473        new->smime_encrypt_default = gtk_toggle_button_get_active (gui->smime_encrypt_default);
2474        new->smime_encrypt_key = g_strdup (gtk_entry_get_text (gui->smime_encrypt_key));
2475        new->smime_encrypt_to_self = gtk_toggle_button_get_active (gui->smime_encrypt_to_self);
2476#endif /* HAVE_NSS */
2477       
2478        is_storage = provider && (provider->flags & CAMEL_PROVIDER_IS_STORAGE);
2479       
2480        if (!mail_config_find_account (account)) {
2481                /* this is a new account so add it to our account-list */
2482                is_new = TRUE;
2483        }
2484       
2485        /* update the old account with the new settings */
2486        e_account_import (account, new);
2487        g_object_unref (new);
2488       
2489        if (is_new) {
2490                mail_config_add_account (account);
2491               
2492                /* if the account provider is something we can stick
2493                   in the folder-tree and not added by some other
2494                   component, then get the CamelStore and add it to
2495                   the folder-tree */
2496                if (is_storage && account->enabled)
2497                        mail_get_store (account->source->url, NULL, add_new_store, account);
2498        } else {
2499                e_account_list_change (mail_config_get_accounts (), account);
2500        }
2501       
2502        if (gtk_toggle_button_get_active (gui->default_account))
2503                mail_config_set_default_account (account);
2504       
2505        mail_config_save_accounts ();
2506       
2507        mail_autoreceive_setup ();
2508       
2509        return TRUE;
2510}
2511
2512void
2513mail_account_gui_destroy (MailAccountGui *gui)
2514{
2515        ESignatureList *signatures;
2516       
2517        g_object_unref (gui->xml);
2518        g_object_unref (gui->account);
2519       
2520        signatures = mail_config_get_signatures ();
2521        g_signal_handler_disconnect (signatures, gui->sig_added_id);
2522        g_signal_handler_disconnect (signatures, gui->sig_removed_id);
2523        g_signal_handler_disconnect (signatures, gui->sig_changed_id);
2524       
2525        if (gui->extra_config)
2526                g_hash_table_destroy (gui->extra_config);
2527       
2528        g_free (gui->drafts_folder_uri);
2529        g_free (gui->sent_folder_uri);
2530        g_free (gui);
2531}
Note: See TracBrowser for help on using the repository browser.