aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2011-04-13 22:30:40 +0800
committerMatthew Barnes <mbarnes@redhat.com>2012-06-03 11:00:40 +0800
commit3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81 (patch)
treeff59febf4ac0c6316ef344ea25cee002088bd314 /mail
parentf78795f4dff8b225d78385c5e23e1cd44ee946ad (diff)
downloadgsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.gz
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.bz2
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.lz
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.xz
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.tar.zst
gsoc2013-evolution-3449e5fcc7f9c797fcde7f2a444b1eb7a934cd81.zip
Adapt mail to the new ESource API.
Diffstat (limited to 'mail')
-rw-r--r--mail/Makefile.am61
-rw-r--r--mail/e-mail-account-manager.c61
-rw-r--r--mail/e-mail-account-manager.h6
-rw-r--r--mail/e-mail-account-store.c315
-rw-r--r--mail/e-mail-autoconfig.c883
-rw-r--r--mail/e-mail-autoconfig.h89
-rw-r--r--mail/e-mail-backend.c246
-rw-r--r--mail/e-mail-config-assistant.c1157
-rw-r--r--mail/e-mail-config-assistant.h96
-rw-r--r--mail/e-mail-config-auth-check.c446
-rw-r--r--mail/e-mail-config-auth-check.h73
-rw-r--r--mail/e-mail-config-confirm-page.c205
-rw-r--r--mail/e-mail-config-confirm-page.h75
-rw-r--r--mail/e-mail-config-defaults-page.c868
-rw-r--r--mail/e-mail-config-defaults-page.h79
-rw-r--r--mail/e-mail-config-identity-page.c738
-rw-r--r--mail/e-mail-config-identity-page.h91
-rw-r--r--mail/e-mail-config-lookup-page.c109
-rw-r--r--mail/e-mail-config-lookup-page.h73
-rw-r--r--mail/e-mail-config-notebook.c783
-rw-r--r--mail/e-mail-config-notebook.h98
-rw-r--r--mail/e-mail-config-page.c176
-rw-r--r--mail/e-mail-config-page.h72
-rw-r--r--mail/e-mail-config-provider-page.c774
-rw-r--r--mail/e-mail-config-provider-page.h81
-rw-r--r--mail/e-mail-config-receiving-page.c70
-rw-r--r--mail/e-mail-config-receiving-page.h69
-rw-r--r--mail/e-mail-config-security-page.c672
-rw-r--r--mail/e-mail-config-security-page.h73
-rw-r--r--mail/e-mail-config-sending-page.c70
-rw-r--r--mail/e-mail-config-sending-page.h68
-rw-r--r--mail/e-mail-config-service-backend.c514
-rw-r--r--mail/e-mail-config-service-backend.h121
-rw-r--r--mail/e-mail-config-service-notebook.c365
-rw-r--r--mail/e-mail-config-service-notebook.h77
-rw-r--r--mail/e-mail-config-service-page.c1039
-rw-r--r--mail/e-mail-config-service-page.h107
-rw-r--r--mail/e-mail-config-sidebar.c416
-rw-r--r--mail/e-mail-config-sidebar.h72
-rw-r--r--mail/e-mail-config-summary-page.c1064
-rw-r--r--mail/e-mail-config-summary-page.h101
-rw-r--r--mail/e-mail-config-welcome-page.c203
-rw-r--r--mail/e-mail-config-welcome-page.h75
-rw-r--r--mail/e-mail-config-window.c524
-rw-r--r--mail/e-mail-config-window.h71
-rw-r--r--mail/e-mail-folder-pane.c17
-rw-r--r--mail/e-mail-migrate.c524
-rw-r--r--mail/e-mail-paned-view.c8
-rw-r--r--mail/e-mail-reader-utils.c27
-rw-r--r--mail/e-mail-reader.c51
-rw-r--r--mail/e-mail-ui-session.c305
-rw-r--r--mail/e-mail-ui-session.h2
-rw-r--r--mail/e-mail.h1
-rw-r--r--mail/em-account-editor.c5834
-rw-r--r--mail/em-account-editor.h124
-rw-r--r--mail/em-composer-utils.c338
-rw-r--r--mail/em-composer-utils.h3
-rw-r--r--mail/em-filter-source-element.c114
-rw-r--r--mail/em-folder-tree-model.c98
-rw-r--r--mail/em-format-html.c19
-rw-r--r--mail/em-subscription-editor.c14
-rw-r--r--mail/em-utils.c52
-rw-r--r--mail/em-utils.h6
-rw-r--r--mail/mail-config.ui3174
-rw-r--r--mail/mail-send-recv.c292
-rw-r--r--mail/mail.error.xml28
-rw-r--r--mail/test-mail-autoconfig.c53
67 files changed, 13915 insertions, 10595 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 7358f359a5..d1c4fddce9 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -45,8 +45,28 @@ mailinclude_HEADERS = \
e-mail-account-store.h \
e-mail-account-tree-view.h \
e-mail-attachment-bar.h \
+ e-mail-autoconfig.h \
e-mail-backend.h \
e-mail-browser.h \
+ e-mail-config-assistant.h \
+ e-mail-config-auth-check.h \
+ e-mail-config-confirm-page.h \
+ e-mail-config-defaults-page.h \
+ e-mail-config-identity-page.h \
+ e-mail-config-lookup-page.h \
+ e-mail-config-notebook.h \
+ e-mail-config-page.h \
+ e-mail-config-provider-page.h \
+ e-mail-config-receiving-page.h \
+ e-mail-config-security-page.h \
+ e-mail-config-sending-page.h \
+ e-mail-config-service-backend.h \
+ e-mail-config-service-notebook.h \
+ e-mail-config-service-page.h \
+ e-mail-config-sidebar.h \
+ e-mail-config-summary-page.h \
+ e-mail-config-welcome-page.h \
+ e-mail-config-window.h \
e-mail-display.h \
e-mail-folder-pane.h \
e-mail-junk-options.h \
@@ -67,7 +87,6 @@ mailinclude_HEADERS = \
e-mail-tag-editor.h \
e-mail-ui-session.h \
e-mail-view.h \
- em-account-editor.h \
em-composer-utils.h \
em-config.h \
em-event.h \
@@ -111,8 +130,28 @@ libevolution_mail_la_SOURCES = \
e-mail-account-store.c \
e-mail-account-tree-view.c \
e-mail-attachment-bar.c \
+ e-mail-autoconfig.c \
e-mail-backend.c \
e-mail-browser.c \
+ e-mail-config-assistant.c \
+ e-mail-config-auth-check.c \
+ e-mail-config-confirm-page.c \
+ e-mail-config-defaults-page.c \
+ e-mail-config-identity-page.c \
+ e-mail-config-lookup-page.c \
+ e-mail-config-notebook.c \
+ e-mail-config-page.c \
+ e-mail-config-provider-page.c \
+ e-mail-config-receiving-page.c \
+ e-mail-config-security-page.c \
+ e-mail-config-sending-page.c \
+ e-mail-config-service-backend.c \
+ e-mail-config-service-notebook.c \
+ e-mail-config-service-page.c \
+ e-mail-config-sidebar.c \
+ e-mail-config-summary-page.c \
+ e-mail-config-welcome-page.c \
+ e-mail-config-window.c \
e-mail-display.c \
e-mail-folder-pane.c \
e-mail-junk-options.c \
@@ -133,7 +172,6 @@ libevolution_mail_la_SOURCES = \
e-mail-tag-editor.c \
e-mail-ui-session.c \
e-mail-view.c \
- em-account-editor.c \
em-composer-utils.c \
em-config.c \
em-event.c \
@@ -202,12 +240,29 @@ libevolution_mail_la_LIBADD = \
$(E_WIDGETS_LIBS) \
$(SMIME_LIBS) \
$(LIBSOUP_LIBS) \
- $(GNOME_PLATFORM_LIBS)
+ -lresolv
libevolution_mail_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
libevolution_mail_la_DEPENDENCIES = em-filter-i18n.h
+noinst_PROGRAMS = test-mail-autoconfig
+
+test_mail_autoconfig_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+test_mail_autoconfig_SOURCES = \
+ e-mail-autoconfig.c \
+ e-mail-autoconfig.h \
+ test-mail-autoconfig.c
+
+test_mail_autoconfig_LDADD = \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ -lresolv
+
# Misc data to install
filterdir = $(privdatadir)
filter_DATA = filtertypes.xml vfoldertypes.xml searchtypes.xml
diff --git a/mail/e-mail-account-manager.c b/mail/e-mail-account-manager.c
index 86a0bf5e4b..5cf6012351 100644
--- a/mail/e-mail-account-manager.c
+++ b/mail/e-mail-account-manager.c
@@ -22,6 +22,8 @@
#include <glib/gi18n-lib.h>
#include <gdk/gdkkeysyms.h>
+#include <libedataserver/e-source-collection.h>
+
#include <libemail-engine/e-mail-session.h>
#include <mail/e-mail-account-tree-view.h>
@@ -70,18 +72,27 @@ static void
mail_account_manager_edit_cb (EMailAccountManager *manager)
{
EMailAccountTreeView *tree_view;
- EAccount *account;
+ EMailAccountStore *store;
+ ESourceRegistry *registry;
+ EMailSession *session;
CamelService *service;
+ ESource *source;
const gchar *uid;
+ store = e_mail_account_manager_get_store (manager);
+ session = e_mail_account_store_get_session (store);
+ registry = e_mail_session_get_registry (session);
+
tree_view = E_MAIL_ACCOUNT_TREE_VIEW (manager->priv->tree_view);
service = e_mail_account_tree_view_get_selected_service (tree_view);
uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
- g_return_if_fail (account != NULL);
+ source = e_source_registry_ref_source (registry, uid);
+ g_return_if_fail (source != NULL);
- e_mail_account_manager_edit_account (manager, account);
+ e_mail_account_manager_edit_account (manager, source);
+
+ g_object_unref (source);
}
static void
@@ -209,6 +220,7 @@ mail_account_manager_selection_changed_cb (EMailAccountManager *manager,
gboolean builtin;
gboolean sensitive;
gboolean not_default;
+ gboolean removable;
add_button = manager->priv->add_button;
edit_button = manager->priv->edit_button;
@@ -221,9 +233,11 @@ mail_account_manager_selection_changed_cb (EMailAccountManager *manager,
E_MAIL_ACCOUNT_STORE_COLUMN_SERVICE, &service,
E_MAIL_ACCOUNT_STORE_COLUMN_BUILTIN, &builtin,
-1);
+ removable = !builtin;
} else {
service = NULL;
builtin = FALSE;
+ removable = FALSE;
}
store = e_mail_account_manager_get_store (manager);
@@ -232,11 +246,40 @@ mail_account_manager_selection_changed_cb (EMailAccountManager *manager,
if (service == NULL)
gtk_widget_grab_focus (add_button);
+ else {
+ ESource *source;
+ EMailSession *session;
+ ESourceRegistry *registry;
+ const gchar *uid;
+
+ session = e_mail_account_store_get_session (store);
+ registry = e_mail_session_get_registry (session);
+
+ uid = camel_service_get_uid (service);
+ source = e_source_registry_ref_source (registry, uid);
+
+ if (source != NULL) {
+ ESource *collection;
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_COLLECTION;
+ collection = e_source_registry_find_extension (
+ registry, source, extension_name);
+ if (collection != NULL) {
+ g_object_unref (source);
+ source = collection;
+ }
+
+ removable = e_source_get_removable (source);
+
+ g_object_unref (source);
+ }
+ }
sensitive = (service != NULL && !builtin);
gtk_widget_set_sensitive (edit_button, sensitive);
- sensitive = (service != NULL && !builtin);
+ sensitive = (service != NULL && removable);
gtk_widget_set_sensitive (delete_button, sensitive);
sensitive = (service != NULL && !builtin && not_default);
@@ -519,7 +562,7 @@ e_mail_account_manager_class_init (EMailAccountManagerClass *class)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
- E_TYPE_ACCOUNT);
+ E_TYPE_SOURCE);
}
static void
@@ -556,11 +599,11 @@ e_mail_account_manager_add_account (EMailAccountManager *manager)
void
e_mail_account_manager_edit_account (EMailAccountManager *manager,
- EAccount *account)
+ ESource *source)
{
g_return_if_fail (E_IS_MAIL_ACCOUNT_MANAGER (manager));
- g_return_if_fail (E_IS_ACCOUNT (account));
+ g_return_if_fail (E_IS_SOURCE (source));
- g_signal_emit (manager, signals[EDIT_ACCOUNT], 0, account);
+ g_signal_emit (manager, signals[EDIT_ACCOUNT], 0, source);
}
diff --git a/mail/e-mail-account-manager.h b/mail/e-mail-account-manager.h
index 63e52b463c..a17ff2a317 100644
--- a/mail/e-mail-account-manager.h
+++ b/mail/e-mail-account-manager.h
@@ -20,8 +20,8 @@
#define E_MAIL_ACCOUNT_MANAGER_H
#include <gtk/gtk.h>
+#include <libedataserver/e-source.h>
#include <mail/e-mail-account-store.h>
-#include <libemail-utils/e-account-utils.h>
/* Standard GObject macros */
#define E_TYPE_MAIL_ACCOUNT_MANAGER \
@@ -59,7 +59,7 @@ struct _EMailAccountManagerClass {
/* Signals */
void (*add_account) (EMailAccountManager *manager);
void (*edit_account) (EMailAccountManager *manager,
- EAccount *account);
+ ESource *source);
};
GType e_mail_account_manager_get_type (void) G_GNUC_CONST;
@@ -71,7 +71,7 @@ void e_mail_account_manager_add_account
(EMailAccountManager *manager);
void e_mail_account_manager_edit_account
(EMailAccountManager *manager,
- EAccount *account);
+ ESource *source);
G_END_DECLS
diff --git a/mail/e-mail-account-store.c b/mail/e-mail-account-store.c
index 2dac692d82..1c5dedf52e 100644
--- a/mail/e-mail-account-store.c
+++ b/mail/e-mail-account-store.c
@@ -23,11 +23,11 @@
#include <glib/gi18n-lib.h>
#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-collection.h>
#include <e-util/e-marshal.h>
#include <libevolution-utils/e-alert-dialog.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-engine/mail-ops.h>
#include <mail/mail-vfolder-ui.h>
@@ -101,24 +101,6 @@ index_item_free (IndexItem *item)
g_slice_free (IndexItem, item);
}
-static void
-mail_account_store_save_default (EMailAccountStore *store)
-{
- EAccountList *account_list;
- EAccount *account;
- CamelService *service;
- const gchar *uid;
-
- service = e_mail_account_store_get_default_service (store);
-
- account_list = e_get_account_list ();
- uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
- g_return_if_fail (account != NULL);
-
- e_account_list_set_default (account_list, account);
-}
-
static gboolean
mail_account_store_get_iter (EMailAccountStore *store,
CamelService *service,
@@ -238,6 +220,46 @@ mail_account_store_service_notify_cb (CamelService *service,
}
static void
+mail_account_store_remove_source_cb (ESource *source,
+ GAsyncResult *result,
+ EMailAccountStore *store)
+{
+ GError *error = NULL;
+
+ /* FIXME EMailAccountStore should implement EAlertSink. */
+ if (!e_source_remove_finish (source, result, &error)) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ g_return_if_fail (store->priv->busy_count > 0);
+ store->priv->busy_count--;
+ g_object_notify (G_OBJECT (store), "busy");
+
+ g_object_unref (store);
+}
+
+static void
+mail_account_store_write_source_cb (ESource *source,
+ GAsyncResult *result,
+ EMailAccountStore *store)
+{
+ GError *error = NULL;
+
+ /* FIXME EMailAccountStore should implement EAlertSink. */
+ if (!e_source_write_finish (source, result, &error)) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ g_return_if_fail (store->priv->busy_count > 0);
+ store->priv->busy_count--;
+ g_object_notify (G_OBJECT (store), "busy");
+
+ g_object_unref (store);
+}
+
+static void
mail_account_store_clean_index (EMailAccountStore *store)
{
GQueue trash = G_QUEUE_INIT;
@@ -427,23 +449,34 @@ static void
mail_account_store_constructed (GObject *object)
{
EMailAccountStore *store;
+ EMailSession *session;
+ ESourceRegistry *registry;
const gchar *config_dir;
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_mail_account_store_parent_class)->constructed (object);
store = E_MAIL_ACCOUNT_STORE (object);
+ session = e_mail_account_store_get_session (store);
+ registry = e_mail_session_get_registry (session);
+
+ /* Bind the default mail account ESource to our default
+ * CamelService, with help from some transform functions. */
+ g_object_bind_property_full (
+ registry, "default-mail-account",
+ store, "default-service",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ e_binding_transform_source_to_service,
+ e_binding_transform_service_to_source,
+ session, (GDestroyNotify) NULL);
+
config_dir = mail_session_get_config_dir ();
/* XXX Should we take the filename as a constructor property? */
store->priv->sort_order_filename = g_build_filename (
config_dir, "sortorder.ini", NULL);
- /* XXX This is kinda lame, but should work until EAccount dies. */
- g_signal_connect (
- object, "notify::default-service",
- G_CALLBACK (mail_account_store_save_default), NULL);
-
e_extensible_load_extensions (E_EXTENSIBLE (object));
}
@@ -458,94 +491,73 @@ static void
mail_account_store_service_removed (EMailAccountStore *store,
CamelService *service)
{
- /* XXX On the account-mgmt branch this operation is asynchronous.
- * The 'busy_count' is bumped until changes are written back
- * to the D-Bus service. For now I guess we'll just block. */
-
- EAccountList *account_list;
- EAccount *account;
EMailSession *session;
- MailFolderCache *cache;
- CamelProvider *provider;
+ ESourceRegistry *registry;
+ ESource *source;
const gchar *uid;
session = e_mail_account_store_get_session (store);
- cache = e_mail_session_get_folder_cache (session);
+ registry = e_mail_session_get_registry (session);
- mail_folder_cache_service_removed (cache, service);
-
- account_list = e_get_account_list ();
uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
- g_return_if_fail (account != NULL);
-
- /* no change */
- if (!account->enabled)
- return;
-
- provider = camel_service_get_provider (service);
- g_return_if_fail (provider != NULL);
-
- if (provider->flags & CAMEL_PROVIDER_IS_STORAGE)
- mail_disconnect_store (CAMEL_STORE (service));
+ source = e_source_registry_ref_source (registry, uid);
+
+ /* If this ESource is part of a collection, we need to remove
+ * the entire collection. Check the ESource and its ancestors
+ * for a collection extension and remove the containing source. */
+ if (source != NULL) {
+ ESource *collection;
+
+ collection = e_source_registry_find_extension (
+ registry, source, E_SOURCE_EXTENSION_COLLECTION);
+ if (collection != NULL) {
+ g_object_unref (source);
+ source = collection;
+ }
+ }
- /* Remove all the proxies the account has created.
- * FIXME This proxy stuff belongs in evolution-groupwise. */
- e_account_list_remove_account_proxies (account_list, account);
+ if (source != NULL) {
+ store->priv->busy_count++;
+ g_object_notify (G_OBJECT (store), "busy");
- e_account_list_remove (account_list, account);
+ /* XXX Should this be cancellable? */
+ e_source_remove (
+ source, NULL, (GAsyncReadyCallback)
+ mail_account_store_remove_source_cb,
+ g_object_ref (store));
- e_account_list_save (account_list);
+ g_object_unref (source);
+ }
}
static void
mail_account_store_service_enabled (EMailAccountStore *store,
CamelService *service)
{
- /* XXX On the account-mgmt branch this operation is asynchronous.
- * The 'busy_count' is bumped until changes are written back
- * to the D-Bus service. For now I guess we'll just block. */
-
EMailSession *session;
- MailFolderCache *cache;
- GSettings *settings;
+ ESourceRegistry *registry;
+ ESource *source;
const gchar *uid;
session = e_mail_account_store_get_session (store);
- cache = e_mail_session_get_folder_cache (session);
-
- mail_folder_cache_service_enabled (cache, service);
+ registry = e_mail_session_get_registry (session);
uid = camel_service_get_uid (service);
+ source = e_source_registry_ref_source (registry, uid);
- /* Handle built-in services that don't have an EAccount. */
+ if (source != NULL) {
+ e_source_set_enabled (source, TRUE);
- if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) {
- settings = g_settings_new ("org.gnome.evolution.mail");
- g_settings_set_boolean (settings, "enable-local", TRUE);
- g_object_unref (settings);
-
- } else if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
- settings = g_settings_new ("org.gnome.evolution.mail");
- g_settings_set_boolean (settings, "enable-vfolders", TRUE);
- g_object_unref (settings);
-
- } else {
- EAccountList *account_list;
- EAccount *account;
-
- account_list = e_get_account_list ();
- account = e_get_account_by_uid (uid);
- g_return_if_fail (account != NULL);
-
- /* no change */
- if (account->enabled)
- return;
+ store->priv->busy_count++;
+ g_object_notify (G_OBJECT (store), "busy");
- account->enabled = TRUE;
+ /* XXX Should this be cancellable? */
+ e_source_write (
+ source, NULL, (GAsyncReadyCallback)
+ mail_account_store_write_source_cb,
+ g_object_ref (store));
- e_account_list_change (account_list, account);
- e_account_list_save (account_list);
+ g_object_unref (source);
}
}
@@ -553,63 +565,30 @@ static void
mail_account_store_service_disabled (EMailAccountStore *store,
CamelService *service)
{
- /* XXX On the account-mgmt branch this operation is asynchronous.
- * The 'busy_count' is bumped until changes are written back
- * to the D-Bus service. For now I guess we'll just block. */
-
EMailSession *session;
- MailFolderCache *cache;
- GSettings *settings;
+ ESourceRegistry *registry;
+ ESource *source;
const gchar *uid;
session = e_mail_account_store_get_session (store);
- cache = e_mail_session_get_folder_cache (session);
-
- mail_folder_cache_service_disabled (cache, service);
+ registry = e_mail_session_get_registry (session);
uid = camel_service_get_uid (service);
+ source = e_source_registry_ref_source (registry, uid);
- /* Handle built-in services that don't have an EAccount. */
+ if (source != NULL) {
+ e_source_set_enabled (source, FALSE);
- if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0) {
- settings = g_settings_new ("org.gnome.evolution.mail");
- g_settings_set_boolean (settings, "enable-local", FALSE);
- g_object_unref (settings);
-
- } else if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0) {
- settings = g_settings_new ("org.gnome.evolution.mail");
- g_settings_set_boolean (settings, "enable-vfolders", FALSE);
- g_object_unref (settings);
-
- } else {
- EAccountList *account_list;
- EAccount *account;
- CamelProvider *provider;
+ store->priv->busy_count++;
+ g_object_notify (G_OBJECT (store), "busy");
- account_list = e_get_account_list ();
- account = e_get_account_by_uid (uid);
- g_return_if_fail (account != NULL);
+ /* XXX Should this be cancellable? */
+ e_source_write (
+ source, NULL, (GAsyncReadyCallback)
+ mail_account_store_write_source_cb,
+ g_object_ref (store));
- /* no change */
- if (!account->enabled)
- return;
-
- account->enabled = FALSE;
-
- provider = camel_service_get_provider (service);
- g_return_if_fail (provider != NULL);
-
- if (provider->flags & CAMEL_PROVIDER_IS_STORAGE)
- mail_disconnect_store (CAMEL_STORE (service));
-
- /* FIXME This proxy stuff belongs in evolution-groupwise. */
- e_account_list_remove_account_proxies (account_list, account);
-
- if (account->parent_uid != NULL)
- e_account_list_remove (account_list, account);
-
- e_account_list_change (account_list, account);
- e_account_list_save (account_list);
+ g_object_unref (source);
}
}
@@ -643,25 +622,14 @@ mail_account_store_remove_requested (EMailAccountStore *store,
GtkWindow *parent_window,
CamelService *service)
{
- EAccountList *account_list;
- EAccount *account;
- const gchar *alert;
- const gchar *uid;
gint response;
- account_list = e_get_account_list ();
- uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
-
- g_return_val_if_fail (account != NULL, FALSE);
+ /* FIXME Need to use "mail:ask-delete-account-with-proxies" if the
+ * mail account has proxies. But this is groupwise-specific
+ * and doesn't belong here anyway. Think of a better idea. */
- /* FIXME This proxy stuff belongs in evolution-groupwise. */
- if (e_account_list_account_has_proxies (account_list, account))
- alert = "mail:ask-delete-account-with-proxies";
- else
- alert = "mail:ask-delete-account";
-
- response = e_alert_run_dialog_for_args (parent_window, alert, NULL);
+ response = e_alert_run_dialog_for_args (
+ parent_window, "mail:ask-delete-account", NULL);
return (response == GTK_RESPONSE_YES);
}
@@ -679,34 +647,12 @@ mail_account_store_disable_requested (EMailAccountStore *store,
GtkWindow *parent_window,
CamelService *service)
{
- EAccountList *account_list;
- EAccount *account;
- const gchar *uid;
- gint response;
-
- account_list = e_get_account_list ();
- uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
-
- /* "On This Computer" and "Search Folders" do not have
- * EAccounts, so just silently return TRUE if we failed
- * to find a matching EAccount for the CamelService. */
-
- /* Silently return TRUE if we failed to find a matching
- * EAccount since "On This Computer" and "Search Folders"
- * do not have EAccounts. */
- if (account == NULL)
- return TRUE;
+ /* FIXME Need to check whether the account has proxies and run a
+ * "mail:ask-delete-proxy-accounts" alert dialog, but this
+ * is groupwise-specific and doesn't belong here anyway.
+ * Think of a better idea. */
- /* FIXME This proxy stuff belongs in evolution-groupwise. */
- if (e_account_list_account_has_proxies (account_list, account))
- response = e_alert_run_dialog_for_args (
- parent_window,
- "mail:ask-delete-proxy-accounts", NULL);
- else
- response = GTK_RESPONSE_YES;
-
- return (response == GTK_RESPONSE_YES);
+ return TRUE;
}
static void
@@ -1086,13 +1032,20 @@ e_mail_account_store_add_service (EMailAccountStore *store,
g_object_unref (settings);
} else {
- EAccount *account;
+ EMailSession *session;
+ ESourceRegistry *registry;
+ ESource *source;
+
+ session = e_mail_account_store_get_session (store);
- account = e_get_account_by_uid (uid);
- g_return_if_fail (account != NULL);
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_source (registry, uid);
+ g_return_if_fail (source != NULL);
builtin = FALSE;
- enabled = account->enabled;
+ enabled = e_source_get_enabled (source);
+
+ g_object_unref (source);
}
/* Where do we insert new services now that accounts can be
diff --git a/mail/e-mail-autoconfig.c b/mail/e-mail-autoconfig.c
new file mode 100644
index 0000000000..e3588a8964
--- /dev/null
+++ b/mail/e-mail-autoconfig.c
@@ -0,0 +1,883 @@
+/*
+ * e-mail-autoconfig.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-autoconfig.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+
+/* Stuff for DNS querying and message parsing. */
+#include <netdb.h>
+#include <netinet/in.h>
+#include <resolv.h>
+#include <arpa/nameser.h>
+#if defined(HAVE_ARPA_NAMESER_COMPAT_H) && !defined(GETSHORT)
+#include <arpa/nameser_compat.h>
+#endif
+
+/* For error codes. */
+#include <libsoup/soup.h>
+
+#include <libedataserver/e-source-camel.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-transport.h>
+
+#define E_MAIL_AUTOCONFIG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_AUTOCONFIG, EMailAutoconfigPrivate))
+
+#define AUTOCONFIG_BASE_URI \
+ "http://api.gnome.org/evolution/autoconfig/1.1/"
+
+/* XXX g_file_load_contents() on an "http://" URI returns error codes
+ * in the SOUP_HTTP_ERROR domain instead of the G_IO_ERROR domain.
+ * That is both undocumented and unexpected. */
+#define ERROR_IS_NOT_FOUND(error) \
+ (g_error_matches ((error), SOUP_HTTP_ERROR, SOUP_STATUS_NOT_FOUND))
+
+typedef struct _ParserClosure ParserClosure;
+typedef struct _ResolverClosure ResolverClosure;
+
+struct _EMailAutoconfigPrivate {
+ gchar *email_address;
+ gchar *email_local_part;
+ gchar *email_domain_part;
+ gchar *markup_content;
+};
+
+struct _ParserClosure {
+ CamelNetworkSettings *network_settings;
+ const gchar *expected_type;
+ const gchar *email_address;
+ const gchar *email_local_part;
+ const gchar *email_domain_part;
+ gboolean in_server_element;
+ gboolean settings_modified;
+};
+
+struct _ResolverClosure {
+ volatile gint ref_count;
+ GMainContext *main_context;
+ GMainLoop *main_loop;
+ gchar *domain_name;
+ gchar *name_server;
+ GError *error;
+};
+
+enum {
+ PROP_0,
+ PROP_EMAIL_ADDRESS
+};
+
+/* Forward Declarations */
+static void e_mail_autoconfig_initable_init (GInitableIface *interface);
+
+/* By default, the GAsyncInitable interface calls GInitable.init()
+ * from a separate thread, so we only have to override GInitable. */
+G_DEFINE_TYPE_WITH_CODE (
+ EMailAutoconfig,
+ e_mail_autoconfig,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_INITABLE, e_mail_autoconfig_initable_init)
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_ASYNC_INITABLE, NULL))
+
+static ResolverClosure *
+resolver_closure_new (const gchar *domain_name)
+{
+ ResolverClosure *closure;
+
+ closure = g_slice_new0 (ResolverClosure);
+ closure->domain_name = g_strdup (domain_name);
+ closure->main_context = g_main_context_new ();
+ closure->main_loop = g_main_loop_new (closure->main_context, FALSE);
+ closure->ref_count = 1;
+
+ return closure;
+}
+
+static ResolverClosure *
+resolver_closure_ref (ResolverClosure *closure)
+{
+ g_return_val_if_fail (closure != NULL, NULL);
+ g_return_val_if_fail (closure->ref_count > 0, NULL);
+
+ g_atomic_int_inc (&closure->ref_count);
+
+ return closure;
+}
+
+static void
+resolver_closure_unref (ResolverClosure *closure)
+{
+ g_return_if_fail (closure != NULL);
+ g_return_if_fail (closure->ref_count > 0);
+
+ if (g_atomic_int_dec_and_test (&closure->ref_count)) {
+ g_main_context_unref (closure->main_context);
+ g_main_loop_unref (closure->main_loop);
+ g_free (closure->domain_name);
+ g_free (closure->name_server);
+ g_clear_error (&closure->error);
+ g_slice_free (ResolverClosure, closure);
+ }
+}
+
+static gboolean
+mail_autoconfig_resolver_idle_quit (gpointer user_data)
+{
+ GMainLoop *main_loop = user_data;
+
+ g_main_loop_quit (main_loop);
+
+ return FALSE;
+}
+
+static void
+mail_autoconfig_resolver_cancelled (GCancellable *cancellable,
+ ResolverClosure *closure)
+{
+ GSource *source;
+
+ source = g_idle_source_new ();
+ g_source_set_callback (
+ source,
+ mail_autoconfig_resolver_idle_quit,
+ g_main_loop_ref (closure->main_loop),
+ (GDestroyNotify) g_main_loop_unref);
+ g_source_attach (source, closure->main_context);
+ g_source_unref (source);
+}
+
+static gpointer
+mail_autoconfig_resolver_thread (gpointer user_data)
+{
+ ResolverClosure *closure = user_data;
+ HEADER *header;
+ guchar answer[1024];
+ gchar namebuf[1024];
+ guchar *end, *cp;
+ gint count;
+ gint length;
+ gint herr;
+
+ /* Query DNS for the MX record for the domain name given in the
+ * email address. We need an authoritative name server for it. */
+
+ length = res_query (
+ closure->domain_name, C_IN, T_MX,
+ answer, sizeof (answer));
+ herr = h_errno; /* h_errno is defined in <netdb.h> */
+
+ /* Based heavily on _g_resolver_targets_from_res_query().
+ * The binary DNS message format is described in RFC 1035. */
+
+ if (length <= 0) {
+ if (length == 0 || herr == HOST_NOT_FOUND || herr == NO_DATA)
+ g_set_error (
+ &closure->error,
+ G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_NOT_FOUND,
+ _("No mail exchanger record for '%s'"),
+ closure->domain_name);
+ else if (herr == TRY_AGAIN)
+ g_set_error (
+ &closure->error,
+ G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_TEMPORARY_FAILURE,
+ _("Temporarily unable to resolve '%s'"),
+ closure->domain_name);
+ else
+ g_set_error (
+ &closure->error,
+ G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_INTERNAL,
+ _("Error resolving '%s'"),
+ closure->domain_name);
+ goto exit;
+ }
+
+ header = (HEADER *) answer;
+ cp = answer + sizeof (HEADER);
+ end = answer + length;
+
+ /* Skip the 'question' section. */
+ count = ntohs (header->qdcount);
+ while (count-- && cp < end) {
+ cp += dn_expand (answer, end, cp, namebuf, sizeof (namebuf));
+ cp += 2; /* skip QTYPE */
+ cp += 2; /* skip QCLASS */
+ }
+
+ /* Skip the 'answers' section. */
+ count = ntohs (header->ancount);
+ while (count-- && cp < end) {
+ guint16 rdlength;
+ cp += dn_expand (answer, end, cp, namebuf, sizeof (namebuf));
+ cp += 2; /* skip TYPE */
+ cp += 2; /* skip CLASS */
+ cp += 4; /* skip TTL */
+ GETSHORT (rdlength, cp); /* read RDLENGTH */
+ cp += rdlength; /* skip RDATA */
+ }
+
+ /* Read the 'authority' section. */
+ count = ntohs (header->nscount);
+ while (count-- && cp < end) {
+ guint16 type, qclass, rdlength;
+ cp += dn_expand (answer, end, cp, namebuf, sizeof (namebuf));
+ GETSHORT (type, cp);
+ GETSHORT (qclass, cp);
+ cp += 4; /* skip TTL */
+ GETSHORT (rdlength, cp);
+
+ if (type != T_NS || qclass != C_IN) {
+ cp += rdlength;
+ continue;
+ }
+
+ cp += dn_expand (answer, end, cp, namebuf, sizeof (namebuf));
+
+ /* Pick the first T_NS record we find. */
+ closure->name_server = g_strdup (namebuf);
+ break;
+ }
+
+ if (closure->name_server == NULL)
+ g_set_error (
+ &closure->error,
+ G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_NOT_FOUND,
+ _("No authoritative name server for '%s'"),
+ closure->domain_name);
+
+exit:
+ g_main_loop_quit (closure->main_loop);
+ resolver_closure_unref (closure);
+
+ return NULL; /* return value is not used */
+}
+
+static gchar *
+mail_autoconfig_resolve_authority (const gchar *domain,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ResolverClosure *closure;
+ GThread *resolver_thread;
+ gchar *name_server = NULL;
+ gulong cancel_id = 0;
+
+ closure = resolver_closure_new (domain);
+
+ /* DNS record lookup is not cancellable, so we run it in a
+ * separate thread. We don't join with the thread, however,
+ * because if we get cancelled we want to return immediately.
+ * So use a reference count on the thread closure and always
+ * let the thread run to completion even if we're not around
+ * any longer to pick up the result. */
+ resolver_thread = g_thread_create (
+ mail_autoconfig_resolver_thread,
+ resolver_closure_ref (closure),
+ FALSE /* not joinable */, error);
+
+ if (resolver_thread == NULL)
+ return FALSE;
+
+ if (G_IS_CANCELLABLE (cancellable))
+ cancel_id = g_cancellable_connect (
+ cancellable,
+ G_CALLBACK (mail_autoconfig_resolver_cancelled),
+ resolver_closure_ref (closure),
+ (GDestroyNotify) resolver_closure_unref);
+
+ g_main_loop_run (closure->main_loop);
+
+ if (cancel_id > 0)
+ g_cancellable_disconnect (cancellable, cancel_id);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
+ /* do nothing */
+
+ } else if (closure->error != NULL) {
+ g_warn_if_fail (closure->name_server == NULL);
+ g_propagate_error (error, closure->error);
+ closure->error = NULL;
+
+ } else {
+ g_warn_if_fail (closure->name_server != NULL);
+ name_server = closure->name_server;
+ closure->name_server = NULL;
+ }
+
+ resolver_closure_unref (closure);
+
+ return name_server;
+}
+
+static gboolean
+mail_autoconfig_lookup (EMailAutoconfig *autoconfig,
+ const gchar *domain,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GFile *file;
+ gchar *uri;
+ gboolean success;
+
+ uri = g_strconcat (AUTOCONFIG_BASE_URI, domain, NULL);
+ file = g_file_new_for_uri (uri);
+ g_free (uri);
+
+ /* Just to make sure we don't leak. */
+ g_free (autoconfig->priv->markup_content);
+ autoconfig->priv->markup_content = NULL;
+
+ success = g_file_load_contents (
+ file, cancellable,
+ &autoconfig->priv->markup_content,
+ NULL, NULL, error);
+
+ g_object_unref (file);
+
+ return success;
+}
+
+static void
+mail_autoconfig_parse_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ParserClosure *closure = user_data;
+ gboolean is_incoming_server;
+ gboolean is_outgoing_server;
+
+ is_incoming_server = g_str_equal (element_name, "incomingServer");
+ is_outgoing_server = g_str_equal (element_name, "outgoingServer");
+
+ if (is_incoming_server || is_outgoing_server) {
+ const gchar *type = NULL;
+
+ g_markup_collect_attributes (
+ element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING,
+ "type", &type,
+ G_MARKUP_COLLECT_INVALID);
+
+ closure->in_server_element =
+ (g_strcmp0 (type, closure->expected_type) == 0);
+ }
+}
+
+static void
+mail_autoconfig_parse_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParserClosure *closure = user_data;
+ gboolean is_incoming_server;
+ gboolean is_outgoing_server;
+
+ is_incoming_server = g_str_equal (element_name, "incomingServer");
+ is_outgoing_server = g_str_equal (element_name, "outgoingServer");
+
+ if (is_incoming_server || is_outgoing_server)
+ closure->in_server_element = FALSE;
+}
+
+static void
+mail_autoconfig_parse_text (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_length,
+ gpointer user_data,
+ GError **error)
+{
+ ParserClosure *closure = user_data;
+ const gchar *element_name;
+ GString *string;
+
+ if (!closure->in_server_element)
+ return;
+
+ /* Perform the following text substitutions:
+ *
+ * %EMAILADDRESS% : closure->email_address
+ * %EMAILLOCALPART% : closure->email_local_part
+ * %EMAILDOMAIN% : closure->email_domain_part
+ */
+ if (strchr (text, '%') == NULL)
+ string = g_string_new (text);
+ else {
+ const gchar *cp = text;
+
+ string = g_string_sized_new (256);
+ while (*cp != '\0') {
+ const gchar *variable;
+ const gchar *substitute;
+
+ if (*cp != '%') {
+ g_string_append_c (string, *cp++);
+ continue;
+ }
+
+ variable = "%EMAILADDRESS%";
+ substitute = closure->email_address;
+
+ if (strncmp (cp, variable, strlen (variable)) == 0) {
+ g_string_append (string, substitute);
+ cp += strlen (variable);
+ continue;
+ }
+
+ variable = "%EMAILLOCALPART%";
+ substitute = closure->email_local_part;
+
+ if (strncmp (cp, variable, strlen (variable)) == 0) {
+ g_string_append (string, substitute);
+ cp += strlen (variable);
+ continue;
+ }
+
+ variable = "%EMAILDOMAIN%";
+ substitute = closure->email_domain_part;
+
+ if (strncmp (cp, variable, strlen (variable)) == 0) {
+ g_string_append (string, substitute);
+ cp += strlen (variable);
+ continue;
+ }
+
+ g_string_append_c (string, *cp++);
+ }
+ }
+
+ element_name = g_markup_parse_context_get_element (context);
+
+ if (g_str_equal (element_name, "hostname")) {
+ camel_network_settings_set_host (
+ closure->network_settings, string->str);
+ closure->settings_modified = TRUE;
+
+ } else if (g_str_equal (element_name, "username")) {
+ camel_network_settings_set_user (
+ closure->network_settings, string->str);
+ closure->settings_modified = TRUE;
+
+ } else if (g_str_equal (element_name, "port")) {
+ glong port = strtol (string->str, NULL, 10);
+ if (port == CLAMP (port, 1, G_MAXUINT16)) {
+ camel_network_settings_set_port (
+ closure->network_settings, (guint16) port);
+ closure->settings_modified = TRUE;
+ }
+
+ } else if (g_str_equal (element_name, "socketType")) {
+ if (g_str_equal (string->str, "plain")) {
+ camel_network_settings_set_security_method (
+ closure->network_settings,
+ CAMEL_NETWORK_SECURITY_METHOD_NONE);
+ closure->settings_modified = TRUE;
+ } else if (g_str_equal (string->str, "SSL")) {
+ camel_network_settings_set_security_method (
+ closure->network_settings,
+ CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT);
+ closure->settings_modified = TRUE;
+ } else if (g_str_equal (string->str, "STARTTLS")) {
+ camel_network_settings_set_security_method (
+ closure->network_settings,
+ CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT);
+ closure->settings_modified = TRUE;
+ }
+ }
+
+ /* FIXME Not handling <authentication> elements.
+ * Unclear how some map to SASL mechanisms. */
+
+ g_string_free (string, TRUE);
+}
+
+static GMarkupParser mail_autoconfig_parser = {
+ mail_autoconfig_parse_start_element,
+ mail_autoconfig_parse_end_element,
+ mail_autoconfig_parse_text
+};
+
+static gboolean
+mail_autoconfig_set_details (EMailAutoconfig *autoconfig,
+ const gchar *expected_type,
+ ESource *source,
+ const gchar *extension_name)
+{
+ GMarkupParseContext *context;
+ ESourceCamel *camel_ext;
+ ESourceBackend *backend_ext;
+ CamelSettings *settings;
+ ParserClosure closure;
+ const gchar *backend_name;
+ const gchar *markup_content;
+ gboolean success;
+
+ if (!e_source_has_extension (source, extension_name))
+ return FALSE;
+
+ backend_ext = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (backend_ext);
+ extension_name = e_source_camel_get_extension_name (backend_name);
+ camel_ext = e_source_get_extension (source, extension_name);
+
+ settings = e_source_camel_get_settings (camel_ext);
+ g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), FALSE);
+
+ markup_content = e_mail_autoconfig_get_markup_content (autoconfig);
+ g_return_val_if_fail (markup_content != NULL, FALSE);
+
+ closure.network_settings = CAMEL_NETWORK_SETTINGS (settings);
+ closure.expected_type = expected_type;
+ closure.in_server_element = FALSE;
+ closure.settings_modified = FALSE;
+
+ /* These are used for text substitutions. */
+ closure.email_address = autoconfig->priv->email_address;
+ closure.email_local_part = autoconfig->priv->email_local_part;
+ closure.email_domain_part = autoconfig->priv->email_domain_part;
+
+ context = g_markup_parse_context_new (
+ &mail_autoconfig_parser, 0, &closure, (GDestroyNotify) NULL);
+
+ success = g_markup_parse_context_parse (
+ context, markup_content, strlen (markup_content), NULL);
+
+ success &= g_markup_parse_context_end_parse (context, NULL);
+
+ /* Did we actually configure anything? */
+ success &= closure.settings_modified;
+
+ g_markup_parse_context_free (context);
+
+ return success;
+}
+
+static void
+mail_autoconfig_set_email_address (EMailAutoconfig *autoconfig,
+ const gchar *email_address)
+{
+ g_return_if_fail (email_address != NULL);
+ g_return_if_fail (autoconfig->priv->email_address == NULL);
+
+ autoconfig->priv->email_address = g_strdup (email_address);
+}
+
+static void
+mail_autoconfig_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_EMAIL_ADDRESS:
+ mail_autoconfig_set_email_address (
+ E_MAIL_AUTOCONFIG (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_autoconfig_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_EMAIL_ADDRESS:
+ g_value_set_string (
+ value,
+ e_mail_autoconfig_get_email_address (
+ E_MAIL_AUTOCONFIG (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_autoconfig_finalize (GObject *object)
+{
+ EMailAutoconfigPrivate *priv;
+
+ priv = E_MAIL_AUTOCONFIG_GET_PRIVATE (object);
+
+ g_free (priv->email_address);
+ g_free (priv->email_local_part);
+ g_free (priv->email_domain_part);
+ g_free (priv->markup_content);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_autoconfig_parent_class)->finalize (object);
+}
+
+static gboolean
+mail_autoconfig_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EMailAutoconfig *autoconfig;
+ const gchar *email_address;
+ const gchar *domain;
+ const gchar *cp;
+ gchar *name_server;
+ gboolean success = FALSE;
+ GError *local_error = NULL;
+
+ autoconfig = E_MAIL_AUTOCONFIG (initable);
+ email_address = e_mail_autoconfig_get_email_address (autoconfig);
+
+ if (email_address == NULL) {
+ g_set_error_literal (
+ error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("No email address provided"));
+ return FALSE;
+ }
+
+ cp = strchr (email_address, '@');
+ if (cp == NULL) {
+ g_set_error_literal (
+ error, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Missing domain in email address"));
+ return FALSE;
+ }
+
+ domain = cp + 1;
+
+ autoconfig->priv->email_local_part =
+ g_strndup (email_address, cp - email_address);
+ autoconfig->priv->email_domain_part = g_strdup (domain);
+
+ /* First try the email address domain verbatim. */
+ success = mail_autoconfig_lookup (
+ autoconfig, domain, cancellable, &local_error);
+
+ g_warn_if_fail (
+ (success && local_error == NULL) ||
+ (!success && local_error != NULL));
+
+ if (success)
+ return TRUE;
+
+ /* "404 Not Found" errors are non-fatal this time around. */
+ if (ERROR_IS_NOT_FOUND (local_error)) {
+ g_clear_error (&local_error);
+ } else {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ /* Look up an authoritative name server for the email address
+ * domain according to its "mail exchanger" (MX) DNS record. */
+ name_server = mail_autoconfig_resolve_authority (
+ domain, cancellable, error);
+
+ if (name_server == NULL)
+ return FALSE;
+
+ /* Widdle away segments of the name server domain until
+ * we find a match, or until we widdle down to nothing. */
+
+ cp = name_server;
+ while (cp != NULL && strchr (cp, '.') != NULL) {
+ g_clear_error (&local_error);
+
+ success = mail_autoconfig_lookup (
+ autoconfig, cp, cancellable, &local_error);
+
+ g_warn_if_fail (
+ (success && local_error == NULL) ||
+ (!success && local_error != NULL));
+
+ if (success || !ERROR_IS_NOT_FOUND (local_error))
+ break;
+
+ cp = strchr (cp, '.');
+ if (cp != NULL)
+ cp++;
+ }
+
+ if (local_error != NULL)
+ g_propagate_error (error, local_error);
+
+ g_free (name_server);
+
+ return success;
+}
+
+static void
+e_mail_autoconfig_class_init (EMailAutoconfigClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailAutoconfigPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_autoconfig_set_property;
+ object_class->get_property = mail_autoconfig_get_property;
+ object_class->finalize = mail_autoconfig_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EMAIL_ADDRESS,
+ g_param_spec_string (
+ "email-address",
+ "Email Address",
+ "The address from which to query config data",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_autoconfig_initable_init (GInitableIface *interface)
+{
+ interface->init = mail_autoconfig_initable_init;
+}
+
+static void
+e_mail_autoconfig_init (EMailAutoconfig *autoconfig)
+{
+ autoconfig->priv = E_MAIL_AUTOCONFIG_GET_PRIVATE (autoconfig);
+}
+
+EMailAutoconfig *
+e_mail_autoconfig_new_sync (const gchar *email_address,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (email_address != NULL, NULL);
+
+ return g_initable_new (
+ E_TYPE_MAIL_AUTOCONFIG,
+ cancellable, error,
+ "email-address", email_address,
+ NULL);
+}
+
+void
+e_mail_autoconfig_new (const gchar *email_address,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (email_address != NULL);
+
+ g_async_initable_new_async (
+ E_TYPE_MAIL_AUTOCONFIG,
+ io_priority, cancellable,
+ callback, user_data,
+ "email-address", email_address,
+ NULL);
+}
+
+EMailAutoconfig *
+e_mail_autoconfig_finish (GAsyncResult *result,
+ GError **error)
+{
+ GObject *source_object;
+ GObject *autoconfig;
+
+ g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+
+ source_object = g_async_result_get_source_object (result);
+ g_return_val_if_fail (source_object != NULL, NULL);
+
+ autoconfig = g_async_initable_new_finish (
+ G_ASYNC_INITABLE (source_object), result, error);
+
+ g_object_unref (source_object);
+
+ if (autoconfig == NULL)
+ return NULL;
+
+ return E_MAIL_AUTOCONFIG (autoconfig);
+}
+
+const gchar *
+e_mail_autoconfig_get_email_address (EMailAutoconfig *autoconfig)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), NULL);
+
+ return autoconfig->priv->email_address;
+}
+
+const gchar *
+e_mail_autoconfig_get_markup_content (EMailAutoconfig *autoconfig)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), NULL);
+
+ return autoconfig->priv->markup_content;
+}
+
+gboolean
+e_mail_autoconfig_set_imap_details (EMailAutoconfig *autoconfig,
+ ESource *imap_source)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), FALSE);
+ g_return_val_if_fail (E_IS_SOURCE (imap_source), FALSE);
+
+ return mail_autoconfig_set_details (
+ autoconfig, "imap", imap_source,
+ E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+}
+
+gboolean
+e_mail_autoconfig_set_pop3_details (EMailAutoconfig *autoconfig,
+ ESource *pop3_source)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), FALSE);
+ g_return_val_if_fail (E_IS_SOURCE (pop3_source), FALSE);
+
+ return mail_autoconfig_set_details (
+ autoconfig, "pop3", pop3_source,
+ E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+}
+
+gboolean
+e_mail_autoconfig_set_smtp_details (EMailAutoconfig *autoconfig,
+ ESource *smtp_source)
+{
+ g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), FALSE);
+ g_return_val_if_fail (E_IS_SOURCE (smtp_source), FALSE);
+
+ return mail_autoconfig_set_details (
+ autoconfig, "smtp", smtp_source,
+ E_SOURCE_EXTENSION_MAIL_TRANSPORT);
+}
+
diff --git a/mail/e-mail-autoconfig.h b/mail/e-mail-autoconfig.h
new file mode 100644
index 0000000000..5b03ace7a3
--- /dev/null
+++ b/mail/e-mail-autoconfig.h
@@ -0,0 +1,89 @@
+/*
+ * e-mail-autoconfig.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_AUTOCONFIG_H
+#define E_MAIL_AUTOCONFIG_H
+
+#include <gio/gio.h>
+#include <libedataserver/e-source.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_AUTOCONFIG \
+ (e_mail_autoconfig_get_type ())
+#define E_MAIL_AUTOCONFIG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_AUTOCONFIG, EMailAutoconfig))
+#define E_MAIL_AUTOCONFIG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_AUTOCONFIG, EMailAutoconfigClass))
+#define E_IS_MAIL_AUTOCONFIG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_AUTOCONFIG))
+#define E_IS_MAIL_AUTOCONFIG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_AUTOCONFIG))
+#define E_MAIL_AUTOCONFIG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_AUTOCONFIG, EMailAutoconfigClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAutoconfig EMailAutoconfig;
+typedef struct _EMailAutoconfigClass EMailAutoconfigClass;
+typedef struct _EMailAutoconfigPrivate EMailAutoconfigPrivate;
+
+struct _EMailAutoconfig {
+ GObject parent;
+ EMailAutoconfigPrivate *priv;
+};
+
+struct _EMailAutoconfigClass {
+ GObjectClass parent_class;
+};
+
+GType e_mail_autoconfig_get_type (void) G_GNUC_CONST;
+EMailAutoconfig *
+ e_mail_autoconfig_new_sync (const gchar *email_address,
+ GCancellable *cancellable,
+ GError **error);
+void e_mail_autoconfig_new (const gchar *email_address,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+EMailAutoconfig *
+ e_mail_autoconfig_finish (GAsyncResult *result,
+ GError **error);
+const gchar * e_mail_autoconfig_get_email_address
+ (EMailAutoconfig *autoconfig);
+const gchar * e_mail_autoconfig_get_markup_content
+ (EMailAutoconfig *autoconfig);
+gboolean e_mail_autoconfig_set_imap_details
+ (EMailAutoconfig *autoconfig,
+ ESource *imap_source);
+gboolean e_mail_autoconfig_set_pop3_details
+ (EMailAutoconfig *autoconfig,
+ ESource *pop3_source);
+gboolean e_mail_autoconfig_set_smtp_details
+ (EMailAutoconfig *autoconfig,
+ ESource *smtp_source);
+
+G_END_DECLS
+
+#endif /* E_MAIL_AUTOCONFIG_H */
+
diff --git a/mail/e-mail-backend.c b/mail/e-mail-backend.c
index c350bd7b5d..60e506d09d 100644
--- a/mail/e-mail-backend.c
+++ b/mail/e-mail-backend.c
@@ -32,15 +32,15 @@
#include <glib/gstdio.h>
#include <glib/gi18n-lib.h>
#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-submission.h>
#include <shell/e-shell.h>
#include <libevolution-utils/e-alert-dialog.h>
#include <libevolution-utils/e-alert-sink.h>
-#include <misc/e-account-combo-box.h>
-
-#include <libemail-utils/e-account-utils.h>
#include <libemail-engine/e-mail-folder-utils.h>
#include <libemail-engine/e-mail-session.h>
#include <libemail-engine/e-mail-store-utils.h>
@@ -141,11 +141,14 @@ mail_backend_prepare_for_offline_cb (EShell *shell,
{
GtkWindow *window;
EMailSession *session;
+ ESourceRegistry *registry;
GList *list, *link;
+ const gchar *extension_name;
gboolean synchronize = FALSE;
window = e_shell_get_active_window (shell);
session = e_mail_backend_get_session (backend);
+ registry = e_mail_session_get_registry (session);
if (e_shell_get_network_available (shell) &&
e_shell_backend_is_started (E_SHELL_BACKEND (backend)))
@@ -158,12 +161,17 @@ mail_backend_prepare_for_offline_cb (EShell *shell,
CAMEL_SESSION (session), FALSE);
}
- list = camel_session_list_services (CAMEL_SESSION (session));
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
CamelService *service;
+ const gchar *uid;
- service = CAMEL_SERVICE (link->data);
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), uid);
if (!CAMEL_IS_STORE (service))
continue;
@@ -176,7 +184,7 @@ mail_backend_prepare_for_offline_cb (EShell *shell,
g_object_ref (activity));
}
- g_list_free (list);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
}
static void
@@ -185,27 +193,31 @@ mail_backend_prepare_for_online_cb (EShell *shell,
EMailBackend *backend)
{
EMailSession *session;
+ ESourceRegistry *registry;
GList *list, *link;
+ const gchar *extension_name;
session = e_mail_backend_get_session (backend);
+ registry = e_mail_session_get_registry (session);
+
camel_session_set_online (CAMEL_SESSION (session), TRUE);
- list = camel_session_list_services (CAMEL_SESSION (session));
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
CamelService *service;
- EAccount *account;
const gchar *uid;
- service = CAMEL_SERVICE (link->data);
-
- if (!CAMEL_IS_STORE (service))
+ if (!e_source_get_enabled (source))
continue;
- uid = camel_service_get_uid (service);
- account = e_get_account_by_uid (uid);
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (
+ CAMEL_SESSION (session), uid);
- if (account != NULL && !account->enabled)
+ if (!CAMEL_IS_STORE (service))
continue;
/* FIXME Not passing a GCancellable. */
@@ -216,7 +228,7 @@ mail_backend_prepare_for_online_cb (EShell *shell,
g_object_ref (activity));
}
- g_list_free (link);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
}
/* Helper for mail_backend_prepare_for_quit_cb() */
@@ -273,7 +285,6 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
EActivity *activity,
EMailBackend *backend)
{
- EAccountList *account_list;
EMailSession *session;
GList *list, *link;
gboolean delete_junk;
@@ -286,9 +297,6 @@ mail_backend_prepare_for_quit_cb (EShell *shell,
camel_application_is_exiting = TRUE;
- account_list = e_get_account_list ();
- e_account_list_prune_proxies (account_list);
-
mail_vfolder_shutdown ();
/* Cancel all pending activities. */
@@ -399,20 +407,26 @@ mail_backend_folder_deleted_cb (MailFolderCache *folder_cache,
const gchar *folder_name,
EMailBackend *backend)
{
+ EShell *shell;
CamelStoreClass *class;
- EAccountList *account_list;
- EIterator *iterator;
+ ESourceRegistry *registry;
+ EShellBackend *shell_backend;
EMailSession *session;
EAlertSink *alert_sink;
+ GList *list, *link;
+ const gchar *extension_name;
const gchar *local_drafts_folder_uri;
const gchar *local_sent_folder_uri;
- gboolean write_config = FALSE;
gchar *uri;
/* Check whether the deleted folder was a designated Drafts or
* Sent folder for any mail account, and if so revert the setting
* to the equivalent local folder, which is always present. */
+ shell_backend = E_SHELL_BACKEND (backend);
+ shell = e_shell_backend_get_shell (shell_backend);
+ registry = e_shell_get_registry (shell);
+
class = CAMEL_STORE_GET_CLASS (store);
g_return_if_fail (class->compare_folder_name != NULL);
@@ -429,51 +443,69 @@ mail_backend_folder_deleted_cb (MailFolderCache *folder_cache,
uri = e_mail_folder_uri_build (store, folder_name);
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ list = e_source_registry_list_sources (registry, extension_name);
- while (e_iterator_is_valid (iterator)) {
- EAccount *account;
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceExtension *extension;
+ const gchar *drafts_folder_uri;
+
+ extension = e_source_get_extension (source, extension_name);
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
+ drafts_folder_uri =
+ e_source_mail_composition_get_drafts_folder (
+ E_SOURCE_MAIL_COMPOSITION (extension));
- if (account->sent_folder_uri != NULL) {
- gboolean match;
+ if (class->compare_folder_name (drafts_folder_uri, uri)) {
+ GError *error = NULL;
- match = class->compare_folder_name (
- account->sent_folder_uri, uri);
+ e_source_mail_composition_set_drafts_folder (
+ E_SOURCE_MAIL_COMPOSITION (extension),
+ local_drafts_folder_uri);
- if (match) {
- g_free (account->sent_folder_uri);
- account->sent_folder_uri =
- g_strdup (local_sent_folder_uri);
- write_config = TRUE;
+ /* FIXME This is a blocking D-Bus method call. */
+ if (!e_source_write_sync (source, NULL, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
}
+ }
- if (account->drafts_folder_uri != NULL) {
- gboolean match;
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
- match = class->compare_folder_name (
- account->drafts_folder_uri, uri);
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ list = e_source_registry_list_sources (registry, extension_name);
- if (match) {
- g_free (account->drafts_folder_uri);
- account->drafts_folder_uri =
- g_strdup (local_drafts_folder_uri);
- write_config = TRUE;
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceExtension *extension;
+ const gchar *sent_folder_uri;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ sent_folder_uri =
+ e_source_mail_submission_get_sent_folder (
+ E_SOURCE_MAIL_SUBMISSION (extension));
+
+ if (class->compare_folder_name (sent_folder_uri, uri)) {
+ GError *error = NULL;
+
+ e_source_mail_submission_set_sent_folder (
+ E_SOURCE_MAIL_SUBMISSION (extension),
+ local_sent_folder_uri);
+
+ /* FIXME This is a blocking D-Bus method call. */
+ if (!e_source_write_sync (source, NULL, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
}
-
- e_iterator_next (iterator);
}
- g_object_unref (iterator);
- g_free (uri);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
- if (write_config)
- mail_config_write ();
+ g_free (uri);
/* This does something completely different.
* XXX Make it a separate signal handler? */
@@ -487,10 +519,12 @@ mail_backend_folder_renamed_cb (MailFolderCache *folder_cache,
const gchar *new_folder_name,
EMailBackend *backend)
{
+ EShell *shell;
CamelStoreClass *class;
- EAccountList *account_list;
- EIterator *iterator;
- gboolean write_config = FALSE;
+ ESourceRegistry *registry;
+ EShellBackend *shell_backend;
+ GList *list, *link;
+ const gchar *extension_name;
gchar *old_uri;
gchar *new_uri;
gint ii;
@@ -500,54 +534,84 @@ mail_backend_folder_renamed_cb (MailFolderCache *folder_cache,
"views/custom_view-"
};
+ /* Check whether the renamed folder was a designated Drafts or
+ * Sent folder for any mail account, and if so update the setting
+ * to the new folder name. */
+
+ shell_backend = E_SHELL_BACKEND (backend);
+ shell = e_shell_backend_get_shell (shell_backend);
+ registry = e_shell_get_registry (shell);
+
class = CAMEL_STORE_GET_CLASS (store);
g_return_if_fail (class->compare_folder_name != NULL);
old_uri = e_mail_folder_uri_build (store, old_folder_name);
new_uri = e_mail_folder_uri_build (store, new_folder_name);
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceExtension *extension;
+ const gchar *drafts_folder_uri;
- while (e_iterator_is_valid (iterator)) {
- EAccount *account;
+ extension = e_source_get_extension (source, extension_name);
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
+ drafts_folder_uri =
+ e_source_mail_composition_get_drafts_folder (
+ E_SOURCE_MAIL_COMPOSITION (extension));
- if (account->sent_folder_uri != NULL) {
- gboolean match;
+ if (class->compare_folder_name (drafts_folder_uri, old_uri)) {
+ GError *error = NULL;
- match = class->compare_folder_name (
- account->sent_folder_uri, old_uri);
+ e_source_mail_composition_set_drafts_folder (
+ E_SOURCE_MAIL_COMPOSITION (extension),
+ new_uri);
- if (match) {
- g_free (account->sent_folder_uri);
- account->sent_folder_uri = g_strdup (new_uri);
- write_config = TRUE;
+ /* FIXME This is a blocking D-Bus method call. */
+ if (!e_source_write_sync (source, NULL, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
}
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
- if (account->drafts_folder_uri != NULL) {
- gboolean match;
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ list = e_source_registry_list_sources (registry, extension_name);
- match = class->compare_folder_name (
- account->drafts_folder_uri, old_uri);
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceExtension *extension;
+ const gchar *sent_folder_uri;
- if (match) {
- g_free (account->drafts_folder_uri);
- account->drafts_folder_uri = g_strdup (new_uri);
- write_config = TRUE;
+ extension = e_source_get_extension (source, extension_name);
+
+ sent_folder_uri =
+ e_source_mail_submission_get_sent_folder (
+ E_SOURCE_MAIL_SUBMISSION (extension));
+
+ if (class->compare_folder_name (sent_folder_uri, old_uri)) {
+ GError *error = NULL;
+
+ e_source_mail_submission_set_sent_folder (
+ E_SOURCE_MAIL_SUBMISSION (extension),
+ new_uri);
+
+ /* FIXME This is a blocking D-Bus method call. */
+ if (!e_source_write_sync (source, NULL, &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
}
-
- e_iterator_next (iterator);
}
- g_object_unref (iterator);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
- if (write_config)
- mail_config_write ();
+ g_free (old_uri);
+ g_free (new_uri);
/* Rename GalView files. */
@@ -565,9 +629,6 @@ mail_backend_folder_renamed_cb (MailFolderCache *folder_cache,
g_free (newname);
}
- g_free (old_uri);
- g_free (new_uri);
-
/* This does something completely different.
* XXX Make it a separate signal handler? */
mail_filter_rename_folder (
@@ -606,10 +667,8 @@ mail_backend_folder_changed_cb (MailFolderCache *folder_cache,
g_object_unref (folder);
}
- g_free (folder_uri);
-
target = em_event_target_new_folder (
- event, store, folder_name, new_messages,
+ event, store, folder_uri, new_messages,
msg_uid, msg_sender, msg_subject);
folder_type = (flags & CAMEL_FOLDER_TYPE_MASK);
@@ -939,6 +998,7 @@ mail_backend_constructed (GObject *object)
EShell *shell;
EShellBackend *shell_backend;
MailFolderCache *folder_cache;
+ ESourceRegistry *registry;
priv = E_MAIL_BACKEND_GET_PRIVATE (object);
@@ -948,9 +1008,8 @@ mail_backend_constructed (GObject *object)
if (camel_init (e_get_user_data_dir (), TRUE) != 0)
exit (0);
- camel_provider_init ();
-
- priv->session = e_mail_ui_session_new ();
+ registry = e_shell_get_registry (shell);
+ priv->session = e_mail_ui_session_new (registry);
g_signal_connect (
priv->session, "flush-outbox",
@@ -978,10 +1037,6 @@ mail_backend_constructed (GObject *object)
G_CALLBACK (mail_backend_job_finished_cb),
shell_backend);
- /* FIXME This is an evil hack that needs to die.
- * Give EAccountComboBox a CamelSession property. */
- e_account_combo_box_set_session (CAMEL_SESSION (priv->session));
-
g_signal_connect (
priv->session, "store-added",
G_CALLBACK (mail_backend_add_store),
@@ -1029,7 +1084,6 @@ mail_backend_constructed (GObject *object)
G_CALLBACK (mail_backend_folder_changed_cb), shell_backend);
mail_config_init (priv->session);
- mail_msg_init ();
mail_msg_register_activities (
mail_mt_create_activity,
diff --git a/mail/e-mail-config-assistant.c b/mail/e-mail-config-assistant.c
new file mode 100644
index 0000000000..e81a1980ce
--- /dev/null
+++ b/mail/e-mail-config-assistant.c
@@ -0,0 +1,1157 @@
+/*
+ * e-mail-config-assistant.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-assistant.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-source-mail-transport.h>
+
+#include <libevolution-utils/e-alert-sink.h>
+
+#include <mail/e-mail-config-confirm-page.h>
+#include <mail/e-mail-config-identity-page.h>
+#include <mail/e-mail-config-lookup-page.h>
+#include <mail/e-mail-config-provider-page.h>
+#include <mail/e-mail-config-receiving-page.h>
+#include <mail/e-mail-config-sending-page.h>
+#include <mail/e-mail-config-summary-page.h>
+#include <mail/e-mail-config-welcome-page.h>
+
+#define E_MAIL_CONFIG_ASSISTANT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_ASSISTANT, EMailConfigAssistantPrivate))
+
+struct _EMailConfigAssistantPrivate {
+ EMailSession *session;
+ ESource *identity_source;
+ GPtrArray *account_sources;
+ GPtrArray *transport_sources;
+ EMailConfigServicePage *receiving_page;
+ EMailConfigServicePage *sending_page;
+ EMailConfigSummaryPage *summary_page;
+ EMailConfigPage *lookup_page;
+ GHashTable *visited_pages;
+ gboolean auto_configure_done;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_BACKEND,
+ PROP_ACCOUNT_SOURCE,
+ PROP_IDENTITY_SOURCE,
+ PROP_SESSION,
+ PROP_TRANSPORT_BACKEND,
+ PROP_TRANSPORT_SOURCE
+};
+
+/* XXX We implement EAlertSink but don't implement a custom submit_alert()
+ * method. So any alert results in a pop-up message dialog, which is a
+ * fashion faux pas these days. But it's only used when submitting the
+ * the newly-configured account fails, so should rarely be seen. */
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigAssistant,
+ e_mail_config_assistant,
+ GTK_TYPE_ASSISTANT,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_ALERT_SINK, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL))
+
+static gint
+mail_config_assistant_provider_compare (gconstpointer data1,
+ gconstpointer data2)
+{
+ const CamelProvider *provider1 = data1;
+ const CamelProvider *provider2 = data2;
+
+ /* The "none" provider comes first. */
+ if (g_strcmp0 (provider1->protocol, "none") == 0)
+ return -1;
+ if (g_strcmp0 (provider2->protocol, "none") == 0)
+ return 1;
+
+ /* Then sort remote providers before local providers. */
+ if (provider1->flags & CAMEL_PROVIDER_IS_REMOTE) {
+ if (provider2->flags & CAMEL_PROVIDER_IS_REMOTE)
+ return 0;
+ else
+ return -1;
+ } else {
+ if (provider2->flags & CAMEL_PROVIDER_IS_REMOTE)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+static GList *
+mail_config_assistant_list_providers (void)
+{
+ GList *list, *link;
+ GQueue trash = G_QUEUE_INIT;
+
+ list = camel_provider_list (TRUE);
+ list = g_list_sort (list, mail_config_assistant_provider_compare);
+
+ /* Keep only providers with a "mail" or "news" domain. */
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ CamelProvider *provider = link->data;
+ gboolean mail_or_news_domain;
+
+ mail_or_news_domain =
+ (g_strcmp0 (provider->domain, "mail") == 0) ||
+ (g_strcmp0 (provider->domain, "news") == 0);
+
+ if (mail_or_news_domain)
+ continue;
+
+ g_queue_push_tail (&trash, link);
+ }
+
+ while ((link = g_queue_pop_head (&trash)) != NULL)
+ list = g_list_remove_link (list, link);
+
+ return list;
+}
+
+static void
+mail_config_assistant_notify_account_backend (EMailConfigServicePage *page,
+ GParamSpec *pspec,
+ EMailConfigAssistant *assistant)
+{
+ EMailConfigServiceBackend *backend;
+ EMailConfigServicePage *sending_page;
+ EMailConfigServicePageClass *page_class;
+ CamelProvider *provider;
+
+ backend = e_mail_config_service_page_get_active_backend (page);
+
+ /* The Receiving Page combo box may not have an active item. */
+ if (backend == NULL)
+ goto notify;
+
+ /* The Sending Page may not have been created yet. */
+ if (assistant->priv->sending_page == NULL)
+ goto notify;
+
+ provider = e_mail_config_service_backend_get_provider (backend);
+
+ /* XXX This should never fail, but the Camel macro below does
+ * not check for NULL so better to malfunction than crash. */
+ g_return_if_fail (provider != NULL);
+
+ sending_page = assistant->priv->sending_page;
+ page_class = E_MAIL_CONFIG_SERVICE_PAGE_GET_CLASS (sending_page);
+
+ /* The Sending Page is invisible when the CamelProvider for the
+ * receiving type defines both a storage and transport service.
+ * This is common in CamelProviders for groupware products like
+ * Microsoft Exchange and Novell GroupWise. */
+ if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) {
+ backend = e_mail_config_service_page_lookup_backend (
+ sending_page, provider->protocol);
+ gtk_widget_hide (GTK_WIDGET (sending_page));
+ } else {
+ backend = e_mail_config_service_page_lookup_backend (
+ sending_page, page_class->default_backend_name);
+ gtk_widget_show (GTK_WIDGET (sending_page));
+ }
+
+ e_mail_config_service_page_set_active_backend (sending_page, backend);
+
+notify:
+ g_object_freeze_notify (G_OBJECT (assistant));
+
+ g_object_notify (G_OBJECT (assistant), "account-backend");
+ g_object_notify (G_OBJECT (assistant), "account-source");
+
+ g_object_thaw_notify (G_OBJECT (assistant));
+}
+
+static void
+mail_config_assistant_notify_transport_backend (EMailConfigServicePage *page,
+ GParamSpec *pspec,
+ EMailConfigAssistant *assistant)
+{
+ g_object_freeze_notify (G_OBJECT (assistant));
+
+ g_object_notify (G_OBJECT (assistant), "transport-backend");
+ g_object_notify (G_OBJECT (assistant), "transport-source");
+
+ g_object_thaw_notify (G_OBJECT (assistant));
+}
+
+static void
+mail_config_assistant_page_changed (EMailConfigPage *page,
+ EMailConfigAssistant *assistant)
+{
+ gtk_assistant_set_page_complete (
+ GTK_ASSISTANT (assistant), GTK_WIDGET (page),
+ e_mail_config_page_check_complete (page));
+}
+
+static void
+mail_config_assistant_autoconfigure_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EMailConfigAssistantPrivate *priv;
+ GtkAssistant *assistant;
+ EMailAutoconfig *autoconfig;
+ const gchar *email_address;
+ gint n_pages, ii;
+ GError *error = NULL;
+
+ assistant = GTK_ASSISTANT (user_data);
+ priv = E_MAIL_CONFIG_ASSISTANT_GET_PRIVATE (assistant);
+
+ /* Whether it works or not, we only do this once. */
+ priv->auto_configure_done = TRUE;
+
+ autoconfig = e_mail_autoconfig_finish (result, &error);
+
+ /* We don't really care about errors, we only capture the GError
+ * as a debugging aid. If this doesn't work we simply proceed to
+ * the Receiving Email page. */
+ if (error != NULL) {
+ gtk_assistant_next_page (assistant);
+ g_error_free (error);
+ goto exit;
+ }
+
+ g_return_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig));
+
+ /* Autoconfiguration worked! Feed the results to the
+ * service pages and then skip to the Summary page. */
+
+ e_mail_config_service_page_auto_configure (
+ priv->receiving_page, autoconfig);
+
+ e_mail_config_service_page_auto_configure (
+ priv->sending_page, autoconfig);
+
+ /* Also set the initial account name to the email address
+ * given so the user can just click past the Summary page. */
+ email_address = e_mail_autoconfig_get_email_address (autoconfig);
+ e_mail_config_summary_page_set_account_name (
+ priv->summary_page, email_address);
+
+ /* XXX Can't find a better way to learn the page number of
+ * the summary page. Oh my god this API is horrible. */
+ n_pages = gtk_assistant_get_n_pages (assistant);
+ for (ii = 0; ii < n_pages; ii++) {
+ GtkWidget *nth_page;
+
+ nth_page = gtk_assistant_get_nth_page (assistant, ii);
+ if (E_IS_MAIL_CONFIG_SUMMARY_PAGE (nth_page))
+ break;
+ }
+
+ g_warn_if_fail (ii < n_pages);
+ gtk_assistant_set_current_page (assistant, ii);
+
+exit:
+ /* Set the page invisible so we never revisit it. */
+ gtk_widget_set_visible (GTK_WIDGET (priv->lookup_page), FALSE);
+
+ g_object_unref (assistant);
+}
+
+static gboolean
+mail_config_assistant_provider_page_visible (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer unused)
+{
+ EMailConfigServiceBackend *active_backend;
+ EMailConfigServiceBackend *page_backend;
+ EMailConfigProviderPage *page;
+ GObject *target_object;
+ gboolean visible;
+
+ target_object = g_binding_get_target (binding);
+ page = E_MAIL_CONFIG_PROVIDER_PAGE (target_object);
+ page_backend = e_mail_config_provider_page_get_backend (page);
+
+ active_backend = g_value_get_object (source_value);
+ visible = (page_backend == active_backend);
+ g_value_set_boolean (target_value, visible);
+
+ return TRUE;
+}
+
+static void
+mail_config_assistant_close_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EMailConfigAssistant *assistant;
+ GdkWindow *gdk_window;
+ GError *error = NULL;
+
+ assistant = E_MAIL_CONFIG_ASSISTANT (object);
+
+ /* Set the cursor back to normal. */
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (assistant));
+ gdk_window_set_cursor (gdk_window, NULL);
+
+ /* Allow user interaction with window content. */
+ gtk_widget_set_sensitive (GTK_WIDGET (assistant), TRUE);
+
+ e_mail_config_assistant_commit_finish (assistant, result, &error);
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+
+ } else if (error != NULL) {
+ e_alert_submit (
+ E_ALERT_SINK (assistant),
+ "mail:session-message-error",
+ error->message, NULL);
+ g_error_free (error);
+
+ } else {
+ gtk_widget_destroy (GTK_WIDGET (assistant));
+ }
+}
+
+static void
+mail_config_assistant_set_session (EMailConfigAssistant *assistant,
+ EMailSession *session)
+{
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (assistant->priv->session == NULL);
+
+ assistant->priv->session = g_object_ref (session);
+}
+
+static void
+mail_config_assistant_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SESSION:
+ mail_config_assistant_set_session (
+ E_MAIL_CONFIG_ASSISTANT (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_assistant_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_assistant_get_account_backend (
+ E_MAIL_CONFIG_ASSISTANT (object)));
+ return;
+
+ case PROP_ACCOUNT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_assistant_get_account_source (
+ E_MAIL_CONFIG_ASSISTANT (object)));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_assistant_get_identity_source (
+ E_MAIL_CONFIG_ASSISTANT (object)));
+ return;
+
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ e_mail_config_assistant_get_session (
+ E_MAIL_CONFIG_ASSISTANT (object)));
+ return;
+
+ case PROP_TRANSPORT_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_assistant_get_transport_backend (
+ E_MAIL_CONFIG_ASSISTANT (object)));
+ return;
+
+ case PROP_TRANSPORT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_assistant_get_transport_source (
+ E_MAIL_CONFIG_ASSISTANT (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_assistant_dispose (GObject *object)
+{
+ EMailConfigAssistantPrivate *priv;
+
+ priv = E_MAIL_CONFIG_ASSISTANT_GET_PRIVATE (object);
+
+ if (priv->session != NULL) {
+ g_object_unref (priv->session);
+ priv->session = NULL;
+ }
+
+ if (priv->identity_source != NULL) {
+ g_object_unref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ if (priv->receiving_page != NULL) {
+ g_object_unref (priv->receiving_page);
+ priv->receiving_page = NULL;
+ }
+
+ if (priv->sending_page != NULL) {
+ g_object_unref (priv->sending_page);
+ priv->sending_page = NULL;
+ }
+
+ if (priv->summary_page != NULL) {
+ g_object_unref (priv->summary_page);
+ priv->summary_page = NULL;
+ }
+
+ if (priv->lookup_page != NULL) {
+ g_object_unref (priv->lookup_page);
+ priv->lookup_page = NULL;
+ }
+
+ g_ptr_array_set_size (priv->account_sources, 0);
+ g_ptr_array_set_size (priv->transport_sources, 0);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_assistant_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_assistant_finalize (GObject *object)
+{
+ EMailConfigAssistantPrivate *priv;
+
+ priv = E_MAIL_CONFIG_ASSISTANT_GET_PRIVATE (object);
+
+ g_ptr_array_free (priv->account_sources, TRUE);
+ g_ptr_array_free (priv->transport_sources, TRUE);
+
+ g_hash_table_destroy (priv->visited_pages);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_assistant_parent_class)->
+ finalize (object);
+}
+
+static void
+mail_config_assistant_constructed (GObject *object)
+{
+ EMailConfigAssistant *assistant;
+ ESource *identity_source;
+ ESourceRegistry *registry;
+ ESourceExtension *extension;
+ ESourceMailComposition *mail_composition_extension;
+ ESourceMailIdentity *mail_identity_extension;
+ ESourceMailSubmission *mail_submission_extension;
+ EMailSession *session;
+ EMailConfigPage *page;
+ GList *list, *link;
+ const gchar *extension_name;
+ const gchar *title;
+
+ assistant = E_MAIL_CONFIG_ASSISTANT (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_assistant_parent_class)->
+ constructed (object);
+
+ title = _("Evolution Account Assistant");
+ gtk_window_set_title (GTK_WINDOW (assistant), title);
+ gtk_window_set_position (GTK_WINDOW (assistant), GTK_WIN_POS_CENTER);
+
+ session = e_mail_config_assistant_get_session (assistant);
+ registry = e_mail_session_get_registry (session);
+
+ /* Configure a new identity source. */
+
+ identity_source = e_source_new (NULL, NULL, NULL);
+ assistant->priv->identity_source = identity_source;
+ session = e_mail_config_assistant_get_session (assistant);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ extension = e_source_get_extension (identity_source, extension_name);
+ mail_composition_extension = E_SOURCE_MAIL_COMPOSITION (extension);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (identity_source, extension_name);
+ mail_identity_extension = E_SOURCE_MAIL_IDENTITY (extension);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ extension = e_source_get_extension (identity_source, extension_name);
+ mail_submission_extension = E_SOURCE_MAIL_SUBMISSION (extension);
+
+ e_source_mail_composition_set_drafts_folder (
+ mail_composition_extension,
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS));
+
+ e_source_mail_composition_set_templates_folder (
+ mail_composition_extension,
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_TEMPLATES));
+
+ e_source_mail_submission_set_sent_folder (
+ mail_submission_extension,
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_SENT));
+
+ /*** Welcome Page ***/
+
+ page = e_mail_config_welcome_page_new ();
+ e_mail_config_assistant_add_page (assistant, page);
+
+ /*** Identity Page ***/
+
+ page = e_mail_config_identity_page_new (registry, identity_source);
+ e_mail_config_identity_page_set_show_account_info (
+ E_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
+ e_mail_config_identity_page_set_show_signatures (
+ E_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
+ e_mail_config_assistant_add_page (assistant, page);
+
+ /*** Lookup Page ***/
+
+ page = e_mail_config_lookup_page_new ();
+ e_mail_config_assistant_add_page (assistant, page);
+ assistant->priv->lookup_page = g_object_ref (page);
+
+ /*** Receiving Page ***/
+
+ page = e_mail_config_receiving_page_new (registry);
+ e_mail_config_assistant_add_page (assistant, page);
+ assistant->priv->receiving_page = g_object_ref (page);
+
+ g_object_bind_property (
+ mail_identity_extension, "address",
+ page, "email-address",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (
+ page, "notify::active-backend",
+ G_CALLBACK (mail_config_assistant_notify_account_backend),
+ assistant);
+
+ /*** Receiving Options (multiple) ***/
+
+ /* Populate the Receiving Email page while at the same time
+ * adding a Receiving Options page for each account type. */
+
+ list = mail_config_assistant_list_providers ();
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider = link->data;
+ ESourceBackend *backend_extension;
+ ESource *scratch_source;
+ const gchar *backend_name;
+
+ if (provider->object_types[CAMEL_PROVIDER_STORE] == 0)
+ continue;
+
+ /* ESource uses "backend_name" and CamelProvider
+ * uses "protocol", but the terms are synonymous. */
+ backend_name = provider->protocol;
+
+ scratch_source = e_source_new (NULL, NULL, NULL);
+ backend_extension = e_source_get_extension (
+ scratch_source, E_SOURCE_EXTENSION_MAIL_ACCOUNT);
+ e_source_backend_set_backend_name (
+ backend_extension, backend_name);
+
+ /* We always pass NULL for the collection argument.
+ * The backend generates its own scratch collection
+ * source if implements the new_collection() method. */
+ backend = e_mail_config_service_page_add_scratch_source (
+ assistant->priv->receiving_page, scratch_source, NULL);
+
+ g_object_unref (scratch_source);
+
+ page = e_mail_config_provider_page_new (backend);
+
+ /* Note: We exclude this page if it has no options,
+ * but we don't know that until we create it. */
+ if (e_mail_config_provider_page_is_empty (
+ E_MAIL_CONFIG_PROVIDER_PAGE (page))) {
+ g_object_unref (g_object_ref_sink (page));
+ continue;
+ } else {
+ e_mail_config_assistant_add_page (assistant, page);
+ }
+
+ /* Each Receiving Options page is only visible when its
+ * service backend is active on the Receiving Email page. */
+ g_object_bind_property_full (
+ assistant->priv->receiving_page, "active-backend",
+ page, "visible",
+ G_BINDING_SYNC_CREATE,
+ mail_config_assistant_provider_page_visible,
+ NULL,
+ NULL, (GDestroyNotify) NULL);
+ }
+
+ g_list_free (list);
+
+ /*** Sending Page ***/
+
+ page = e_mail_config_sending_page_new (registry);
+ e_mail_config_assistant_add_page (assistant, page);
+ assistant->priv->sending_page = g_object_ref (page);
+
+ g_object_bind_property (
+ mail_identity_extension, "address",
+ page, "email-address",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (
+ page, "notify::active-backend",
+ G_CALLBACK (mail_config_assistant_notify_transport_backend),
+ assistant);
+
+ list = mail_config_assistant_list_providers ();
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ CamelProvider *provider = link->data;
+ ESourceBackend *backend_extension;
+ ESource *scratch_source;
+ const gchar *backend_name;
+
+ if (provider->object_types[CAMEL_PROVIDER_TRANSPORT] == 0)
+ continue;
+
+ /* ESource uses "backend_name" and CamelProvider
+ * uses "protocol", but the terms are synonymous. */
+ backend_name = provider->protocol;
+
+ scratch_source = e_source_new (NULL, NULL, NULL);
+ backend_extension = e_source_get_extension (
+ scratch_source, E_SOURCE_EXTENSION_MAIL_TRANSPORT);
+ e_source_backend_set_backend_name (
+ backend_extension, backend_name);
+
+ /* We always pass NULL for the collection argument.
+ * The backend generates its own scratch collection
+ * source if implements the new_collection() method. */
+ e_mail_config_service_page_add_scratch_source (
+ assistant->priv->sending_page, scratch_source, NULL);
+
+ g_object_unref (scratch_source);
+ }
+
+ g_list_free (list);
+
+ /*** Summary Page ***/
+
+ page = e_mail_config_summary_page_new ();
+ e_mail_config_assistant_add_page (assistant, page);
+ assistant->priv->summary_page = g_object_ref (page);
+
+ g_object_bind_property (
+ assistant, "account-backend",
+ page, "account-backend",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ assistant, "identity-source",
+ page, "identity-source",
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ assistant, "transport-backend",
+ page, "transport-backend",
+ G_BINDING_SYNC_CREATE);
+
+ /*** Confirm Page ***/
+
+ page = e_mail_config_confirm_page_new ();
+ e_mail_config_assistant_add_page (assistant, page);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (assistant));
+}
+
+static void
+mail_config_assistant_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ if (E_IS_MAIL_CONFIG_PAGE (widget))
+ g_signal_handlers_disconnect_by_func (
+ widget, mail_config_assistant_page_changed,
+ E_MAIL_CONFIG_ASSISTANT (container));
+
+ /* Chain up to parent's remove() method. */
+ GTK_CONTAINER_CLASS (e_mail_config_assistant_parent_class)->
+ remove (container, widget);
+}
+
+static void
+mail_config_assistant_prepare (GtkAssistant *assistant,
+ GtkWidget *page)
+{
+ EMailConfigAssistantPrivate *priv;
+
+ priv = E_MAIL_CONFIG_ASSISTANT_GET_PRIVATE (assistant);
+
+ /* Only setup defaults the first time a page is visited. */
+ if (!g_hash_table_contains (priv->visited_pages, page)) {
+ if (E_IS_MAIL_CONFIG_PAGE (page))
+ e_mail_config_page_setup_defaults (
+ E_MAIL_CONFIG_PAGE (page));
+ g_hash_table_add (priv->visited_pages, page);
+ }
+
+ if (E_IS_MAIL_CONFIG_LOOKUP_PAGE (page)) {
+ ESource *source;
+ ESourceMailIdentity *extension;
+ const gchar *email_address;
+ const gchar *extension_name;
+
+ source = priv->identity_source;
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (source, extension_name);
+ email_address = e_source_mail_identity_get_address (extension);
+
+ /* XXX This operation is not cancellable. */
+ e_mail_autoconfig_new (
+ email_address, G_PRIORITY_DEFAULT, NULL,
+ mail_config_assistant_autoconfigure_cb,
+ g_object_ref (assistant));
+ }
+}
+
+static void
+mail_config_assistant_close (GtkAssistant *assistant)
+{
+ GdkCursor *gdk_cursor;
+ GdkWindow *gdk_window;
+
+ /* Do not chain up. GtkAssistant does not implement this method. */
+
+ /* Make the cursor appear busy. */
+ gdk_cursor = gdk_cursor_new (GDK_WATCH);
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (assistant));
+ gdk_window_set_cursor (gdk_window, gdk_cursor);
+ g_object_unref (gdk_cursor);
+
+ /* Prevent user interaction with window content. */
+ gtk_widget_set_sensitive (GTK_WIDGET (assistant), FALSE);
+
+ /* XXX This operation is not cancellable. */
+ e_mail_config_assistant_commit (
+ E_MAIL_CONFIG_ASSISTANT (assistant),
+ NULL, mail_config_assistant_close_cb, NULL);
+}
+
+static void
+mail_config_assistant_cancel (GtkAssistant *assistant)
+{
+ /* Do not chain up. GtkAssistant does not implement this method. */
+
+ gtk_widget_destroy (GTK_WIDGET (assistant));
+}
+
+static void
+e_mail_config_assistant_class_init (EMailConfigAssistantClass *class)
+{
+ GObjectClass *object_class;
+ GtkContainerClass *container_class;
+ GtkAssistantClass *assistant_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigAssistantPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_assistant_set_property;
+ object_class->get_property = mail_config_assistant_get_property;
+ object_class->dispose = mail_config_assistant_dispose;
+ object_class->finalize = mail_config_assistant_finalize;
+ object_class->constructed = mail_config_assistant_constructed;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->remove = mail_config_assistant_remove;
+
+ assistant_class = GTK_ASSISTANT_CLASS (class);
+ assistant_class->prepare = mail_config_assistant_prepare;
+ assistant_class->close = mail_config_assistant_close;
+ assistant_class->cancel = mail_config_assistant_cancel;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_BACKEND,
+ g_param_spec_object (
+ "account-backend",
+ "Account Backend",
+ "Active mail account service backend",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_SOURCE,
+ g_param_spec_object (
+ "account-source",
+ "Account Source",
+ "Mail account source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IDENTITY_SOURCE,
+ g_param_spec_object (
+ "identity-source",
+ "Identity Source",
+ "Mail identity source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "Mail session",
+ E_TYPE_MAIL_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TRANSPORT_BACKEND,
+ g_param_spec_object (
+ "transport-backend",
+ "Transport Backend",
+ "Active mail transport service backend",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TRANSPORT_SOURCE,
+ g_param_spec_object (
+ "transport-source",
+ "Transport Source",
+ "Mail transport source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_assistant_init (EMailConfigAssistant *assistant)
+{
+ assistant->priv = E_MAIL_CONFIG_ASSISTANT_GET_PRIVATE (assistant);
+
+ assistant->priv->account_sources =
+ g_ptr_array_new_with_free_func (
+ (GDestroyNotify) g_object_unref);
+
+ assistant->priv->transport_sources =
+ g_ptr_array_new_with_free_func (
+ (GDestroyNotify) g_object_unref);
+
+ assistant->priv->visited_pages = g_hash_table_new (NULL, NULL);
+}
+
+GtkWidget *
+e_mail_config_assistant_new (EMailSession *session)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_ASSISTANT,
+ "session", session, NULL);
+}
+
+EMailSession *
+e_mail_config_assistant_get_session (EMailConfigAssistant *assistant)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant), NULL);
+
+ return assistant->priv->session;
+}
+
+EMailConfigServiceBackend *
+e_mail_config_assistant_get_account_backend (EMailConfigAssistant *assistant)
+{
+ EMailConfigServicePage *page;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant), NULL);
+
+ page = assistant->priv->receiving_page;
+
+ return e_mail_config_service_page_get_active_backend (page);
+}
+
+ESource *
+e_mail_config_assistant_get_account_source (EMailConfigAssistant *assistant)
+{
+ EMailConfigServiceBackend *backend;
+ ESource *source = NULL;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant), NULL);
+
+ backend = e_mail_config_assistant_get_account_backend (assistant);
+
+ if (backend != NULL)
+ source = e_mail_config_service_backend_get_source (backend);
+
+ return source;
+}
+
+ESource *
+e_mail_config_assistant_get_identity_source (EMailConfigAssistant *assistant)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant), NULL);
+
+ return assistant->priv->identity_source;
+}
+
+EMailConfigServiceBackend *
+e_mail_config_assistant_get_transport_backend (EMailConfigAssistant *assistant)
+{
+ EMailConfigServicePage *page;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant), NULL);
+
+ page = assistant->priv->sending_page;
+
+ return e_mail_config_service_page_get_active_backend (page);
+}
+
+ESource *
+e_mail_config_assistant_get_transport_source (EMailConfigAssistant *assistant)
+{
+ EMailConfigServiceBackend *backend;
+ ESource *source = NULL;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant), NULL);
+
+ backend = e_mail_config_assistant_get_transport_backend (assistant);
+
+ if (backend != NULL)
+ source = e_mail_config_service_backend_get_source (backend);
+
+ return source;
+}
+
+void
+e_mail_config_assistant_add_page (EMailConfigAssistant *assistant,
+ EMailConfigPage *page)
+{
+ EMailConfigPageInterface *page_interface;
+ GtkAssistantPageType page_type;
+ GtkWidget *page_widget;
+ gint n_pages, position;
+ const gchar *page_title;
+ gboolean complete;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant));
+ g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
+
+ page_widget = GTK_WIDGET (page);
+ page_interface = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page);
+ page_type = page_interface->page_type;
+ page_title = page_interface->title;
+
+ /* Determine the position to insert the page. */
+ n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (assistant));
+ for (position = 0; position < n_pages; position++) {
+ GtkWidget *nth_page;
+
+ nth_page = gtk_assistant_get_nth_page (
+ GTK_ASSISTANT (assistant), position);
+ if (e_mail_config_page_compare (page_widget, nth_page) < 0)
+ break;
+ }
+
+ gtk_widget_show (page_widget);
+
+ /* Some pages can be clicked through unchanged. */
+ complete = e_mail_config_page_check_complete (page);
+
+ gtk_assistant_insert_page (
+ GTK_ASSISTANT (assistant), page_widget, position);
+ gtk_assistant_set_page_type (
+ GTK_ASSISTANT (assistant), page_widget, page_type);
+ gtk_assistant_set_page_title (
+ GTK_ASSISTANT (assistant), page_widget, page_title);
+ gtk_assistant_set_page_complete (
+ GTK_ASSISTANT (assistant), page_widget, complete);
+
+ /* XXX GtkAssistant has no equivalent to GtkNotebook's
+ * "page-added" and "page-removed" signals. Fortunately
+ * removing a page does trigger GtkContainer::remove, so
+ * we can override that method and disconnect our signal
+ * handler before chaining up. But I don't see any way
+ * for a subclass to intercept GtkAssistant pages being
+ * added, so we have to connect our signal handler here.
+ * Not really an issue, I'm just being pedantic. */
+
+ g_signal_connect (
+ page, "changed",
+ G_CALLBACK (mail_config_assistant_page_changed),
+ assistant);
+}
+
+/********************* e_mail_config_assistant_commit() **********************/
+
+static void
+mail_config_assistant_commit_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ GError *error = NULL;
+
+ simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ e_source_registry_create_sources_finish (
+ E_SOURCE_REGISTRY (object), result, &error);
+
+ if (error != NULL)
+ g_simple_async_result_take_error (simple, error);
+
+ g_simple_async_result_complete (simple);
+
+ g_object_unref (simple);
+}
+
+void
+e_mail_config_assistant_commit (EMailConfigAssistant *assistant,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ EMailConfigServiceBackend *backend;
+ GSimpleAsyncResult *simple;
+ ESourceRegistry *registry;
+ EMailSession *session;
+ ESource *source;
+ GQueue *queue;
+ gint n_pages, ii;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_ASSISTANT (assistant));
+
+ session = e_mail_config_assistant_get_session (assistant);
+ registry = e_mail_session_get_registry (session);
+
+ queue = g_queue_new ();
+
+ /* Queue the collection data source if one is defined. */
+ backend = e_mail_config_assistant_get_account_backend (assistant);
+ source = e_mail_config_service_backend_get_collection (backend);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+
+ /* Queue the mail-related data sources for the account. */
+ source = e_mail_config_assistant_get_account_source (assistant);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+ source = e_mail_config_assistant_get_identity_source (assistant);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+ source = e_mail_config_assistant_get_transport_source (assistant);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+
+ n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (assistant));
+
+ /* Tell all EMailConfigPages to commit their UI state to their
+ * scratch ESources and push any additional data sources on to
+ * the given source queue, such as calendars or address books
+ * to be bundled with the mail account. */
+ for (ii = 0; ii < n_pages; ii++) {
+ GtkWidget *widget;
+
+ widget = gtk_assistant_get_nth_page (
+ GTK_ASSISTANT (assistant), ii);
+
+ if (E_IS_MAIL_CONFIG_PAGE (widget)) {
+ EMailConfigPage *page;
+ page = E_MAIL_CONFIG_PAGE (widget);
+ e_mail_config_page_commit_changes (page, queue);
+ }
+ }
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (assistant), callback, user_data,
+ e_mail_config_assistant_commit);
+
+ e_source_registry_create_sources (
+ registry, g_queue_peek_head_link (queue),
+ cancellable, mail_config_assistant_commit_cb, simple);
+
+ g_queue_free_full (queue, (GDestroyNotify) g_object_unref);
+}
+
+gboolean
+e_mail_config_assistant_commit_finish (EMailConfigAssistant *assistant,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (assistant),
+ e_mail_config_assistant_commit), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
diff --git a/mail/e-mail-config-assistant.h b/mail/e-mail-config-assistant.h
new file mode 100644
index 0000000000..de225af921
--- /dev/null
+++ b/mail/e-mail-config-assistant.h
@@ -0,0 +1,96 @@
+/*
+ * e-mail-config-assistant.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_ASSISTANT_H
+#define E_MAIL_CONFIG_ASSISTANT_H
+
+#include <gtk/gtk.h>
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-service-backend.h>
+#include <libemail-engine/e-mail-session.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_ASSISTANT \
+ (e_mail_config_assistant_get_type ())
+#define E_MAIL_CONFIG_ASSISTANT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_ASSISTANT, EMailConfigAssistant))
+#define E_MAIL_CONFIG_ASSISTANT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_ASSISTANT, EMailConfigAssistantClass))
+#define E_IS_MAIL_CONFIG_ASSISTANT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_ASSISTANT))
+#define E_IS_MAIL_CONFIG_ASSISTANT_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_ASSISTANT))
+#define E_MAIL_CONFIG_ASSISTANT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_ASSISTANT, EMailConfigAssistantClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigAssistant EMailConfigAssistant;
+typedef struct _EMailConfigAssistantClass EMailConfigAssistantClass;
+typedef struct _EMailConfigAssistantPrivate EMailConfigAssistantPrivate;
+
+struct _EMailConfigAssistant {
+ GtkAssistant parent;
+ EMailConfigAssistantPrivate *priv;
+};
+
+struct _EMailConfigAssistantClass {
+ GtkAssistantClass parent_class;
+};
+
+GType e_mail_config_assistant_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_config_assistant_new
+ (EMailSession *session);
+EMailSession * e_mail_config_assistant_get_session
+ (EMailConfigAssistant *assistant);
+EMailConfigServiceBackend *
+ e_mail_config_assistant_get_account_backend
+ (EMailConfigAssistant *assistant);
+ESource * e_mail_config_assistant_get_account_source
+ (EMailConfigAssistant *assistant);
+ESource * e_mail_config_assistant_get_identity_source
+ (EMailConfigAssistant *assistant);
+EMailConfigServiceBackend *
+ e_mail_config_assistant_get_transport_backend
+ (EMailConfigAssistant *assistant);
+ESource * e_mail_config_assistant_get_transport_source
+ (EMailConfigAssistant *assistant);
+void e_mail_config_assistant_add_page
+ (EMailConfigAssistant *assistant,
+ EMailConfigPage *page);
+void e_mail_config_assistant_commit
+ (EMailConfigAssistant *assistant,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_mail_config_assistant_commit_finish
+ (EMailConfigAssistant *assistant,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_ASSISTANT_H */
+
diff --git a/mail/e-mail-config-auth-check.c b/mail/e-mail-config-auth-check.c
new file mode 100644
index 0000000000..22523e5af0
--- /dev/null
+++ b/mail/e-mail-config-auth-check.c
@@ -0,0 +1,446 @@
+/*
+ * e-mail-config-auth-check.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-auth-check.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libevolution-utils/e-alert.h>
+#include <e-util/e-mktemp.h>
+#include <misc/e-auth-combo-box.h>
+#include <mail/e-mail-config-service-page.h>
+
+#define E_MAIL_CONFIG_AUTH_CHECK_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_AUTH_CHECK, EMailConfigAuthCheckPrivate))
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _EMailConfigAuthCheckPrivate {
+ EMailConfigServiceBackend *backend;
+ gchar *active_mechanism;
+
+ GtkWidget *combo_box; /* not referenced */
+};
+
+struct _AsyncContext {
+ EMailConfigAuthCheck *auth_check;
+ CamelSession *temporary_session;
+ EActivity *activity;
+};
+
+enum {
+ PROP_0,
+ PROP_ACTIVE_MECHANISM,
+ PROP_BACKEND
+};
+
+G_DEFINE_TYPE (
+ EMailConfigAuthCheck,
+ e_mail_config_auth_check,
+ GTK_TYPE_BOX)
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->auth_check != NULL)
+ g_object_unref (async_context->auth_check);
+
+ if (async_context->temporary_session != NULL)
+ g_object_unref (async_context->temporary_session);
+
+ if (async_context->activity != NULL)
+ g_object_unref (async_context->activity);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+mail_config_auth_check_update_done_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AsyncContext *async_context = user_data;
+ EMailConfigAuthCheck *auth_check;
+ EAlertSink *alert_sink;
+ GList *available_authtypes;
+ GError *error = NULL;
+
+ auth_check = async_context->auth_check;
+ alert_sink = e_activity_get_alert_sink (async_context->activity);
+
+ available_authtypes = camel_service_query_auth_types_finish (
+ CAMEL_SERVICE (source_object), result, &error);
+
+ if (e_activity_handle_cancellation (async_context->activity, error)) {
+ g_warn_if_fail (available_authtypes == NULL);
+ g_error_free (error);
+
+ } else if (error != NULL) {
+ g_warn_if_fail (available_authtypes == NULL);
+ e_alert_submit (
+ alert_sink,
+ "mail:checking-service-error",
+ error->message, NULL);
+ g_error_free (error);
+
+ } else {
+ e_auth_combo_box_update_available (
+ E_AUTH_COMBO_BOX (auth_check->priv->combo_box),
+ available_authtypes);
+ g_list_free (available_authtypes);
+ }
+
+ gtk_widget_set_sensitive (GTK_WIDGET (auth_check), TRUE);
+
+ async_context_free (async_context);
+}
+
+static void
+mail_config_auth_check_update (EMailConfigAuthCheck *auth_check)
+{
+ EActivity *activity;
+ EMailConfigServicePage *page;
+ EMailConfigServiceBackend *backend;
+ EMailConfigServicePageClass *page_class;
+ EMailConfigServiceBackendClass *backend_class;
+ CamelService *service;
+ CamelSession *session;
+ CamelSettings *settings;
+ GCancellable *cancellable;
+ AsyncContext *async_context;
+ gchar *temp_dir;
+ GError *error = NULL;
+
+ backend = e_mail_config_auth_check_get_backend (auth_check);
+ page = e_mail_config_service_backend_get_page (backend);
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ page_class = E_MAIL_CONFIG_SERVICE_PAGE_GET_CLASS (page);
+ backend_class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+
+ temp_dir = e_mkdtemp ("evolution-auth-check-XXXXXX");
+
+ /* Create a temporary session for our temporary service.
+ * Use the same temporary directory for "user-data-dir" and
+ * "user-cache-dir". For our purposes it shouldn't matter. */
+ session = g_object_new (
+ CAMEL_TYPE_SESSION,
+ "user-data-dir", temp_dir,
+ "user-cache-dir", temp_dir,
+ NULL);
+
+ /* This returns a BORROWED reference to the CamelService. */
+ service = camel_session_add_service (
+ session, "fake-uid",
+ backend_class->backend_name,
+ page_class->provider_type, &error);
+
+ g_free (temp_dir);
+
+ if (error != NULL) {
+ g_warn_if_fail (service == NULL);
+ e_alert_submit (
+ E_ALERT_SINK (page),
+ "mail:checking-service-error",
+ error->message, NULL);
+ g_error_free (error);
+ return;
+ }
+
+ g_return_if_fail (CAMEL_IS_SERVICE (service));
+
+ camel_service_set_settings (service, settings);
+
+ activity = e_mail_config_service_page_new_activity (page);
+ cancellable = e_activity_get_cancellable (activity);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (auth_check), FALSE);
+
+ async_context = g_slice_new (AsyncContext);
+ async_context->auth_check = g_object_ref (auth_check);
+ async_context->temporary_session = session; /* takes ownership */
+ async_context->activity = activity; /* takes ownership */
+
+ camel_service_query_auth_types (
+ service, G_PRIORITY_DEFAULT, cancellable,
+ mail_config_auth_check_update_done_cb, async_context);
+}
+
+static void
+mail_config_auth_check_clicked_cb (GtkButton *button,
+ EMailConfigAuthCheck *auth_check)
+{
+ mail_config_auth_check_update (auth_check);
+}
+
+static void
+mail_config_auth_check_init_mechanism (EMailConfigAuthCheck *auth_check)
+{
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider;
+ CamelSettings *settings;
+ const gchar *auth_mechanism = NULL;
+
+ /* Pick an initial active mechanism name by examining both
+ * the corresponding CamelNetworkSettings and CamelProvider. */
+
+ backend = e_mail_config_auth_check_get_backend (auth_check);
+ provider = e_mail_config_service_backend_get_provider (backend);
+ settings = e_mail_config_service_backend_get_settings (backend);
+ g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings));
+
+ auth_mechanism =
+ camel_network_settings_get_auth_mechanism (
+ CAMEL_NETWORK_SETTINGS (settings));
+
+ /* If CamelNetworkSettings does not have a mechanism name set,
+ * choose from the CamelProvider's list of supported mechanisms. */
+ if (auth_mechanism == NULL && provider != NULL) {
+ if (provider->authtypes != NULL) {
+ CamelServiceAuthType *auth_type;
+ auth_type = provider->authtypes->data;
+ auth_mechanism = auth_type->authproto;
+ }
+ }
+
+ if (auth_mechanism != NULL)
+ e_mail_config_auth_check_set_active_mechanism (
+ auth_check, auth_mechanism);
+}
+
+static void
+mail_config_auth_check_set_backend (EMailConfigAuthCheck *auth_check,
+ EMailConfigServiceBackend *backend)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_return_if_fail (auth_check->priv->backend == NULL);
+
+ auth_check->priv->backend = g_object_ref (backend);
+}
+
+static void
+mail_config_auth_check_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE_MECHANISM:
+ e_mail_config_auth_check_set_active_mechanism (
+ E_MAIL_CONFIG_AUTH_CHECK (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_BACKEND:
+ mail_config_auth_check_set_backend (
+ E_MAIL_CONFIG_AUTH_CHECK (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_auth_check_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE_MECHANISM:
+ g_value_set_string (
+ value,
+ e_mail_config_auth_check_get_active_mechanism (
+ E_MAIL_CONFIG_AUTH_CHECK (object)));
+ return;
+
+ case PROP_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_auth_check_get_backend (
+ E_MAIL_CONFIG_AUTH_CHECK (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_auth_check_dispose (GObject *object)
+{
+ EMailConfigAuthCheckPrivate *priv;
+
+ priv = E_MAIL_CONFIG_AUTH_CHECK_GET_PRIVATE (object);
+
+ if (priv->backend != NULL) {
+ g_object_unref (priv->backend);
+ priv->backend = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_auth_check_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_auth_check_finalize (GObject *object)
+{
+ EMailConfigAuthCheckPrivate *priv;
+
+ priv = E_MAIL_CONFIG_AUTH_CHECK_GET_PRIVATE (object);
+
+ g_free (priv->active_mechanism);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_auth_check_parent_class)->
+ finalize (object);
+}
+
+static void
+mail_config_auth_check_constructed (GObject *object)
+{
+ EMailConfigAuthCheck *auth_check;
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider;
+ GtkWidget *widget;
+ const gchar *text;
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_auth_check_parent_class)->
+ constructed (object);
+
+ auth_check = E_MAIL_CONFIG_AUTH_CHECK (object);
+ backend = e_mail_config_auth_check_get_backend (auth_check);
+ provider = e_mail_config_service_backend_get_provider (backend);
+
+ widget = e_auth_combo_box_new ();
+ e_auth_combo_box_set_provider (E_AUTH_COMBO_BOX (widget), provider);
+ gtk_box_pack_start (GTK_BOX (object), widget, FALSE, FALSE, 0);
+ auth_check->priv->combo_box = widget; /* do not reference */
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ widget, "active-id",
+ auth_check, "active-mechanism",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ text = _("Check for Supported Types");
+ widget = gtk_button_new_with_label (text);
+ gtk_box_pack_start (GTK_BOX (object), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (mail_config_auth_check_clicked_cb),
+ auth_check);
+
+ mail_config_auth_check_init_mechanism (auth_check);
+}
+
+static void
+e_mail_config_auth_check_class_init (EMailConfigAuthCheckClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigAuthCheckPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_auth_check_set_property;
+ object_class->get_property = mail_config_auth_check_get_property;
+ object_class->dispose = mail_config_auth_check_dispose;
+ object_class->finalize = mail_config_auth_check_finalize;
+ object_class->constructed = mail_config_auth_check_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVE_MECHANISM,
+ g_param_spec_string (
+ "active-mechanism",
+ "Active Mechanism",
+ "Active authentication mechanism",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BACKEND,
+ g_param_spec_object (
+ "backend",
+ "Backend",
+ "Mail configuration backend",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_auth_check_init (EMailConfigAuthCheck *auth_check)
+{
+ auth_check->priv = E_MAIL_CONFIG_AUTH_CHECK_GET_PRIVATE (auth_check);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (auth_check),
+ GTK_ORIENTATION_HORIZONTAL);
+
+ gtk_box_set_spacing (GTK_BOX (auth_check), 6);
+}
+
+GtkWidget *
+e_mail_config_auth_check_new (EMailConfigServiceBackend *backend)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_AUTH_CHECK,
+ "backend", backend, NULL);
+}
+
+EMailConfigServiceBackend *
+e_mail_config_auth_check_get_backend (EMailConfigAuthCheck *auth_check)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_AUTH_CHECK (auth_check), NULL);
+
+ return auth_check->priv->backend;
+}
+
+const gchar *
+e_mail_config_auth_check_get_active_mechanism (EMailConfigAuthCheck *auth_check)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_AUTH_CHECK (auth_check), NULL);
+
+ return auth_check->priv->active_mechanism;
+}
+
+void
+e_mail_config_auth_check_set_active_mechanism (EMailConfigAuthCheck *auth_check,
+ const gchar *active_mechanism)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_AUTH_CHECK (auth_check));
+
+ g_free (auth_check->priv->active_mechanism);
+ auth_check->priv->active_mechanism = g_strdup (active_mechanism);
+
+ g_object_notify (G_OBJECT (auth_check), "active-mechanism");
+}
+
diff --git a/mail/e-mail-config-auth-check.h b/mail/e-mail-config-auth-check.h
new file mode 100644
index 0000000000..c7bf759059
--- /dev/null
+++ b/mail/e-mail-config-auth-check.h
@@ -0,0 +1,73 @@
+/*
+ * e-mail-config-auth-check.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_AUTH_CHECK_H
+#define E_MAIL_CONFIG_AUTH_CHECK_H
+
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_AUTH_CHECK \
+ (e_mail_config_auth_check_get_type ())
+#define E_MAIL_CONFIG_AUTH_CHECK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_AUTH_CHECK, EMailConfigAuthCheck))
+#define E_MAIL_CONFIG_AUTH_CHECK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_AUTH_CHECK, EMailConfigAuthCheckClass))
+#define E_IS_MAIL_CONFIG_AUTH_CHECK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_AUTH_CHECK))
+#define E_IS_MAIL_CONFIG_AUTH_CHECK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_AUTH_CHECK))
+#define E_MAIL_CONFIG_AUTH_CHECK_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_AUTH_CHECK, EMailConfigAuthCheckClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigAuthCheck EMailConfigAuthCheck;
+typedef struct _EMailConfigAuthCheckClass EMailConfigAuthCheckClass;
+typedef struct _EMailConfigAuthCheckPrivate EMailConfigAuthCheckPrivate;
+
+struct _EMailConfigAuthCheck {
+ GtkBox parent;
+ EMailConfigAuthCheckPrivate *priv;
+};
+
+struct _EMailConfigAuthCheckClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_auth_check_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_config_auth_check_new
+ (EMailConfigServiceBackend *backend);
+EMailConfigServiceBackend *
+ e_mail_config_auth_check_get_backend
+ (EMailConfigAuthCheck *auth_check);
+const gchar * e_mail_config_auth_check_get_active_mechanism
+ (EMailConfigAuthCheck *auth_check);
+void e_mail_config_auth_check_set_active_mechanism
+ (EMailConfigAuthCheck *auth_check,
+ const gchar *active_mechanism);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_AUTH_CHECK_H */
diff --git a/mail/e-mail-config-confirm-page.c b/mail/e-mail-config-confirm-page.c
new file mode 100644
index 0000000000..f58da035b6
--- /dev/null
+++ b/mail/e-mail-config-confirm-page.c
@@ -0,0 +1,205 @@
+/*
+ * e-mail-config-confirm-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-confirm-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+
+#define E_MAIL_CONFIG_CONFIRM_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_CONFIRM_PAGE, EMailConfigConfirmPagePrivate))
+
+struct _EMailConfigConfirmPagePrivate {
+ gchar *text;
+};
+
+enum {
+ PROP_0,
+ PROP_TEXT
+};
+
+/* Forward Declarations */
+static void e_mail_config_confirm_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigConfirmPage,
+ e_mail_config_confirm_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_confirm_page_interface_init))
+
+static void
+mail_config_confirm_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TEXT:
+ e_mail_config_confirm_page_set_text (
+ E_MAIL_CONFIG_CONFIRM_PAGE (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_confirm_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TEXT:
+ g_value_set_string (
+ value,
+ e_mail_config_confirm_page_get_text (
+ E_MAIL_CONFIG_CONFIRM_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_confirm_page_finalize (GObject *object)
+{
+ EMailConfigConfirmPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_CONFIRM_PAGE_GET_PRIVATE (object);
+
+ g_free (priv->text);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_confirm_page_parent_class)->
+ finalize (object);
+}
+
+static void
+mail_config_confirm_page_constructed (GObject *object)
+{
+ EMailConfigConfirmPage *page;
+ GtkWidget *widget;
+
+ page = E_MAIL_CONFIG_CONFIRM_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_confirm_page_parent_class)->
+ constructed (object);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ gtk_widget_set_valign (GTK_WIDGET (page), GTK_ALIGN_CENTER);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ page, "text",
+ widget, "label",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static void
+e_mail_config_confirm_page_class_init (EMailConfigConfirmPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigConfirmPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_confirm_page_set_property;
+ object_class->get_property = mail_config_confirm_page_get_property;
+ object_class->finalize = mail_config_confirm_page_finalize;
+ object_class->constructed = mail_config_confirm_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT,
+ g_param_spec_string (
+ "text",
+ "Text",
+ "Confirmation message",
+ _("Congratulations, your mail configuration is "
+ "complete.\n\nYou are now ready to send and "
+ "receive email using Evolution.\n\nClick "
+ "\"Apply\" to save your settings."),
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_confirm_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Done");
+ interface->page_type = GTK_ASSISTANT_PAGE_CONFIRM;
+ interface->sort_order = E_MAIL_CONFIG_CONFIRM_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_confirm_page_init (EMailConfigConfirmPage *page)
+{
+ page->priv = E_MAIL_CONFIG_CONFIRM_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_confirm_page_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_CONFIG_CONFIRM_PAGE, NULL);
+}
+
+const gchar *
+e_mail_config_confirm_page_get_text (EMailConfigConfirmPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_CONFIRM_PAGE (page), NULL);
+
+ return page->priv->text;
+}
+
+void
+e_mail_config_confirm_page_set_text (EMailConfigConfirmPage *page,
+ const gchar *text)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_CONFIRM_PAGE (page));
+
+ g_free (page->priv->text);
+ page->priv->text = g_strdup ((text != NULL) ? text : "");
+
+ g_object_notify (G_OBJECT (page), "text");
+}
+
diff --git a/mail/e-mail-config-confirm-page.h b/mail/e-mail-config-confirm-page.h
new file mode 100644
index 0000000000..d4bae9485f
--- /dev/null
+++ b/mail/e-mail-config-confirm-page.h
@@ -0,0 +1,75 @@
+/*
+ * e-mail-config-confirm-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_CONFIRM_PAGE_H
+#define E_MAIL_CONFIG_CONFIRM_PAGE_H
+
+#include <gtk/gtk.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_CONFIRM_PAGE \
+ (e_mail_config_confirm_page_get_type ())
+#define E_MAIL_CONFIG_CONFIRM_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_CONFIRM_PAGE, EMailConfigConfirmPage))
+#define E_MAIL_CONFIG_CONFIRM_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_CONFIRM_PAGE, EMailConfigConfirmPageClass))
+#define E_IS_MAIL_CONFIG_CONFIRM_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_CONFIRM_PAGE))
+#define E_IS_MAIL_CONFIG_CONFIRM_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_CONFIRM_PAGE))
+#define E_MAIL_CONFIG_CONFIRM_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_CONFIRM_PAGE, EMailConfigConfirmPageClass))
+
+#define E_MAIL_CONFIG_CONFIRM_PAGE_SORT_ORDER (600)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigConfirmPage EMailConfigConfirmPage;
+typedef struct _EMailConfigConfirmPageClass EMailConfigConfirmPageClass;
+typedef struct _EMailConfigConfirmPagePrivate EMailConfigConfirmPagePrivate;
+
+struct _EMailConfigConfirmPage {
+ GtkBox parent;
+ EMailConfigConfirmPagePrivate *priv;
+};
+
+struct _EMailConfigConfirmPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_confirm_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_confirm_page_new (void);
+const gchar * e_mail_config_confirm_page_get_text
+ (EMailConfigConfirmPage *page);
+void e_mail_config_confirm_page_set_text
+ (EMailConfigConfirmPage *page,
+ const gchar *text);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_CONFIRM_PAGE_H */
+
diff --git a/mail/e-mail-config-defaults-page.c b/mail/e-mail-config-defaults-page.c
new file mode 100644
index 0000000000..d815f0560c
--- /dev/null
+++ b/mail/e-mail-config-defaults-page.c
@@ -0,0 +1,868 @@
+/*
+ * e-mail-config-defaults-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-defaults-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-camel.h>
+#include <libedataserver/e-source-enumtypes.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-source-mdn.h>
+#include <libedataserver/e-data-server-util.h>
+
+#include <libemail-engine/e-mail-folder-utils.h>
+
+#include <mail/e-mail-config-page.h>
+#include <mail/em-folder-selection-button.h>
+
+#define E_MAIL_CONFIG_DEFAULTS_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE, EMailConfigDefaultsPagePrivate))
+
+struct _EMailConfigDefaultsPagePrivate {
+ EMailSession *session;
+ ESource *account_source;
+ ESource *identity_source;
+
+ GtkWidget *drafts_button; /* not referenced */
+ GtkWidget *sent_button; /* not referenced */
+ GtkWidget *trash_toggle; /* not referenced */
+ GtkWidget *junk_toggle; /* not referenced */
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_SOURCE,
+ PROP_IDENTITY_SOURCE,
+ PROP_SESSION
+};
+
+/* Forward Declarations */
+static void e_mail_config_defaults_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigDefaultsPage,
+ e_mail_config_defaults_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_defaults_page_interface_init))
+
+static CamelSettings *
+mail_config_defaults_page_maybe_get_settings (EMailConfigDefaultsPage *page)
+{
+ ESource *source;
+ ESourceCamel *camel_ext;
+ ESourceBackend *backend_ext;
+ const gchar *backend_name;
+ const gchar *extension_name;
+
+ source = e_mail_config_defaults_page_get_account_source (page);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ backend_ext = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (backend_ext);
+ extension_name = e_source_camel_get_extension_name (backend_name);
+
+ /* Avoid accidentally creating a backend-specific extension
+ * in the mail account source if the mail account source is
+ * part of a collection, in which case the backend-specific
+ * extension is kept in the top-level collection source. */
+ if (!e_source_has_extension (source, extension_name))
+ return NULL;
+
+ camel_ext = e_source_get_extension (source, extension_name);
+
+ return e_source_camel_get_settings (camel_ext);
+}
+
+static CamelStore *
+mail_config_defaults_page_get_store (EMailConfigDefaultsPage *page)
+{
+ ESource *source;
+ EMailSession *session;
+ CamelService *service;
+ const gchar *uid;
+
+ session = e_mail_config_defaults_page_get_session (page);
+ source = e_mail_config_defaults_page_get_account_source (page);
+
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (CAMEL_SESSION (session), uid);
+
+ return CAMEL_IS_STORE (service) ? CAMEL_STORE (service) : NULL;
+}
+
+static gboolean
+mail_config_defaults_page_addrs_to_string (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer unused)
+{
+ gchar **strv;
+
+ strv = g_value_dup_boxed (source_value);
+
+ if (strv != NULL) {
+ gchar *string = g_strjoinv ("; ", strv);
+ g_value_set_string (target_value, string);
+ g_free (string);
+ } else {
+ g_value_set_string (target_value, "");
+ }
+
+ g_strfreev (strv);
+
+ return TRUE;
+}
+
+static gboolean
+mail_config_defaults_page_string_to_addrs (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer unused)
+{
+ CamelInternetAddress *address;
+ const gchar *string;
+ gchar **strv;
+ gint n_addresses, ii;
+
+ string = g_value_get_string (source_value);
+
+ address = camel_internet_address_new ();
+ n_addresses = camel_address_decode (CAMEL_ADDRESS (address), string);
+
+ if (n_addresses < 0) {
+ g_object_unref (address);
+ return FALSE;
+
+ } else if (n_addresses == 0) {
+ g_value_set_boxed (target_value, NULL);
+ g_object_unref (address);
+ return TRUE;
+ }
+
+ strv = g_new0 (gchar *, n_addresses + 1);
+
+ for (ii = 0; ii < n_addresses; ii++) {
+ const gchar *name = NULL;
+ const gchar *addr = NULL;
+
+ camel_internet_address_get (address, ii, &name, &addr);
+ strv[ii] = camel_internet_address_format_address (name, addr);
+ }
+
+ g_value_take_boxed (target_value, strv);
+
+ return TRUE;
+}
+
+static gboolean
+mail_config_defaults_page_folder_name_to_uri (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer data)
+{
+ EMailConfigDefaultsPage *page;
+ CamelStore *store;
+ const gchar *folder_name;
+ gchar *folder_uri = NULL;
+
+ page = E_MAIL_CONFIG_DEFAULTS_PAGE (data);
+ store = mail_config_defaults_page_get_store (page);
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+
+ folder_name = g_value_get_string (source_value);
+
+ if (folder_name != NULL)
+ folder_uri = e_mail_folder_uri_build (store, folder_name);
+
+ g_value_set_string (target_value, folder_uri);
+
+ g_free (folder_uri);
+
+ return TRUE;
+}
+
+static gboolean
+mail_config_defaults_page_folder_uri_to_name (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer data)
+{
+ EMailConfigDefaultsPage *page;
+ EMailSession *session;
+ const gchar *folder_uri;
+ gchar *folder_name = NULL;
+ GError *error = NULL;
+
+ page = E_MAIL_CONFIG_DEFAULTS_PAGE (data);
+ session = e_mail_config_defaults_page_get_session (page);
+
+ folder_uri = g_value_get_string (source_value);
+
+ if (folder_uri == NULL) {
+ g_value_set_string (target_value, NULL);
+ return TRUE;
+ }
+
+ e_mail_folder_uri_parse (
+ CAMEL_SESSION (session), folder_uri,
+ NULL, &folder_name, &error);
+
+ if (error != NULL) {
+ g_warn_if_fail (folder_name == NULL);
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_return_val_if_fail (folder_name != NULL, FALSE);
+
+ g_value_set_string (target_value, folder_name);
+
+ g_free (folder_name);
+
+ return TRUE;
+}
+
+static void
+mail_config_defaults_page_restore_folders (EMailConfigDefaultsPage *page)
+{
+ EMFolderSelectionButton *button;
+ EMailSession *session;
+ EMailLocalFolder type;
+ const gchar *folder_uri;
+
+ session = e_mail_config_defaults_page_get_session (page);
+
+ type = E_MAIL_LOCAL_FOLDER_DRAFTS;
+ button = EM_FOLDER_SELECTION_BUTTON (page->priv->drafts_button);
+ folder_uri = e_mail_session_get_local_folder_uri (session, type);
+ em_folder_selection_button_set_folder_uri (button, folder_uri);
+
+ type = E_MAIL_LOCAL_FOLDER_SENT;
+ button = EM_FOLDER_SELECTION_BUTTON (page->priv->sent_button);
+ folder_uri = e_mail_session_get_local_folder_uri (session, type);
+ em_folder_selection_button_set_folder_uri (button, folder_uri);
+}
+
+static void
+mail_config_defaults_page_restore_real_folder (GtkToggleButton *toggle_button)
+{
+ gtk_toggle_button_set_active (toggle_button, FALSE);
+}
+
+static GtkWidget *
+mail_config_defaults_page_add_real_folder (EMailConfigDefaultsPage *page,
+ GtkSizeGroup *size_group,
+ GtkButton *revert_button,
+ const gchar *toggle_label,
+ const gchar *dialog_caption,
+ const gchar *property_name,
+ const gchar *use_property_name)
+{
+ GtkWidget *box;
+ GtkWidget *check_button;
+ GtkWidget *folder_button;
+ EMailSession *session;
+ CamelSettings *settings;
+ CamelStore *store;
+ GObjectClass *class;
+
+ store = mail_config_defaults_page_get_store (page);
+ g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+
+ session = e_mail_config_defaults_page_get_session (page);
+ settings = mail_config_defaults_page_maybe_get_settings (page);
+
+ if (settings == NULL)
+ return NULL;
+
+ /* These folder settings are backend-specific, so check if
+ * the CamelSettings class has the property names we need. */
+
+ class = G_OBJECT_GET_CLASS (settings);
+
+ if (g_object_class_find_property (class, property_name) == NULL)
+ return NULL;
+
+ if (g_object_class_find_property (class, use_property_name) == NULL)
+ return NULL;
+
+ /* We're good to go. */
+
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+ check_button = gtk_check_button_new_with_mnemonic (toggle_label);
+ g_object_set (check_button, "xalign", 1.0, NULL);
+ gtk_size_group_add_widget (size_group, check_button);
+ gtk_box_pack_start (GTK_BOX (box), check_button, FALSE, FALSE, 0);
+ gtk_widget_show (check_button);
+
+ g_object_bind_property (
+ settings, use_property_name,
+ check_button, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ folder_button = em_folder_selection_button_new (
+ session, "", dialog_caption);
+ em_folder_selection_button_set_store (
+ EM_FOLDER_SELECTION_BUTTON (folder_button), store);
+ gtk_box_pack_start (GTK_BOX (box), folder_button, TRUE, TRUE, 0);
+ gtk_widget_show (folder_button);
+
+ /* XXX CamelSettings only stores the folder's path name, but the
+ * EMFolderSelectionButton requires a full folder URI, so we
+ * have to do some fancy transforms for the binding to work. */
+ g_object_bind_property_full (
+ settings, property_name,
+ folder_button, "folder-uri",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ mail_config_defaults_page_folder_name_to_uri,
+ mail_config_defaults_page_folder_uri_to_name,
+ g_object_ref (page),
+ (GDestroyNotify) g_object_unref);
+
+ g_object_bind_property (
+ check_button, "active",
+ folder_button, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect_swapped (
+ revert_button, "clicked",
+ G_CALLBACK (mail_config_defaults_page_restore_real_folder),
+ check_button);
+
+ return box;
+}
+
+static void
+mail_config_defaults_page_set_account_source (EMailConfigDefaultsPage *page,
+ ESource *account_source)
+{
+ g_return_if_fail (E_IS_SOURCE (account_source));
+ g_return_if_fail (page->priv->account_source == NULL);
+
+ page->priv->account_source = g_object_ref (account_source);
+}
+
+static void
+mail_config_defaults_page_set_identity_source (EMailConfigDefaultsPage *page,
+ ESource *identity_source)
+{
+ g_return_if_fail (E_IS_SOURCE (identity_source));
+ g_return_if_fail (page->priv->identity_source == NULL);
+
+ page->priv->identity_source = g_object_ref (identity_source);
+}
+
+static void
+mail_config_defaults_page_set_session (EMailConfigDefaultsPage *page,
+ EMailSession *session)
+{
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (page->priv->session == NULL);
+
+ page->priv->session = g_object_ref (session);
+}
+
+static void
+mail_config_defaults_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_SOURCE:
+ mail_config_defaults_page_set_account_source (
+ E_MAIL_CONFIG_DEFAULTS_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ mail_config_defaults_page_set_identity_source (
+ E_MAIL_CONFIG_DEFAULTS_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SESSION:
+ mail_config_defaults_page_set_session (
+ E_MAIL_CONFIG_DEFAULTS_PAGE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_defaults_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_defaults_page_get_account_source (
+ E_MAIL_CONFIG_DEFAULTS_PAGE (object)));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_defaults_page_get_identity_source (
+ E_MAIL_CONFIG_DEFAULTS_PAGE (object)));
+ return;
+
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ e_mail_config_defaults_page_get_session (
+ E_MAIL_CONFIG_DEFAULTS_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_defaults_page_dispose (GObject *object)
+{
+ EMailConfigDefaultsPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_DEFAULTS_PAGE_GET_PRIVATE (object);
+
+ if (priv->identity_source != NULL) {
+ g_object_unref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ if (priv->session != NULL) {
+ g_object_unref (priv->session);
+ priv->session = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_defaults_page_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_defaults_page_constructed (GObject *object)
+{
+ EMailConfigDefaultsPage *page;
+ EMailSession *session;
+ ESource *source;
+ ESourceMailComposition *composition_ext;
+ ESourceMailSubmission *submission_ext;
+ ESourceMDN *mdn_ext;
+ GtkLabel *label;
+ GtkButton *button;
+ GtkWidget *widget;
+ GtkWidget *container;
+ GtkSizeGroup *size_group;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+ EMdnResponsePolicy policy;
+ const gchar *extension_name;
+ const gchar *text;
+ gchar *markup;
+
+ page = E_MAIL_CONFIG_DEFAULTS_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_defaults_page_parent_class)->
+ constructed (object);
+
+ session = e_mail_config_defaults_page_get_session (page);
+ source = e_mail_config_defaults_page_get_identity_source (page);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ composition_ext = e_source_get_extension (source, extension_name);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ submission_ext = e_source_get_extension (source, extension_name);
+
+ extension_name = E_SOURCE_EXTENSION_MDN;
+ mdn_ext = e_source_get_extension (source, extension_name);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ /*** Special Folders ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Special Folders");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Draft Messages _Folder:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ text = _("Choose a folder for saving draft messages.");
+ widget = em_folder_selection_button_new (session, "", text);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ page->priv->drafts_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ composition_ext, "drafts-folder",
+ widget, "folder-uri",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ text = _("Sent _Messages Folder:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ text = _("Choose a folder for saving sent messages.");
+ widget = em_folder_selection_button_new (session, "", text);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ page->priv->sent_button = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ submission_ext, "sent-folder",
+ widget, "folder-uri",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ widget = gtk_button_new_with_mnemonic (_("_Restore Defaults"));
+ gtk_widget_set_halign (widget, GTK_ALIGN_START);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 5, 1, 1);
+ gtk_widget_show (widget);
+
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (mail_config_defaults_page_restore_folders),
+ page);
+
+ button = GTK_BUTTON (widget);
+
+ widget = mail_config_defaults_page_add_real_folder (
+ page, size_group, button,
+ _("Use a Real Folder for _Trash:"),
+ _("Choose a folder for deleted messages."),
+ "real-trash-path", "use-real-trash-path");
+ if (widget != NULL) {
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 3, 2, 1);
+ gtk_widget_show (widget);
+ }
+
+ widget = mail_config_defaults_page_add_real_folder (
+ page, size_group, button,
+ _("Use a Real Folder for _Junk:"),
+ _("Choose a folder for junk messages."),
+ "real-junk-path", "use-real-junk-path");
+ if (widget != NULL) {
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 4, 2, 1);
+ gtk_widget_show (widget);
+ }
+
+ /*** Composing Messages ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Composing Messages");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 1, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Alway_s carbon-copy (cc) to:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property_full (
+ composition_ext, "cc",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ mail_config_defaults_page_addrs_to_string,
+ mail_config_defaults_page_string_to_addrs,
+ NULL, (GDestroyNotify) NULL);
+
+ text = _("Always _blind carbon-copy (bcc) to:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 3, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 4, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property_full (
+ composition_ext, "bcc",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ mail_config_defaults_page_addrs_to_string,
+ mail_config_defaults_page_string_to_addrs,
+ NULL, (GDestroyNotify) NULL);
+
+ /*** Message Receipts ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Message Receipts");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("S_end message receipts:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_combo_box_text_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ /* XXX This is a pain in the butt, but we want to avoid hard-coding
+ * string values from the EMdnResponsePolicy enum class in case
+ * they change in the future. */
+ enum_class = g_type_class_ref (E_TYPE_MDN_RESPONSE_POLICY);
+ policy = E_MDN_RESPONSE_POLICY_NEVER;
+ enum_value = g_enum_get_value (enum_class, policy);
+ g_return_if_fail (enum_value != NULL);
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ enum_value->value_nick, _("Never"));
+ policy = E_MDN_RESPONSE_POLICY_ALWAYS;
+ enum_value = g_enum_get_value (enum_class, policy);
+ g_return_if_fail (enum_value != NULL);
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ enum_value->value_nick, _("Always"));
+ policy = E_MDN_RESPONSE_POLICY_ASK;
+ enum_value = g_enum_get_value (enum_class, policy);
+ g_return_if_fail (enum_value != NULL);
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ enum_value->value_nick, _("Ask for each message"));
+ g_type_class_unref (enum_class);
+
+ g_object_bind_property_full (
+ mdn_ext, "response-policy",
+ widget, "active-id",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ e_binding_transform_enum_value_to_nick,
+ e_binding_transform_enum_nick_to_value,
+ NULL, (GDestroyNotify) NULL);
+
+ g_object_unref (size_group);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static void
+e_mail_config_defaults_page_class_init (EMailConfigDefaultsPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigDefaultsPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_defaults_page_set_property;
+ object_class->get_property = mail_config_defaults_page_get_property;
+ object_class->dispose = mail_config_defaults_page_dispose;
+ object_class->constructed = mail_config_defaults_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_SOURCE,
+ g_param_spec_object (
+ "account-source",
+ "Account Source",
+ "Mail account source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IDENTITY_SOURCE,
+ g_param_spec_object (
+ "identity-source",
+ "Identity Source",
+ "Mail identity source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "Mail session",
+ E_TYPE_MAIL_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_defaults_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Defaults");
+ interface->sort_order = E_MAIL_CONFIG_DEFAULTS_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_defaults_page_init (EMailConfigDefaultsPage *page)
+{
+ page->priv = E_MAIL_CONFIG_DEFAULTS_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_defaults_page_new (EMailSession *session,
+ ESource *account_source,
+ ESource *identity_source)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (account_source), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (identity_source), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE,
+ "account-source", account_source,
+ "identity-source", identity_source,
+ "session", session, NULL);
+}
+
+EMailSession *
+e_mail_config_defaults_page_get_session (EMailConfigDefaultsPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_DEFAULTS_PAGE (page), NULL);
+
+ return page->priv->session;
+}
+
+ESource *
+e_mail_config_defaults_page_get_account_source (EMailConfigDefaultsPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_DEFAULTS_PAGE (page), NULL);
+
+ return page->priv->account_source;
+}
+
+ESource *
+e_mail_config_defaults_page_get_identity_source (EMailConfigDefaultsPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_DEFAULTS_PAGE (page), NULL);
+
+ return page->priv->identity_source;
+}
+
diff --git a/mail/e-mail-config-defaults-page.h b/mail/e-mail-config-defaults-page.h
new file mode 100644
index 0000000000..0f6371ce08
--- /dev/null
+++ b/mail/e-mail-config-defaults-page.h
@@ -0,0 +1,79 @@
+/*
+ * e-mail-config-defaults-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_DEFAULTS_PAGE_H
+#define E_MAIL_CONFIG_DEFAULTS_PAGE_H
+
+#include <gtk/gtk.h>
+#include <libemail-engine/e-mail-session.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE \
+ (e_mail_config_defaults_page_get_type ())
+#define E_MAIL_CONFIG_DEFAULTS_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE, EMailConfigDefaultsPage))
+#define E_MAIL_CONFIG_DEFAULT_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE, EMailConfigDefaultsPageClass))
+#define E_IS_MAIL_CONFIG_DEFAULTS_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE))
+#define E_IS_MAIL_CONFIG_DEFAULTS_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE))
+#define E_MAIL_CONFIG_DEFAULTS_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_DEFAULTS_PAGE, EMailConfigDefaultsPageClass))
+
+#define E_MAIL_CONFIG_DEFAULTS_PAGE_SORT_ORDER (500)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigDefaultsPage EMailConfigDefaultsPage;
+typedef struct _EMailConfigDefaultsPageClass EMailConfigDefaultsPageClass;
+typedef struct _EMailConfigDefaultsPagePrivate EMailConfigDefaultsPagePrivate;
+
+struct _EMailConfigDefaultsPage {
+ GtkBox parent;
+ EMailConfigDefaultsPagePrivate *priv;
+};
+
+struct _EMailConfigDefaultsPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_defaults_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_defaults_page_new (EMailSession *session,
+ ESource *account_source,
+ ESource *identity_source);
+EMailSession * e_mail_config_defaults_page_get_session
+ (EMailConfigDefaultsPage *page);
+ESource * e_mail_config_defaults_page_get_account_source
+ (EMailConfigDefaultsPage *page);
+ESource * e_mail_config_defaults_page_get_identity_source
+ (EMailConfigDefaultsPage *page);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_DEFAULTS_PAGE_H */
+
diff --git a/mail/e-mail-config-identity-page.c b/mail/e-mail-config-identity-page.c
new file mode 100644
index 0000000000..a0920ab1a3
--- /dev/null
+++ b/mail/e-mail-config-identity-page.c
@@ -0,0 +1,738 @@
+/*
+ * e-mail-config-identity-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-identity-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-mail-identity.h>
+
+#include <e-util/e-marshal.h>
+#include <misc/e-mail-signature-combo-box.h>
+#include <misc/e-mail-signature-editor.h>
+
+#define E_MAIL_CONFIG_IDENTITY_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_IDENTITY_PAGE, EMailConfigIdentityPagePrivate))
+
+struct _EMailConfigIdentityPagePrivate {
+ ESource *identity_source;
+ ESourceRegistry *registry;
+ gboolean show_account_info;
+ gboolean show_instructions;
+ gboolean show_signatures;
+};
+
+enum {
+ PROP_0,
+ PROP_IDENTITY_SOURCE,
+ PROP_REGISTRY,
+ PROP_SHOW_ACCOUNT_INFO,
+ PROP_SHOW_INSTRUCTIONS,
+ PROP_SHOW_SIGNATURES
+};
+
+/* Forward Declarations */
+static void e_mail_config_identity_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigIdentityPage,
+ e_mail_config_identity_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_identity_page_interface_init))
+
+static gboolean
+mail_config_identity_page_is_email (const gchar *email_address)
+{
+ const gchar *cp;
+
+ /* Make sure we have a '@' between a name and domain part. */
+ cp = strchr (email_address, '@');
+
+ return (cp != NULL && cp != email_address && *(cp + 1) != '\0');
+}
+
+static void
+mail_config_identity_page_add_signature_cb (GtkButton *button,
+ EMailConfigIdentityPage *page)
+{
+ ESourceRegistry *registry;
+ GtkWidget *editor;
+
+ registry = e_mail_config_identity_page_get_registry (page);
+
+ editor = e_mail_signature_editor_new (registry, NULL);
+ gtk_window_set_position (GTK_WINDOW (editor), GTK_WIN_POS_CENTER);
+ gtk_widget_show (editor);
+}
+
+static void
+mail_config_identity_page_set_registry (EMailConfigIdentityPage *page,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (page->priv->registry == NULL);
+
+ page->priv->registry = g_object_ref (registry);
+}
+
+static void
+mail_config_identity_page_set_identity_source (EMailConfigIdentityPage *page,
+ ESource *identity_source)
+{
+ g_return_if_fail (E_IS_SOURCE (identity_source));
+ g_return_if_fail (page->priv->identity_source == NULL);
+
+ page->priv->identity_source = g_object_ref (identity_source);
+}
+
+static void
+mail_config_identity_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_IDENTITY_SOURCE:
+ mail_config_identity_page_set_identity_source (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_REGISTRY:
+ mail_config_identity_page_set_registry (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SHOW_ACCOUNT_INFO:
+ e_mail_config_identity_page_set_show_account_info (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHOW_INSTRUCTIONS:
+ e_mail_config_identity_page_set_show_instructions (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_SHOW_SIGNATURES:
+ e_mail_config_identity_page_set_show_signatures (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_identity_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_IDENTITY_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_identity_page_get_identity_source (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object)));
+ return;
+
+ case PROP_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_config_identity_page_get_registry (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object)));
+ return;
+
+ case PROP_SHOW_ACCOUNT_INFO:
+ g_value_set_boolean (
+ value,
+ e_mail_config_identity_page_get_show_account_info (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object)));
+ return;
+
+ case PROP_SHOW_INSTRUCTIONS:
+ g_value_set_boolean (
+ value,
+ e_mail_config_identity_page_get_show_instructions (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object)));
+ return;
+
+ case PROP_SHOW_SIGNATURES:
+ g_value_set_boolean (
+ value,
+ e_mail_config_identity_page_get_show_signatures (
+ E_MAIL_CONFIG_IDENTITY_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_identity_page_dispose (GObject *object)
+{
+ EMailConfigIdentityPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_IDENTITY_PAGE_GET_PRIVATE (object);
+
+ if (priv->identity_source != NULL) {
+ g_object_unref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ if (priv->registry != NULL) {
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_identity_page_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_identity_page_constructed (GObject *object)
+{
+ EMailConfigIdentityPage *page;
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceMailIdentity *extension;
+ GtkLabel *label;
+ GtkWidget *widget;
+ GtkWidget *container;
+ GtkSizeGroup *size_group;
+ const gchar *extension_name;
+ const gchar *text;
+ gchar *markup;
+
+ page = E_MAIL_CONFIG_IDENTITY_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_identity_page_parent_class)->
+ constructed (object);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ registry = e_mail_config_identity_page_get_registry (page);
+ source = e_mail_config_identity_page_get_identity_source (page);
+ extension = e_source_get_extension (source, extension_name);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ /* This keeps all mnemonic labels the same width. */
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ gtk_size_group_set_ignore_hidden (size_group, TRUE);
+
+ text = _("Please enter your name and email address below. "
+ "The \"optional\" fields below do not need to be filled "
+ "in, unless you wish to include this information in email "
+ "you send.");
+ widget = gtk_label_new (text);
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+
+ g_object_bind_property (
+ page, "show-instructions",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ /*** Account Information ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+
+ g_object_bind_property (
+ page, "show-account-info",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ container = widget;
+
+ text = _("Account Information");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Type the name by which you would like to refer to "
+ "this account.\nFor example, \"Work\" or \"Personal\".");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 2, 1);
+ gtk_widget_show (widget);
+
+ text = _("_Name:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ source, "display-name",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /* This entry affects the "check-complete" result. */
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (e_mail_config_page_changed), page);
+
+ /*** Required Information ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Required Information");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Full Nam_e:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ extension, "name",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /* This entry affects the "check-complete" result. */
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (e_mail_config_page_changed), page);
+
+ text = _("Email _Address:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ extension, "address",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /* This entry affects the "check-complete" result. */
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (e_mail_config_page_changed), page);
+
+ /*** Optional Information ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Optional Information");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 3, 1);
+ gtk_widget_show (widget);
+
+ text = _("Re_ply-To:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 2, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ extension, "reply-to",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /* This entry affects the "check-complete" result. */
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (e_mail_config_page_changed), page);
+
+ text = _("Or_ganization:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 2, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ extension, "organization",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ text = _("Si_gnature:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 3, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ page, "show-signatures",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ label = GTK_LABEL (widget);
+
+ widget = e_mail_signature_combo_box_new (registry);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_halign (widget, GTK_ALIGN_START);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 3, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ extension, "signature-uid",
+ widget, "active-id",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ page, "show-signatures",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ text = _("Add Ne_w Signature...");
+ widget = gtk_button_new_with_mnemonic (text);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 3, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ page, "show-signatures",
+ widget, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (mail_config_identity_page_add_signature_cb), page);
+
+ g_object_unref (size_group);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static gboolean
+mail_config_identity_page_check_complete (EMailConfigPage *page)
+{
+ EMailConfigIdentityPage *id_page;
+ ESource *source;
+ ESourceMailIdentity *extension;
+ const gchar *extension_name;
+ const gchar *name;
+ const gchar *address;
+ const gchar *reply_to;
+ const gchar *display_name;
+
+ id_page = E_MAIL_CONFIG_IDENTITY_PAGE (page);
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ source = e_mail_config_identity_page_get_identity_source (id_page);
+ extension = e_source_get_extension (source, extension_name);
+
+ name = e_source_mail_identity_get_name (extension);
+ address = e_source_mail_identity_get_address (extension);
+ reply_to = e_source_mail_identity_get_reply_to (extension);
+
+ display_name = e_source_get_display_name (source);
+
+ if (name == NULL)
+ return FALSE;
+
+ if (address == NULL)
+ return FALSE;
+
+ if (!mail_config_identity_page_is_email (address))
+ return FALSE;
+
+ /* A NULL reply_to string is allowed. */
+ if (reply_to != NULL && !mail_config_identity_page_is_email (reply_to))
+ return FALSE;
+
+ /* Only enforce when account information is visible. */
+ if (e_mail_config_identity_page_get_show_account_info (id_page))
+ if (display_name == NULL || *display_name == '\0')
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+e_mail_config_identity_page_class_init (EMailConfigIdentityPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigIdentityPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_identity_page_set_property;
+ object_class->get_property = mail_config_identity_page_get_property;
+ object_class->dispose = mail_config_identity_page_dispose;
+ object_class->constructed = mail_config_identity_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_REGISTRY,
+ g_param_spec_object (
+ "registry",
+ "Registry",
+ "Registry of data sources",
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IDENTITY_SOURCE,
+ g_param_spec_object (
+ "identity-source",
+ "Identity Source",
+ "Mail identity source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_ACCOUNT_INFO,
+ g_param_spec_boolean (
+ "show-account-info",
+ "Show Account Info",
+ "Show the \"Account Information\" section",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_INSTRUCTIONS,
+ g_param_spec_boolean (
+ "show-instructions",
+ "Show Instructions",
+ "Show helpful instructions",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_SIGNATURES,
+ g_param_spec_boolean (
+ "show-signatures",
+ "Show Signatures",
+ "Show mail signature options",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_identity_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Identity");
+ interface->sort_order = E_MAIL_CONFIG_IDENTITY_PAGE_SORT_ORDER;
+ interface->check_complete = mail_config_identity_page_check_complete;
+}
+
+static void
+e_mail_config_identity_page_init (EMailConfigIdentityPage *page)
+{
+ page->priv = E_MAIL_CONFIG_IDENTITY_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_identity_page_new (ESourceRegistry *registry,
+ ESource *identity_source)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (identity_source), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_IDENTITY_PAGE,
+ "registry", registry,
+ "identity-source", identity_source,
+ NULL);
+}
+
+ESourceRegistry *
+e_mail_config_identity_page_get_registry (EMailConfigIdentityPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page), NULL);
+
+ return page->priv->registry;
+}
+
+ESource *
+e_mail_config_identity_page_get_identity_source (EMailConfigIdentityPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page), NULL);
+
+ return page->priv->identity_source;
+}
+
+gboolean
+e_mail_config_identity_page_get_show_account_info (EMailConfigIdentityPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
+
+ return page->priv->show_account_info;
+}
+
+void
+e_mail_config_identity_page_set_show_account_info (EMailConfigIdentityPage *page,
+ gboolean show_account_info)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+ page->priv->show_account_info = show_account_info;
+
+ g_object_notify (G_OBJECT (page), "show-account-info");
+}
+
+gboolean
+e_mail_config_identity_page_get_show_instructions (EMailConfigIdentityPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
+
+ return page->priv->show_instructions;
+}
+
+void
+e_mail_config_identity_page_set_show_instructions (EMailConfigIdentityPage *page,
+ gboolean show_instructions)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+ page->priv->show_instructions = show_instructions;
+
+ g_object_notify (G_OBJECT (page), "show-instructions");
+}
+
+gboolean
+e_mail_config_identity_page_get_show_signatures (EMailConfigIdentityPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
+
+ return page->priv->show_signatures;
+}
+
+void
+e_mail_config_identity_page_set_show_signatures (EMailConfigIdentityPage *page,
+ gboolean show_signatures)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_IDENTITY_PAGE (page));
+
+ page->priv->show_signatures = show_signatures;
+
+ g_object_notify (G_OBJECT (page), "show-signatures");
+}
+
diff --git a/mail/e-mail-config-identity-page.h b/mail/e-mail-config-identity-page.h
new file mode 100644
index 0000000000..51d879e45f
--- /dev/null
+++ b/mail/e-mail-config-identity-page.h
@@ -0,0 +1,91 @@
+/*
+ * e-mail-config-identity-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_IDENTITY_PAGE_H
+#define E_MAIL_CONFIG_IDENTITY_PAGE_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-source-registry.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_IDENTITY_PAGE \
+ (e_mail_config_identity_page_get_type ())
+#define E_MAIL_CONFIG_IDENTITY_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_IDENTITY_PAGE, EMailConfigIdentityPage))
+#define E_MAIL_CONFIG_IDENTITY_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_IDENTITY_PAGE, EMailConfigIdentityPageClass))
+#define E_IS_MAIL_CONFIG_IDENTITY_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_IDENTITY_PAGE))
+#define E_IS_MAIL_CONFIG_IDENTITY_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_IDENTITY_PAGE))
+#define E_MAIL_CONFIG_IDENTITY_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_IDENTITY_PAGE, EMailConfigIdentityPageClass))
+
+#define E_MAIL_CONFIG_IDENTITY_PAGE_SORT_ORDER (100)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigIdentityPage EMailConfigIdentityPage;
+typedef struct _EMailConfigIdentityPageClass EMailConfigIdentityPageClass;
+typedef struct _EMailConfigIdentityPagePrivate EMailConfigIdentityPagePrivate;
+
+struct _EMailConfigIdentityPage {
+ GtkBox parent;
+ EMailConfigIdentityPagePrivate *priv;
+};
+
+struct _EMailConfigIdentityPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_identity_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_identity_page_new (ESourceRegistry *registry,
+ ESource *identity_source);
+ESourceRegistry *
+ e_mail_config_identity_page_get_registry
+ (EMailConfigIdentityPage *page);
+ESource * e_mail_config_identity_page_get_identity_source
+ (EMailConfigIdentityPage *page);
+gboolean e_mail_config_identity_page_get_show_account_info
+ (EMailConfigIdentityPage *page);
+void e_mail_config_identity_page_set_show_account_info
+ (EMailConfigIdentityPage *page,
+ gboolean show_account_info);
+gboolean e_mail_config_identity_page_get_show_instructions
+ (EMailConfigIdentityPage *page);
+void e_mail_config_identity_page_set_show_instructions
+ (EMailConfigIdentityPage *page,
+ gboolean show_instructions);
+gboolean e_mail_config_identity_page_get_show_signatures
+ (EMailConfigIdentityPage *page);
+void e_mail_config_identity_page_set_show_signatures
+ (EMailConfigIdentityPage *page,
+ gboolean show_signatures);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_IDENTITY_PAGE_H */
diff --git a/mail/e-mail-config-lookup-page.c b/mail/e-mail-config-lookup-page.c
new file mode 100644
index 0000000000..0154a053b1
--- /dev/null
+++ b/mail/e-mail-config-lookup-page.c
@@ -0,0 +1,109 @@
+/*
+ * e-mail-config-lookup-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-lookup-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+/* Forward Declarations */
+static void e_mail_config_lookup_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigLookupPage,
+ e_mail_config_lookup_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE(
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_lookup_page_interface_init))
+
+static void
+mail_config_lookup_page_constructed (GObject *object)
+{
+ EMailConfigLookupPage *page;
+ GtkWidget *container;
+ GtkWidget *widget;
+ const gchar *text;
+
+ page = E_MAIL_CONFIG_LOOKUP_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_lookup_page_parent_class)->
+ constructed (object);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ gtk_widget_set_valign (GTK_WIDGET (page), GTK_ALIGN_FILL);
+
+ widget = gtk_alignment_new (0.5, 0.5, 0.5, 0.5);
+ gtk_box_pack_start (GTK_BOX (page), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = gtk_spinner_new ();
+ gtk_spinner_start (GTK_SPINNER (widget));
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ text = _("Looking up account details...");
+ widget = gtk_label_new (text);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+}
+
+static gboolean
+mail_config_lookup_page_check_complete (EMailConfigPage *page)
+{
+ return FALSE;
+}
+
+static void
+e_mail_config_lookup_page_class_init (EMailConfigLookupPageClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructed = mail_config_lookup_page_constructed;
+}
+
+static void
+e_mail_config_lookup_page_interface_init (EMailConfigPageInterface *interface)
+{
+ /* Do not set a title. We don't want this
+ * page listed in a GtkAssistant sidebar. */
+ interface->title = "";
+ interface->sort_order = E_MAIL_CONFIG_LOOKUP_PAGE_SORT_ORDER;
+ interface->page_type = GTK_ASSISTANT_PAGE_CUSTOM;
+ interface->check_complete = mail_config_lookup_page_check_complete;
+}
+
+static void
+e_mail_config_lookup_page_init (EMailConfigLookupPage *page)
+{
+}
+
+EMailConfigPage *
+e_mail_config_lookup_page_new ()
+{
+ return g_object_new (E_TYPE_MAIL_CONFIG_LOOKUP_PAGE, NULL);
+}
diff --git a/mail/e-mail-config-lookup-page.h b/mail/e-mail-config-lookup-page.h
new file mode 100644
index 0000000000..bbf9db3892
--- /dev/null
+++ b/mail/e-mail-config-lookup-page.h
@@ -0,0 +1,73 @@
+/*
+ * e-mail-config-lookup-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_LOOKUP_PAGE_H
+#define E_MAIL_CONFIG_LOOKUP_PAGE_H
+
+#include <gtk/gtk.h>
+
+#include <mail/e-mail-config-identity-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_LOOKUP_PAGE \
+ (e_mail_config_lookup_page_get_type ())
+#define E_MAIL_CONFIG_LOOKUP_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_LOOKUP_PAGE, EMailConfigLookupPage))
+#define E_MAIL_CONFIG_LOOKUP_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_LOOKUP_PAGE, EMailConfigLookupPageClass))
+#define E_IS_MAIL_CONFIG_LOOKUP_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_LOOKUP_PAGE))
+#define E_IS_MAIL_CONFIG_LOOKUP_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_LOOKUP_PAGE))
+#define E_MAIL_CONFIG_LOOKUP_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_LOOKUP_PAGE, EMailConfigLookupPageClass))
+
+/* Since this is a transient page we define the sort order
+ * as the previous page's sort order plus a small offset. */
+#define E_MAIL_CONFIG_LOOKUP_PAGE_SORT_ORDER \
+ (E_MAIL_CONFIG_IDENTITY_PAGE_SORT_ORDER + 10)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigLookupPage EMailConfigLookupPage;
+typedef struct _EMailConfigLookupPageClass EMailConfigLookupPageClass;
+typedef struct _EMailConfigLookupPagePrivate EMailConfigLookupPagePrivate;
+
+struct _EMailConfigLookupPage {
+ GtkBox parent;
+ EMailConfigLookupPagePrivate *priv;
+};
+
+struct _EMailConfigLookupPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_lookup_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_lookup_page_new (void);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_LOOKUP_PAGE_H */
+
diff --git a/mail/e-mail-config-notebook.c b/mail/e-mail-config-notebook.c
new file mode 100644
index 0000000000..999ee1baf2
--- /dev/null
+++ b/mail/e-mail-config-notebook.c
@@ -0,0 +1,783 @@
+/*
+ * e-mail-config-notebook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-notebook.h"
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-goa.h>
+#include <libedataserver/e-source-mail-identity.h>
+
+#include <mail/e-mail-config-defaults-page.h>
+#include <mail/e-mail-config-identity-page.h>
+#include <mail/e-mail-config-provider-page.h>
+#include <mail/e-mail-config-receiving-page.h>
+#include <mail/e-mail-config-security-page.h>
+#include <mail/e-mail-config-sending-page.h>
+
+#define E_MAIL_CONFIG_NOTEBOOK_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_NOTEBOOK, EMailConfigNotebookPrivate))
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _EMailConfigNotebookPrivate {
+ EMailSession *session;
+ ESource *account_source;
+ ESource *identity_source;
+ ESource *transport_source;
+ ESource *collection_source;
+};
+
+struct _AsyncContext {
+ ESourceRegistry *registry;
+ GCancellable *cancellable;
+ GQueue *source_queue;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_SOURCE,
+ PROP_COLLECTION_SOURCE,
+ PROP_COMPLETE,
+ PROP_IDENTITY_SOURCE,
+ PROP_SESSION,
+ PROP_TRANSPORT_SOURCE
+};
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigNotebook,
+ e_mail_config_notebook,
+ GTK_TYPE_NOTEBOOK,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL))
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->registry != NULL)
+ g_object_unref (async_context->registry);
+
+ if (async_context->cancellable != NULL)
+ g_object_unref (async_context->cancellable);
+
+ g_queue_free_full (
+ async_context->source_queue,
+ (GDestroyNotify) g_object_unref);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+mail_config_notebook_sort_pages (EMailConfigNotebook *notebook)
+{
+ GList *list, *link;
+ gint ii = 0;
+
+ list = g_list_sort (
+ gtk_container_get_children (GTK_CONTAINER (notebook)),
+ (GCompareFunc) e_mail_config_page_compare);
+
+ for (link = list; link != NULL; link = g_list_next (link))
+ gtk_notebook_reorder_child (
+ GTK_NOTEBOOK (notebook),
+ GTK_WIDGET (link->data), ii++);
+
+ g_list_free (list);
+}
+
+static void
+mail_config_notebook_page_changed (EMailConfigPage *page,
+ EMailConfigNotebook *notebook)
+{
+ g_object_notify (G_OBJECT (notebook), "complete");
+}
+
+static void
+mail_config_notebook_set_account_source (EMailConfigNotebook *notebook,
+ ESource *account_source)
+{
+ g_return_if_fail (E_IS_SOURCE (account_source));
+ g_return_if_fail (notebook->priv->account_source == NULL);
+
+ notebook->priv->account_source = g_object_ref (account_source);
+}
+
+static void
+mail_config_notebook_set_collection_source (EMailConfigNotebook *notebook,
+ ESource *collection_source)
+{
+ g_return_if_fail (notebook->priv->collection_source == NULL);
+
+ if (collection_source != NULL) {
+ g_return_if_fail (E_IS_SOURCE (collection_source));
+ g_object_ref (collection_source);
+ }
+
+ notebook->priv->collection_source = collection_source;
+}
+
+static void
+mail_config_notebook_set_identity_source (EMailConfigNotebook *notebook,
+ ESource *identity_source)
+{
+ g_return_if_fail (E_IS_SOURCE (identity_source));
+ g_return_if_fail (notebook->priv->identity_source == NULL);
+
+ notebook->priv->identity_source = g_object_ref (identity_source);
+}
+
+static void
+mail_config_notebook_set_session (EMailConfigNotebook *notebook,
+ EMailSession *session)
+{
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (notebook->priv->session == NULL);
+
+ notebook->priv->session = g_object_ref (session);
+}
+
+static void
+mail_config_notebook_set_transport_source (EMailConfigNotebook *notebook,
+ ESource *transport_source)
+{
+ g_return_if_fail (E_IS_SOURCE (transport_source));
+ g_return_if_fail (notebook->priv->transport_source == NULL);
+
+ notebook->priv->transport_source = g_object_ref (transport_source);
+}
+
+static void
+mail_config_notebook_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_SOURCE:
+ mail_config_notebook_set_account_source (
+ E_MAIL_CONFIG_NOTEBOOK (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_COLLECTION_SOURCE:
+ mail_config_notebook_set_collection_source (
+ E_MAIL_CONFIG_NOTEBOOK (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ mail_config_notebook_set_identity_source (
+ E_MAIL_CONFIG_NOTEBOOK (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SESSION:
+ mail_config_notebook_set_session (
+ E_MAIL_CONFIG_NOTEBOOK (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_TRANSPORT_SOURCE:
+ mail_config_notebook_set_transport_source (
+ E_MAIL_CONFIG_NOTEBOOK (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_notebook_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_notebook_get_account_source (
+ E_MAIL_CONFIG_NOTEBOOK (object)));
+ return;
+
+ case PROP_COLLECTION_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_notebook_get_collection_source (
+ E_MAIL_CONFIG_NOTEBOOK (object)));
+ return;
+
+ case PROP_COMPLETE:
+ g_value_set_boolean (
+ value,
+ e_mail_config_notebook_check_complete (
+ E_MAIL_CONFIG_NOTEBOOK (object)));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_notebook_get_identity_source (
+ E_MAIL_CONFIG_NOTEBOOK (object)));
+ return;
+
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ e_mail_config_notebook_get_session (
+ E_MAIL_CONFIG_NOTEBOOK (object)));
+ return;
+
+ case PROP_TRANSPORT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_notebook_get_transport_source (
+ E_MAIL_CONFIG_NOTEBOOK (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_notebook_dispose (GObject *object)
+{
+ EMailConfigNotebookPrivate *priv;
+
+ priv = E_MAIL_CONFIG_NOTEBOOK_GET_PRIVATE (object);
+
+ if (priv->session != NULL) {
+ g_object_ref (priv->session);
+ priv->session = NULL;
+ }
+
+ if (priv->account_source != NULL) {
+ g_object_ref (priv->account_source);
+ priv->account_source = NULL;
+ }
+
+ if (priv->identity_source != NULL) {
+ g_object_ref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ if (priv->transport_source != NULL) {
+ g_object_ref (priv->transport_source);
+ priv->transport_source = NULL;
+ }
+
+ if (priv->collection_source != NULL) {
+ g_object_ref (priv->collection_source);
+ priv->collection_source = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_notebook_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_notebook_constructed (GObject *object)
+{
+ EMailConfigNotebook *notebook;
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceExtension *extension;
+ ESourceMailIdentity *mail_identity_extension;
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider;
+ EMailSession *session;
+ EMailConfigPage *page;
+ const gchar *extension_name;
+ gboolean add_receiving_page = TRUE;
+ gboolean add_sending_page = TRUE;
+
+ notebook = E_MAIL_CONFIG_NOTEBOOK (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_notebook_parent_class)->
+ constructed (object);
+
+ session = e_mail_config_notebook_get_session (notebook);
+ registry = e_mail_session_get_registry (session);
+
+ source = notebook->priv->identity_source;
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (source, extension_name);
+ mail_identity_extension = E_SOURCE_MAIL_IDENTITY (extension);
+
+ /* If we have a collection source and the collection source
+ * has a [GNOME Online Accounts] extension, skip the Receiving
+ * and Sending pages since GOA dictates those settings. */
+ source = notebook->priv->collection_source;
+ if (source != NULL) {
+ extension_name = E_SOURCE_EXTENSION_GOA;
+ if (e_source_has_extension (source, extension_name)) {
+ add_receiving_page = FALSE;
+ add_sending_page = FALSE;
+ }
+ }
+
+ /*** Identity Page ***/
+
+ page = e_mail_config_identity_page_new (
+ registry, notebook->priv->identity_source);
+ e_mail_config_identity_page_set_show_instructions (
+ E_MAIL_CONFIG_IDENTITY_PAGE (page), FALSE);
+ e_mail_config_notebook_add_page (notebook, page);
+
+ /*** Receiving Page ***/
+
+ page = e_mail_config_receiving_page_new (registry);
+ backend = e_mail_config_service_page_add_scratch_source (
+ E_MAIL_CONFIG_SERVICE_PAGE (page),
+ notebook->priv->account_source,
+ notebook->priv->collection_source);
+ if (add_receiving_page) {
+ e_mail_config_notebook_add_page (notebook, page);
+
+ g_object_bind_property (
+ mail_identity_extension, "address",
+ page, "email-address",
+ G_BINDING_SYNC_CREATE);
+ }
+
+ provider = e_mail_config_service_backend_get_provider (backend);
+
+ /*** Receiving Options (conditional) ***/
+
+ /* Note: We exclude this page if it has no options,
+ * but we don't know that until we create it. */
+ page = e_mail_config_provider_page_new (backend);
+ if (e_mail_config_provider_page_is_empty (
+ E_MAIL_CONFIG_PROVIDER_PAGE (page))) {
+ g_object_unref (g_object_ref_sink (page));
+ } else {
+ e_mail_config_notebook_add_page (notebook, page);
+ }
+
+ /*** Sending Page (conditional) ***/
+
+ if (!CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) {
+ page = e_mail_config_sending_page_new (registry);
+ e_mail_config_service_page_add_scratch_source (
+ E_MAIL_CONFIG_SERVICE_PAGE (page),
+ notebook->priv->transport_source,
+ notebook->priv->collection_source);
+ if (add_sending_page) {
+ e_mail_config_notebook_add_page (notebook, page);
+
+ g_object_bind_property (
+ mail_identity_extension, "address",
+ page, "email-address",
+ G_BINDING_SYNC_CREATE);
+ }
+ }
+
+ /*** Defaults Page ***/
+
+ page = e_mail_config_defaults_page_new (
+ session,
+ notebook->priv->account_source,
+ notebook->priv->identity_source);
+ e_mail_config_notebook_add_page (notebook, page);
+
+ /*** Security Page ***/
+
+ page = e_mail_config_security_page_new (
+ notebook->priv->identity_source);
+ e_mail_config_notebook_add_page (notebook, page);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (notebook));
+}
+
+static void
+mail_config_notebook_page_removed (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint page_num)
+{
+ /* Do not chain up. GtkNotebook does not implement this method. */
+
+ if (E_IS_MAIL_CONFIG_PAGE (child))
+ g_signal_handlers_disconnect_by_func (
+ child, mail_config_notebook_page_changed,
+ E_MAIL_CONFIG_NOTEBOOK (notebook));
+}
+
+static void
+mail_config_notebook_page_added (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint page_num)
+{
+ /* Do not chain up. GtkNotebook does not implement this method. */
+
+ if (E_IS_MAIL_CONFIG_PAGE (child))
+ g_signal_connect (
+ child, "changed",
+ G_CALLBACK (mail_config_notebook_page_changed),
+ E_MAIL_CONFIG_NOTEBOOK (notebook));
+}
+
+static void
+e_mail_config_notebook_class_init (EMailConfigNotebookClass *class)
+{
+ GObjectClass *object_class;
+ GtkNotebookClass *notebook_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigNotebookPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_notebook_set_property;
+ object_class->get_property = mail_config_notebook_get_property;
+ object_class->dispose = mail_config_notebook_dispose;
+ object_class->constructed = mail_config_notebook_constructed;
+
+ notebook_class = GTK_NOTEBOOK_CLASS (class);
+ notebook_class->page_removed = mail_config_notebook_page_removed;
+ notebook_class->page_added = mail_config_notebook_page_added;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_SOURCE,
+ g_param_spec_object (
+ "account-source",
+ "Account Source",
+ "Mail account source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COLLECTION_SOURCE,
+ g_param_spec_object (
+ "collection-source",
+ "Collection Source",
+ "Optional collection source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COMPLETE,
+ g_param_spec_boolean (
+ "complete",
+ "Complete",
+ "Whether all required fields are complete",
+ FALSE, /* default is not used */
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IDENTITY_SOURCE,
+ g_param_spec_object (
+ "identity-source",
+ "Identity Source",
+ "Mail identity source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "Mail session",
+ E_TYPE_MAIL_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TRANSPORT_SOURCE,
+ g_param_spec_object (
+ "transport-source",
+ "Transport Source",
+ "Mail transport source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_notebook_init (EMailConfigNotebook *notebook)
+{
+ notebook->priv = E_MAIL_CONFIG_NOTEBOOK_GET_PRIVATE (notebook);
+}
+
+GtkWidget *
+e_mail_config_notebook_new (EMailSession *session,
+ ESource *account_source,
+ ESource *identity_source,
+ ESource *transport_source,
+ ESource *collection_source)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (account_source), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (identity_source), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (transport_source), NULL);
+
+ /* A collection source is optional. */
+ if (collection_source != NULL)
+ g_return_val_if_fail (E_IS_SOURCE (collection_source), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_NOTEBOOK,
+ "session", session,
+ "account-source", account_source,
+ "identity-source", identity_source,
+ "transport-source", transport_source,
+ "collection-source", collection_source,
+ NULL);
+}
+
+EMailSession *
+e_mail_config_notebook_get_session (EMailConfigNotebook *notebook)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
+
+ return notebook->priv->session;
+}
+
+ESource *
+e_mail_config_notebook_get_account_source (EMailConfigNotebook *notebook)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
+
+ return notebook->priv->account_source;
+}
+
+ESource *
+e_mail_config_notebook_get_identity_source (EMailConfigNotebook *notebook)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
+
+ return notebook->priv->identity_source;
+}
+
+ESource *
+e_mail_config_notebook_get_transport_source (EMailConfigNotebook *notebook)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
+
+ return notebook->priv->transport_source;
+}
+
+ESource *
+e_mail_config_notebook_get_collection_source (EMailConfigNotebook *notebook)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
+
+ return notebook->priv->collection_source;
+}
+
+void
+e_mail_config_notebook_add_page (EMailConfigNotebook *notebook,
+ EMailConfigPage *page)
+{
+ EMailConfigPageInterface *page_interface;
+ GtkWidget *tab_label;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook));
+ g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
+
+ page_interface = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page);
+ tab_label = gtk_label_new (page_interface->title);
+
+ gtk_widget_show (GTK_WIDGET (page));
+
+ gtk_notebook_append_page (
+ GTK_NOTEBOOK (notebook),
+ GTK_WIDGET (page), tab_label);
+
+ mail_config_notebook_sort_pages (notebook);
+}
+
+gboolean
+e_mail_config_notebook_check_complete (EMailConfigNotebook *notebook)
+{
+ GList *list, *link;
+ gboolean complete = TRUE;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), FALSE);
+
+ list = gtk_container_get_children (GTK_CONTAINER (notebook));
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ if (E_IS_MAIL_CONFIG_PAGE (link->data)) {
+ EMailConfigPage *page;
+ page = E_MAIL_CONFIG_PAGE (link->data);
+ complete = e_mail_config_page_check_complete (page);
+
+ if (!complete)
+ break;
+ }
+ }
+
+ g_list_free (list);
+
+ return complete;
+}
+
+/********************** e_mail_config_notebook_commit() **********************/
+
+static void
+mail_config_notebook_commit_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ ESource *next_source;
+ GError *error = NULL;
+
+ simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ e_source_registry_commit_source_finish (
+ E_SOURCE_REGISTRY (object), result, &error);
+
+ if (error != NULL) {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ next_source = g_queue_pop_head (async_context->source_queue);
+
+ if (next_source == NULL) {
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ return;
+ }
+
+ e_source_registry_commit_source (
+ async_context->registry, next_source,
+ async_context->cancellable,
+ mail_config_notebook_commit_cb, simple);
+
+ g_object_unref (next_source);
+}
+
+void
+e_mail_config_notebook_commit (EMailConfigNotebook *notebook,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ ESourceRegistry *registry;
+ EMailSession *session;
+ ESource *source;
+ GList *list, *link;
+ GQueue *queue;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook));
+
+ session = e_mail_config_notebook_get_session (notebook);
+ registry = e_mail_session_get_registry (session);
+
+ queue = g_queue_new ();
+
+ /* Queue the collection data source if one is defined. */
+ source = e_mail_config_notebook_get_collection_source (notebook);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+
+ /* Queue the mail-related data sources for the account. */
+ source = e_mail_config_notebook_get_account_source (notebook);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+ source = e_mail_config_notebook_get_identity_source (notebook);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+ source = e_mail_config_notebook_get_transport_source (notebook);
+ if (source != NULL)
+ g_queue_push_tail (queue, g_object_ref (source));
+
+ list = gtk_container_get_children (GTK_CONTAINER (notebook));
+
+ /* Tell all EMailConfigPages to commit their UI state to their
+ * scratch ESources and push any additional data sources on to
+ * the given source queue, such as calendars or address books
+ * to be bundled with the mail account. */
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ if (E_IS_MAIL_CONFIG_PAGE (link->data)) {
+ EMailConfigPage *page;
+ page = E_MAIL_CONFIG_PAGE (link->data);
+ e_mail_config_page_commit_changes (page, queue);
+ }
+ }
+
+ g_list_free (list);
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->registry = g_object_ref (registry);
+ async_context->source_queue = queue; /* takes ownership */
+
+ if (G_IS_CANCELLABLE (cancellable))
+ async_context->cancellable = g_object_ref (cancellable);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (notebook), callback, user_data,
+ e_mail_config_notebook_commit);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, async_context, (GDestroyNotify) async_context_free);
+
+ source = g_queue_pop_head (async_context->source_queue);
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ e_source_registry_commit_source (
+ async_context->registry, source,
+ async_context->cancellable,
+ mail_config_notebook_commit_cb, simple);
+
+ g_object_unref (source);
+}
+
+gboolean
+e_mail_config_notebook_commit_finish (EMailConfigNotebook *notebook,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (
+ g_simple_async_result_is_valid (
+ result, G_OBJECT (notebook),
+ e_mail_config_notebook_commit), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ /* Assume success unless a GError is set. */
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
diff --git a/mail/e-mail-config-notebook.h b/mail/e-mail-config-notebook.h
new file mode 100644
index 0000000000..3e816c69b4
--- /dev/null
+++ b/mail/e-mail-config-notebook.h
@@ -0,0 +1,98 @@
+/*
+ * e-mail-config-notebook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_NOTEBOOK_H
+#define E_MAIL_CONFIG_NOTEBOOK_H
+
+#include <gtk/gtk.h>
+
+#include <libemail-engine/e-mail-session.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_NOTEBOOK \
+ (e_mail_config_notebook_get_type ())
+#define E_MAIL_CONFIG_NOTEBOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_NOTEBOOK, EMailConfigNotebook))
+#define E_MAIL_CONFIG_NOTEBOOK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_NOTEBOOK, EMailConfigNotebookClass))
+#define E_IS_MAIL_CONFIG_NOTEBOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_NOTEBOOK))
+#define E_IS_MAIL_CONFIG_NOTEBOOK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_NOTEBOOK))
+#define E_MAIL_CONFIG_NOTEBOOK_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_NOTEBOOK, EMailConfigNotebookClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigNotebook EMailConfigNotebook;
+typedef struct _EMailConfigNotebookClass EMailConfigNotebookClass;
+typedef struct _EMailConfigNotebookPrivate EMailConfigNotebookPrivate;
+
+struct _EMailConfigNotebook {
+ GtkNotebook parent;
+ EMailConfigNotebookPrivate *priv;
+};
+
+struct _EMailConfigNotebookClass {
+ GtkNotebookClass parent_class;
+};
+
+GType e_mail_config_notebook_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_config_notebook_new
+ (EMailSession *session,
+ ESource *account_source,
+ ESource *identity_source,
+ ESource *transport_source,
+ ESource *collection_source);
+EMailSession * e_mail_config_notebook_get_session
+ (EMailConfigNotebook *notebook);
+ESource * e_mail_config_notebook_get_account_source
+ (EMailConfigNotebook *notebook);
+ESource * e_mail_config_notebook_get_identity_source
+ (EMailConfigNotebook *notebook);
+ESource * e_mail_config_notebook_get_transport_source
+ (EMailConfigNotebook *notebook);
+ESource * e_mail_config_notebook_get_collection_source
+ (EMailConfigNotebook *notebook);
+void e_mail_config_notebook_add_page
+ (EMailConfigNotebook *notebook,
+ EMailConfigPage *page);
+gboolean e_mail_config_notebook_check_complete
+ (EMailConfigNotebook *notebook);
+void e_mail_config_notebook_commit
+ (EMailConfigNotebook *notebook,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_mail_config_notebook_commit_finish
+ (EMailConfigNotebook *notebook,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_NOTEBOOK_H */
+
diff --git a/mail/e-mail-config-page.c b/mail/e-mail-config-page.c
new file mode 100644
index 0000000000..29d18e8da6
--- /dev/null
+++ b/mail/e-mail-config-page.c
@@ -0,0 +1,176 @@
+/*
+ * e-mail-config-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <e-util/e-marshal.h>
+
+enum {
+ CHANGED,
+ SETUP_DEFAULTS,
+ CHECK_COMPLETE,
+ COMMIT_CHANGES,
+ LAST_SIGNAL
+};
+
+static gulong signals[LAST_SIGNAL];
+
+G_DEFINE_INTERFACE (
+ EMailConfigPage,
+ e_mail_config_page,
+ GTK_TYPE_WIDGET)
+
+static gboolean
+mail_config_page_check_complete (EMailConfigPage *page)
+{
+ return TRUE;
+}
+
+static gboolean
+mail_config_page_check_complete_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer unused)
+{
+ gboolean v_boolean;
+
+ /* Abort emission if a handler returns FALSE. */
+ v_boolean = g_value_get_boolean (handler_return);
+ g_value_set_boolean (return_accu, v_boolean);
+
+ return v_boolean;
+}
+
+static void
+e_mail_config_page_default_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Untitled");
+ interface->page_type = GTK_ASSISTANT_PAGE_CONTENT;
+
+ interface->check_complete = mail_config_page_check_complete;
+
+ signals[CHANGED] = g_signal_new (
+ "changed",
+ G_TYPE_FROM_INTERFACE (interface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailConfigPageInterface, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SETUP_DEFAULTS] = g_signal_new (
+ "setup-defaults",
+ G_TYPE_FROM_INTERFACE (interface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailConfigPageInterface, setup_defaults),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CHECK_COMPLETE] = g_signal_new (
+ "check-complete",
+ G_TYPE_FROM_INTERFACE (interface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailConfigPageInterface, check_complete),
+ mail_config_page_check_complete_accumulator, NULL,
+ e_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ signals[COMMIT_CHANGES] = g_signal_new (
+ "commit-changes",
+ G_TYPE_FROM_INTERFACE (interface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailConfigPageInterface, commit_changes),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+}
+
+void
+e_mail_config_page_changed (EMailConfigPage *page)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
+
+ g_signal_emit (page, signals[CHANGED], 0);
+}
+
+void
+e_mail_config_page_setup_defaults (EMailConfigPage *page)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
+
+ g_signal_emit (page, signals[SETUP_DEFAULTS], 0);
+}
+
+gboolean
+e_mail_config_page_check_complete (EMailConfigPage *page)
+{
+ gboolean complete;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_PAGE (page), FALSE);
+
+ g_signal_emit (page, signals[CHECK_COMPLETE], 0, &complete);
+
+ return complete;
+}
+
+void
+e_mail_config_page_commit_changes (EMailConfigPage *page,
+ GQueue *source_queue)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
+ g_return_if_fail (source_queue != NULL);
+
+ g_signal_emit (page, signals[COMMIT_CHANGES], 0, source_queue);
+}
+
+gint
+e_mail_config_page_compare (GtkWidget *page_a,
+ GtkWidget *page_b)
+{
+ EMailConfigPageInterface *interface_a = NULL;
+ EMailConfigPageInterface *interface_b = NULL;
+
+ if (E_IS_MAIL_CONFIG_PAGE (page_a))
+ interface_a = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page_a);
+
+ if (E_IS_MAIL_CONFIG_PAGE (page_b))
+ interface_b = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page_b);
+
+ if (interface_a == interface_b)
+ return 0;
+
+ if (interface_a != NULL && interface_b == NULL)
+ return -1;
+
+ if (interface_a == NULL && interface_b != NULL)
+ return 1;
+
+ if (interface_a->sort_order < interface_b->sort_order)
+ return -1;
+
+ if (interface_a->sort_order > interface_b->sort_order)
+ return 1;
+
+ return 0;
+}
+
diff --git a/mail/e-mail-config-page.h b/mail/e-mail-config-page.h
new file mode 100644
index 0000000000..40a949a2d5
--- /dev/null
+++ b/mail/e-mail-config-page.h
@@ -0,0 +1,72 @@
+/*
+ * e-mail-config-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_PAGE_H
+#define E_MAIL_CONFIG_PAGE_H
+
+#include <gtk/gtk.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_PAGE \
+ (e_mail_config_page_get_type ())
+#define E_MAIL_CONFIG_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_PAGE, EMailConfigPage))
+#define E_IS_MAIL_CONFIG_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_PAGE))
+#define E_MAIL_CONFIG_PAGE_GET_INTERFACE(obj) \
+ (G_TYPE_INSTANCE_GET_INTERFACE \
+ ((obj), E_TYPE_MAIL_CONFIG_PAGE, EMailConfigPageInterface))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigPage EMailConfigPage;
+typedef struct _EMailConfigPageInterface EMailConfigPageInterface;
+
+struct _EMailConfigPageInterface {
+ GTypeInterface parent_interface;
+
+ gint sort_order;
+ const gchar *title;
+ GtkAssistantPageType page_type;
+
+ /* Signals */
+ void (*changed) (EMailConfigPage *page);
+ void (*setup_defaults) (EMailConfigPage *page);
+ gboolean (*check_complete) (EMailConfigPage *page);
+ void (*commit_changes) (EMailConfigPage *page,
+ GQueue *source_queue);
+};
+
+GType e_mail_config_page_get_type (void) G_GNUC_CONST;
+void e_mail_config_page_changed (EMailConfigPage *page);
+void e_mail_config_page_setup_defaults
+ (EMailConfigPage *page);
+gboolean e_mail_config_page_check_complete
+ (EMailConfigPage *page);
+void e_mail_config_page_commit_changes
+ (EMailConfigPage *page,
+ GQueue *source_queue);
+gint e_mail_config_page_compare (GtkWidget *page_a,
+ GtkWidget *page_b);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_PAGE_H */
+
diff --git a/mail/e-mail-config-provider-page.c b/mail/e-mail-config-provider-page.c
new file mode 100644
index 0000000000..1474ff3263
--- /dev/null
+++ b/mail/e-mail-config-provider-page.c
@@ -0,0 +1,774 @@
+/*
+ * e-mail-config-provider-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-provider-page.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-data-server-util.h>
+
+#include <libevolution-utils/e-alert-sink.h>
+#include <libevolution-utils/e-alert-dialog.h>
+#include <misc/e-activity-bar.h>
+#include <misc/e-alert-bar.h>
+
+#define E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE, EMailConfigProviderPagePrivate))
+
+#define STANDARD_MARGIN 12
+#define DEPENDENCY_MARGIN 24
+
+struct _EMailConfigProviderPagePrivate {
+ EMailConfigServiceBackend *backend;
+ gboolean is_empty;
+
+ GtkWidget *activity_bar;
+ GtkWidget *alert_bar;
+};
+
+enum {
+ PROP_0,
+ PROP_BACKEND
+};
+
+/* Forward Declarations */
+static void e_mail_config_provider_page_alert_sink_init
+ (EAlertSinkInterface *interface);
+static void e_mail_config_provider_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigProviderPage,
+ e_mail_config_provider_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_ALERT_SINK,
+ e_mail_config_provider_page_alert_sink_init)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_provider_page_interface_init))
+
+static void
+mail_config_provider_page_handle_dependency (EMailConfigProviderPage *page,
+ CamelProviderConfEntry *entry,
+ GtkWidget *widget)
+{
+ EMailConfigServiceBackend *backend;
+ CamelSettings *settings;
+ GBindingFlags binding_flags = G_BINDING_SYNC_CREATE;
+ const gchar *depname = entry->depname;
+ gint margin;
+
+ if (depname == NULL)
+ return;
+
+ if (*depname == '!') {
+ binding_flags |= G_BINDING_INVERT_BOOLEAN;
+ depname++;
+ }
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ g_object_bind_property (
+ settings, depname,
+ widget, "sensitive",
+ binding_flags);
+
+ /* Further indent the widget to show its dependency. */
+ margin = gtk_widget_get_margin_left (widget);
+ gtk_widget_set_margin_left (widget, margin + DEPENDENCY_MARGIN);
+}
+
+static void
+mail_config_provider_page_add_section (EMailConfigProviderPage *page,
+ CamelProviderConfEntry *entry)
+{
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider;
+ GtkWidget *widget;
+ gchar *markup;
+
+ g_return_if_fail (entry->text != NULL);
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ provider = e_mail_config_service_backend_get_provider (backend);
+
+ markup = g_markup_printf_escaped ("<b>%s</b>", entry->text);
+
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ /* Skip the top margin if this is the first entry. */
+ if (entry != provider->extra_conf)
+ gtk_widget_set_margin_top (widget, 6);
+
+ g_free (markup);
+}
+
+static void
+mail_config_provider_page_add_checkbox (EMailConfigProviderPage *page,
+ CamelProviderConfEntry *entry)
+{
+ EMailConfigServiceBackend *backend;
+ CamelSettings *settings;
+ GtkWidget *widget;
+
+ g_return_if_fail (entry->text != NULL);
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ widget = gtk_check_button_new_with_mnemonic (entry->text);
+ gtk_widget_set_margin_left (widget, STANDARD_MARGIN);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ settings, entry->name,
+ widget, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ mail_config_provider_page_handle_dependency (page, entry, widget);
+}
+
+static void
+mail_config_provider_page_add_checkspin (EMailConfigProviderPage *page,
+ CamelProviderConfEntry *entry)
+{
+ EMailConfigServiceBackend *backend;
+ CamelSettings *settings;
+ GObjectClass *class;
+ GParamSpec *pspec;
+ GParamSpec *use_pspec;
+ GtkAdjustment *adjustment;
+ GtkWidget *hbox, *spin;
+ GtkWidget *prefix;
+ gchar *use_property_name;
+ gchar *pre, *post;
+
+ g_return_if_fail (entry->text != NULL);
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ /* The entry->name property (e.g. "foo") should be numeric for the
+ * spin button. If a "use" boolean property exists (e.g. "use-foo")
+ * then a checkbox is also shown. */
+
+ class = G_OBJECT_GET_CLASS (settings);
+ pspec = g_object_class_find_property (class, entry->name);
+ g_return_if_fail (pspec != NULL);
+
+ use_property_name = g_strconcat ("use-", entry->name, NULL);
+ use_pspec = g_object_class_find_property (class, use_property_name);
+ if (use_pspec != NULL && use_pspec->value_type != G_TYPE_BOOLEAN)
+ use_pspec = NULL;
+ g_free (use_property_name);
+
+ /* Make sure we can convert to and from doubles. */
+ g_return_if_fail (
+ g_value_type_transformable (
+ pspec->value_type, G_TYPE_DOUBLE));
+ g_return_if_fail (
+ g_value_type_transformable (
+ G_TYPE_DOUBLE, pspec->value_type));
+
+ if (G_IS_PARAM_SPEC_CHAR (pspec)) {
+ GParamSpecChar *pspec_char;
+ pspec_char = G_PARAM_SPEC_CHAR (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_char->default_value,
+ (gdouble) pspec_char->minimum,
+ (gdouble) pspec_char->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_UCHAR (pspec)) {
+ GParamSpecUChar *pspec_uchar;
+ pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_uchar->default_value,
+ (gdouble) pspec_uchar->minimum,
+ (gdouble) pspec_uchar->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_INT (pspec)) {
+ GParamSpecInt *pspec_int;
+ pspec_int = G_PARAM_SPEC_INT (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_int->default_value,
+ (gdouble) pspec_int->minimum,
+ (gdouble) pspec_int->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_UINT (pspec)) {
+ GParamSpecUInt *pspec_uint;
+ pspec_uint = G_PARAM_SPEC_UINT (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_uint->default_value,
+ (gdouble) pspec_uint->minimum,
+ (gdouble) pspec_uint->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_LONG (pspec)) {
+ GParamSpecLong *pspec_long;
+ pspec_long = G_PARAM_SPEC_LONG (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_long->default_value,
+ (gdouble) pspec_long->minimum,
+ (gdouble) pspec_long->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_ULONG (pspec)) {
+ GParamSpecULong *pspec_ulong;
+ pspec_ulong = G_PARAM_SPEC_ULONG (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_ulong->default_value,
+ (gdouble) pspec_ulong->minimum,
+ (gdouble) pspec_ulong->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_FLOAT (pspec)) {
+ GParamSpecFloat *pspec_float;
+ pspec_float = G_PARAM_SPEC_FLOAT (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_float->default_value,
+ (gdouble) pspec_float->minimum,
+ (gdouble) pspec_float->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) {
+ GParamSpecDouble *pspec_double;
+ pspec_double = G_PARAM_SPEC_DOUBLE (pspec);
+ adjustment = gtk_adjustment_new (
+ (gdouble) pspec_double->default_value,
+ (gdouble) pspec_double->minimum,
+ (gdouble) pspec_double->maximum,
+ 1.0, 1.0, 0.0);
+
+ } else
+ g_return_if_reached ();
+
+ pre = g_alloca (strlen (entry->text) + 1);
+ strcpy (pre, entry->text);
+ post = strstr (pre, "%s");
+ if (post != NULL) {
+ *post = '\0';
+ post += 2;
+ }
+
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
+ gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ if (use_pspec != NULL) {
+ prefix = gtk_check_button_new_with_mnemonic (pre);
+
+ g_object_bind_property (
+ settings, use_pspec->name,
+ prefix, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+ } else {
+ prefix = gtk_label_new_with_mnemonic (pre);
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), prefix, FALSE, TRUE, 0);
+ gtk_widget_show (prefix);
+
+ spin = gtk_spin_button_new (adjustment, 1.0, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, TRUE, 0);
+ gtk_widget_show (spin);
+
+ g_object_bind_property (
+ settings, entry->name,
+ spin, "value",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ if (use_pspec != NULL)
+ g_object_bind_property (
+ prefix, "active",
+ spin, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ if (post != NULL) {
+ GtkWidget *label = gtk_label_new_with_mnemonic (post);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), prefix);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ gtk_widget_show (label);
+ }
+
+ mail_config_provider_page_handle_dependency (page, entry, hbox);
+}
+
+static void
+mail_config_provider_page_add_entry (EMailConfigProviderPage *page,
+ CamelProviderConfEntry *entry)
+{
+ EMailConfigServiceBackend *backend;
+ CamelSettings *settings;
+ GtkWidget *hbox;
+ GtkWidget *input;
+ GtkWidget *label;
+
+ g_return_if_fail (entry->text != NULL);
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_set_spacing (GTK_BOX (hbox), 6);
+ gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
+ gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new_with_mnemonic (entry->text);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ input = gtk_entry_new ();
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), input);
+ gtk_box_pack_start (GTK_BOX (hbox), input, TRUE, TRUE, 0);
+ gtk_widget_show (input);
+
+ g_object_bind_property (
+ settings, entry->name,
+ input, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property (
+ input, "sensitive",
+ label, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ mail_config_provider_page_handle_dependency (page, entry, hbox);
+}
+
+static void
+mail_config_provider_page_add_options (EMailConfigProviderPage *page,
+ CamelProviderConfEntry *entry)
+{
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider;
+ CamelSettings *settings;
+ GtkCellRenderer *renderer;
+ GtkListStore *store;
+ GtkWidget *hbox;
+ GtkWidget *combo;
+ GtkWidget *label;
+ gchar **tokens;
+ guint length, ii;
+
+ /* The 'value' string is of the format:
+ *
+ * 'nick0:caption0:nick1:caption1:...nickN:captionN'
+ *
+ * where 'nick' is the nickname a GEnumValue and 'caption'
+ * is the localized combo box item displayed to the user. */
+
+ g_return_if_fail (entry->text != NULL);
+ g_return_if_fail (entry->value != NULL);
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ provider = e_mail_config_service_backend_get_provider (backend);
+ settings = e_mail_config_service_backend_get_settings (backend);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_set_spacing (GTK_BOX (hbox), 6);
+ gtk_widget_set_margin_left (hbox, STANDARD_MARGIN);
+ gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new_with_mnemonic (entry->text);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ /* 0: 'nick', 1: caption */
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+
+ tokens = g_strsplit (entry->value, ":", -1);
+ length = g_strv_length (tokens);
+
+ /* Take the strings two at a time. */
+ for (ii = 0; ii + 1 < length; ii += 2) {
+ GtkTreeIter iter;
+ const gchar *nick;
+ const gchar *caption;
+
+ nick = tokens[ii + 0];
+ caption = tokens[ii + 1];
+
+ /* Localize the caption. */
+ caption = dgettext (provider->translation_domain, caption);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, nick, 1, caption, -1);
+ }
+
+ g_strfreev (tokens);
+
+ combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+ gtk_combo_box_set_id_column (GTK_COMBO_BOX (combo), 0);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+ gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
+ gtk_widget_show (combo);
+
+ g_object_bind_property_full (
+ settings, entry->name,
+ combo, "active-id",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE,
+ e_binding_transform_enum_value_to_nick,
+ e_binding_transform_enum_nick_to_value,
+ NULL, (GDestroyNotify) NULL);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (
+ GTK_CELL_LAYOUT (combo), renderer, "text", 1, NULL);
+
+ mail_config_provider_page_handle_dependency (page, entry, hbox);
+}
+
+static void
+mail_config_provider_page_add_widgets (EMailConfigProviderPage *page)
+{
+ EMailConfigServiceBackend *backend;
+ CamelProviderConfEntry *entries;
+ CamelProvider *provider;
+ GtkWidget *frame;
+ GtkWidget *widget;
+ gint ii;
+
+ /* Note the "text" member of each CamelProviderConfEntry is
+ * already localized, so we can use it directly in widgets. */
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ provider = e_mail_config_service_backend_get_provider (backend);
+ g_return_if_fail (provider != NULL);
+
+ entries = provider->extra_conf;
+
+ /* Loop until we see CAMEL_PROVIDER_CONF_END. */
+ for (ii = 0; entries[ii].type != CAMEL_PROVIDER_CONF_END; ii++) {
+
+ /* Skip entries with no name. */
+ if (entries[ii].name == NULL)
+ continue;
+
+ switch (entries[ii].type) {
+ case CAMEL_PROVIDER_CONF_SECTION_START:
+ mail_config_provider_page_add_section (
+ page, &entries[ii]);
+ break;
+
+ case CAMEL_PROVIDER_CONF_CHECKBOX:
+ mail_config_provider_page_add_checkbox (
+ page, &entries[ii]);
+ break;
+
+ case CAMEL_PROVIDER_CONF_CHECKSPIN:
+ mail_config_provider_page_add_checkspin (
+ page, &entries[ii]);
+ break;
+
+ case CAMEL_PROVIDER_CONF_ENTRY:
+ mail_config_provider_page_add_entry (
+ page, &entries[ii]);
+ break;
+
+ case CAMEL_PROVIDER_CONF_OPTIONS:
+ mail_config_provider_page_add_options (
+ page, &entries[ii]);
+ break;
+
+ default:
+ break; /* skip it */
+ }
+ }
+
+ /* So far only Evolution-EWS uses the activity and alert
+ * bars, but other packages may someday find it handy. */
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+ gtk_box_pack_end (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ /* Visibility is bound to the EActivityBar. */
+
+ frame = widget;
+
+ widget = e_activity_bar_new ();
+ gtk_container_add (GTK_CONTAINER (frame), widget);
+ page->priv->activity_bar = widget; /* not referenced */
+ /* EActivity controls its own visibility. */
+
+ g_object_bind_property (
+ widget, "visible",
+ frame, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+ gtk_box_pack_end (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ /* Visibility is bound to the EAlertBar. */
+
+ frame = widget;
+
+ widget = e_alert_bar_new ();
+ gtk_container_add (GTK_CONTAINER (frame), widget);
+ page->priv->alert_bar = widget; /* not referenced */
+ /* EAlertBar controls its own visibility. */
+
+ g_object_bind_property (
+ widget, "visible",
+ frame, "visible",
+ G_BINDING_SYNC_CREATE);
+}
+
+static void
+mail_config_provider_page_set_backend (EMailConfigProviderPage *page,
+ EMailConfigServiceBackend *backend)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_return_if_fail (page->priv->backend == NULL);
+
+ page->priv->backend = g_object_ref (backend);
+}
+
+static void
+mail_config_provider_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BACKEND:
+ mail_config_provider_page_set_backend (
+ E_MAIL_CONFIG_PROVIDER_PAGE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_provider_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_provider_page_get_backend (
+ E_MAIL_CONFIG_PROVIDER_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_provider_page_dispose (GObject *object)
+{
+ EMailConfigProviderPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (object);
+
+ if (priv->backend != NULL) {
+ g_object_unref (priv->backend);
+ priv->backend = NULL;
+ }
+
+ /* Chain up parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_provider_page_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_provider_page_constructed (GObject *object)
+{
+ EMailConfigProviderPage *page;
+ EMailConfigServiceBackend *backend;
+ CamelProvider *provider;
+
+ page = E_MAIL_CONFIG_PROVIDER_PAGE (object);
+
+ /* Chain up parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_provider_page_parent_class)->
+ constructed (object);
+
+ gtk_box_set_spacing (GTK_BOX (object), 6);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (object), GTK_ORIENTATION_VERTICAL);
+
+ backend = e_mail_config_provider_page_get_backend (page);
+ provider = e_mail_config_service_backend_get_provider (backend);
+
+ if (provider != NULL && provider->extra_conf != NULL)
+ mail_config_provider_page_add_widgets (page);
+ else
+ page->priv->is_empty = TRUE;
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static void
+mail_config_provider_page_submit_alert (EAlertSink *alert_sink,
+ EAlert *alert)
+{
+ EMailConfigProviderPagePrivate *priv;
+ EAlertBar *alert_bar;
+ GtkWidget *dialog;
+ gpointer parent;
+
+ priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (alert_sink);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (alert_sink));
+ parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+
+ switch (e_alert_get_message_type (alert)) {
+ case GTK_MESSAGE_INFO:
+ case GTK_MESSAGE_WARNING:
+ case GTK_MESSAGE_ERROR:
+ alert_bar = E_ALERT_BAR (priv->alert_bar);
+ e_alert_bar_add_alert (alert_bar, alert);
+ break;
+
+ default:
+ dialog = e_alert_dialog_new (parent, alert);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ break;
+ }
+}
+
+static void
+e_mail_config_provider_page_class_init (EMailConfigProviderPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigProviderPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_provider_page_set_property;
+ object_class->get_property = mail_config_provider_page_get_property;
+ object_class->dispose = mail_config_provider_page_dispose;
+ object_class->constructed = mail_config_provider_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BACKEND,
+ g_param_spec_object (
+ "backend",
+ "Backend",
+ "Service backend to generate options from",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_provider_page_alert_sink_init (EAlertSinkInterface *interface)
+{
+ interface->submit_alert = mail_config_provider_page_submit_alert;
+}
+
+static void
+e_mail_config_provider_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Receiving Options");
+ interface->sort_order = E_MAIL_CONFIG_PROVIDER_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_provider_page_init (EMailConfigProviderPage *page)
+{
+ page->priv = E_MAIL_CONFIG_PROVIDER_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_provider_page_new (EMailConfigServiceBackend *backend)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_PROVIDER_PAGE,
+ "backend", backend, NULL);
+}
+
+gboolean
+e_mail_config_provider_page_is_empty (EMailConfigProviderPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), TRUE);
+
+ return page->priv->is_empty;
+}
+
+EMailConfigServiceBackend *
+e_mail_config_provider_page_get_backend (EMailConfigProviderPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), NULL);
+
+ return page->priv->backend;
+}
+
+EActivity *
+e_mail_config_provider_page_new_activity (EMailConfigProviderPage *page)
+{
+ EActivity *activity;
+ EActivityBar *activity_bar;
+ GCancellable *cancellable;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_PROVIDER_PAGE (page), NULL);
+
+ /* Clear any previous alerts. */
+ e_alert_bar_clear (E_ALERT_BAR (page->priv->alert_bar));
+
+ activity = e_activity_new ();
+
+ e_activity_set_alert_sink (activity, E_ALERT_SINK (page));
+
+ cancellable = camel_operation_new ();
+ e_activity_set_cancellable (activity, cancellable);
+ g_object_unref (cancellable);
+
+ activity_bar = E_ACTIVITY_BAR (page->priv->activity_bar);
+ e_activity_bar_set_activity (activity_bar, activity);
+
+ return activity;
+}
+
diff --git a/mail/e-mail-config-provider-page.h b/mail/e-mail-config-provider-page.h
new file mode 100644
index 0000000000..fbbdf7f34a
--- /dev/null
+++ b/mail/e-mail-config-provider-page.h
@@ -0,0 +1,81 @@
+/*
+ * e-mail-config-provider-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_PROVIDER_PAGE_H
+#define E_MAIL_CONFIG_PROVIDER_PAGE_H
+
+#include <gtk/gtk.h>
+#include <camel/camel.h>
+#include <libedataserver/e-source-registry.h>
+
+#include <e-util/e-activity.h>
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_PROVIDER_PAGE \
+ (e_mail_config_provider_page_get_type ())
+#define E_MAIL_CONFIG_PROVIDER_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE, EMailConfigProviderPage))
+#define E_MAIL_CONFIG_PROVIDER_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE, EMailConfigProviderPageClass))
+#define E_IS_MAIL_CONFIG_PROVIDER_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE))
+#define E_IS_MAIL_CONFIG_PROVIDER_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE))
+#define E_MAIL_CONFIG_PROVIDER_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_PROVIDER_PAGE, EMailConfigProviderPageClass))
+
+#define E_MAIL_CONFIG_PROVIDER_PAGE_SORT_ORDER (300)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigProviderPage EMailConfigProviderPage;
+typedef struct _EMailConfigProviderPageClass EMailConfigProviderPageClass;
+typedef struct _EMailConfigProviderPagePrivate EMailConfigProviderPagePrivate;
+
+struct _EMailConfigProviderPage {
+ GtkBox parent;
+ EMailConfigProviderPagePrivate *priv;
+};
+
+struct _EMailConfigProviderPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_provider_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_provider_page_new
+ (EMailConfigServiceBackend *backend);
+gboolean e_mail_config_provider_page_is_empty
+ (EMailConfigProviderPage *page);
+EMailConfigServiceBackend *
+ e_mail_config_provider_page_get_backend
+ (EMailConfigProviderPage *page);
+EActivity * e_mail_config_provider_page_new_activity
+ (EMailConfigProviderPage *page);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_PROVIDER_PAGE_H */
diff --git a/mail/e-mail-config-receiving-page.c b/mail/e-mail-config-receiving-page.c
new file mode 100644
index 0000000000..7106f20414
--- /dev/null
+++ b/mail/e-mail-config-receiving-page.c
@@ -0,0 +1,70 @@
+/*
+ * e-mail-config-receiving-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-receiving-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/e-source-mail-account.h>
+
+/* Forward Declarations */
+static void e_mail_config_receiving_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigReceivingPage,
+ e_mail_config_receiving_page,
+ E_TYPE_MAIL_CONFIG_SERVICE_PAGE,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_receiving_page_interface_init))
+
+static void
+e_mail_config_receiving_page_class_init (EMailConfigReceivingPageClass *class)
+{
+ EMailConfigServicePageClass *service_page_class;
+
+ service_page_class = E_MAIL_CONFIG_SERVICE_PAGE_CLASS (class);
+ service_page_class->extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ service_page_class->provider_type = CAMEL_PROVIDER_STORE;
+ service_page_class->default_backend_name = "imapx";
+}
+
+static void
+e_mail_config_receiving_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Receiving Email");
+ interface->sort_order = E_MAIL_CONFIG_RECEIVING_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_receiving_page_init (EMailConfigReceivingPage *page)
+{
+}
+
+EMailConfigPage *
+e_mail_config_receiving_page_new (ESourceRegistry *registry)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_RECEIVING_PAGE,
+ "registry", registry, NULL);
+}
+
diff --git a/mail/e-mail-config-receiving-page.h b/mail/e-mail-config-receiving-page.h
new file mode 100644
index 0000000000..626da30a49
--- /dev/null
+++ b/mail/e-mail-config-receiving-page.h
@@ -0,0 +1,69 @@
+/*
+ * e-mail-config-receiving-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_RECEIVING_PAGE_H
+#define E_MAIL_CONFIG_RECEIVING_PAGE_H
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-service-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_RECEIVING_PAGE \
+ (e_mail_config_receiving_page_get_type ())
+#define E_MAIL_CONFIG_RECEIVING_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_RECEIVING_PAGE, EMailConfigReceivingPage))
+#define E_MAIL_CONFIG_RECEIVING_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_RECEIVING_PAGE, EMailConfigReceivingPageClass))
+#define E_IS_MAIL_CONFIG_RECEIVING_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_RECEIVING_PAGE))
+#define E_IS_MAIL_CONFIG_RECEIVING_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_RECEIVING_PAGE))
+#define E_MAIL_CONFIG_RECEIVING_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_RECEIVING_PAGE, EMailConfigReceivingPageClass))
+
+#define E_MAIL_CONFIG_RECEIVING_PAGE_SORT_ORDER (200)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigReceivingPage EMailConfigReceivingPage;
+typedef struct _EMailConfigReceivingPageClass EMailConfigReceivingPageClass;
+typedef struct _EMailConfigReceivingPagePrivate EMailConfigReceivingPagePrivate;
+
+struct _EMailConfigReceivingPage {
+ EMailConfigServicePage parent;
+};
+
+struct _EMailConfigReceivingPageClass {
+ EMailConfigServicePageClass parent_class;
+};
+
+GType e_mail_config_receiving_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_receiving_page_new
+ (ESourceRegistry *registry);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_RECEIVING_PAGE_H */
+
diff --git a/mail/e-mail-config-security-page.c b/mail/e-mail-config-security-page.c
new file mode 100644
index 0000000000..911e40bb47
--- /dev/null
+++ b/mail/e-mail-config-security-page.c
@@ -0,0 +1,672 @@
+/*
+ * e-mail-config-security-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-security-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-openpgp.h>
+#include <libedataserver/e-source-smime.h>
+
+#if defined (HAVE_NSS)
+#include <smime/gui/e-cert-selector.h>
+#endif /* HAVE_NSS */
+
+#define E_MAIL_CONFIG_SECURITY_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_SECURITY_PAGE, EMailConfigSecurityPagePrivate))
+
+struct _EMailConfigSecurityPagePrivate {
+ ESource *identity_source;
+};
+
+enum {
+ PROP_0,
+ PROP_IDENTITY_SOURCE
+};
+
+/* Forward Declarations */
+static void e_mail_config_security_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigSecurityPage,
+ e_mail_config_security_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_security_page_interface_init))
+
+static gboolean
+mail_config_security_page_string_has_text (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer unused)
+{
+ const gchar *string;
+ gchar *stripped;
+
+ string = g_value_get_string (source_value);
+
+ if (string == NULL)
+ string = "";
+
+ stripped = g_strstrip (g_strdup (string));
+ g_value_set_boolean (target_value, *stripped != '\0');
+ g_free (stripped);
+
+ return TRUE;
+}
+
+static void
+mail_config_security_page_cert_selected (ECertSelector *selector,
+ const gchar *key,
+ GtkEntry *entry)
+{
+ if (key != NULL)
+ gtk_entry_set_text (entry, key);
+
+ gtk_widget_destroy (GTK_WIDGET (selector));
+}
+
+static void
+mail_config_security_page_select_encrypt_cert (GtkButton *button,
+ GtkEntry *entry)
+{
+ GtkWidget *selector;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ parent = GTK_IS_WIDGET (parent) ? parent : NULL;
+
+ selector = e_cert_selector_new (
+ E_CERT_SELECTOR_RECIPIENT,
+ gtk_entry_get_text (entry));
+ gtk_window_set_transient_for (
+ GTK_WINDOW (selector), parent);
+ gtk_widget_show (selector);
+
+ g_signal_connect (
+ selector, "selected",
+ G_CALLBACK (mail_config_security_page_cert_selected),
+ entry);
+}
+
+static void
+mail_config_security_page_select_sign_cert (GtkButton *button,
+ GtkEntry *entry)
+{
+ GtkWidget *selector;
+ gpointer parent;
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ parent = GTK_IS_WIDGET (parent) ? parent : NULL;
+
+ selector = e_cert_selector_new (
+ E_CERT_SELECTOR_SIGNER,
+ gtk_entry_get_text (entry));
+ gtk_window_set_transient_for (
+ GTK_WINDOW (selector), parent);
+ gtk_widget_show (selector);
+
+ g_signal_connect (
+ selector, "selected",
+ G_CALLBACK (mail_config_security_page_cert_selected),
+ entry);
+}
+
+static void
+mail_config_security_page_clear_cert (GtkButton *button,
+ GtkEntry *entry)
+{
+ gtk_entry_set_text (entry, "");
+}
+
+static void
+mail_config_security_page_set_identity_source (EMailConfigSecurityPage *page,
+ ESource *identity_source)
+{
+ g_return_if_fail (E_IS_SOURCE (identity_source));
+ g_return_if_fail (page->priv->identity_source == NULL);
+
+ page->priv->identity_source = g_object_ref (identity_source);
+}
+
+static void
+mail_config_security_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_IDENTITY_SOURCE:
+ mail_config_security_page_set_identity_source (
+ E_MAIL_CONFIG_SECURITY_PAGE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_security_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_IDENTITY_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_security_page_get_identity_source (
+ E_MAIL_CONFIG_SECURITY_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_security_page_dispose (GObject *object)
+{
+ EMailConfigSecurityPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_SECURITY_PAGE_GET_PRIVATE (object);
+
+ if (priv->identity_source != NULL) {
+ g_object_unref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_security_page_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_security_page_constructed (GObject *object)
+{
+ EMailConfigSecurityPage *page;
+ ESource *source;
+ ESourceMailComposition *composition_ext;
+ ESourceOpenPGP *openpgp_ext;
+ GtkEntry *entry;
+ GtkLabel *label;
+ GtkWidget *widget;
+ GtkWidget *container;
+ GtkSizeGroup *size_group;
+ const gchar *extension_name;
+ const gchar *text;
+ gchar *markup;
+
+#if defined (HAVE_NSS)
+ ESourceSMIME *smime_ext;
+#endif /* HAVE_NSS */
+
+ page = E_MAIL_CONFIG_SECURITY_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_security_page_parent_class)->
+ constructed (object);
+
+ source = e_mail_config_security_page_get_identity_source (page);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ composition_ext = e_source_get_extension (source, extension_name);
+
+ extension_name = E_SOURCE_EXTENSION_OPENPGP;
+ openpgp_ext = e_source_get_extension (source, extension_name);
+
+#if defined (HAVE_NSS)
+ extension_name = E_SOURCE_EXTENSION_SMIME;
+ smime_ext = e_source_get_extension (source, extension_name);
+#endif /* HAVE_NSS */
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ /*** General ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("General");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 1, 1);
+ gtk_widget_show (widget);
+
+ text = _("_Do not sign meeting requests (for Outlook compatibility)");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ composition_ext, "sign-imip",
+ widget, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /*** Pretty Good Privacy (OpenPGP) ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Pretty Good Privacy (OpenPGP)");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+ gtk_widget_show (widget);
+
+ text = _("OpenPGP _Key ID:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ openpgp_ext, "key-id",
+ widget, "text",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ text = _("Si_gning algorithm:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "", _("Default"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha1", _("SHA1"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha256", _("SHA256"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha384", _("SHA384"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha512", _("SHA512"));
+ gtk_widget_set_halign (widget, GTK_ALIGN_START);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ openpgp_ext, "signing-algorithm",
+ widget, "active-id",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ /* Make sure the combo box has an active item. */
+ if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (widget)) == NULL)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+
+ text = _("Al_ways sign outgoing messages when using this account");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 3, 2, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ openpgp_ext, "sign-by-default",
+ widget, "active",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ text = _("Always encrypt to _myself when sending encrypted messages");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 4, 2, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ openpgp_ext, "encrypt-to-self",
+ widget, "active",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ text = _("Always _trust keys in my keyring when encrypting");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 5, 2, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ openpgp_ext, "always-trust",
+ widget, "active",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+#if defined (HAVE_NSS)
+
+ /*** Security MIME (S/MIME) ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Secure MIME (S/MIME)");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 4, 1);
+ gtk_widget_show (widget);
+
+ text = _("Sig_ning certificate:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ smime_ext, "signing-certificate",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ entry = GTK_ENTRY (widget);
+
+ widget = gtk_button_new_with_label (_("Select"));
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (mail_config_security_page_select_sign_cert),
+ entry);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
+ gtk_grid_attach (GTK_GRID (container), widget, 3, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (mail_config_security_page_clear_cert),
+ entry);
+
+ text = _("Signing _algorithm:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "", _("Default"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha1", _("SHA1"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha256", _("SHA256"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha384", _("SHA384"));
+ gtk_combo_box_text_append (
+ GTK_COMBO_BOX_TEXT (widget),
+ "sha512", _("SHA512"));
+ gtk_widget_set_halign (widget, GTK_ALIGN_START);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ smime_ext, "signing-algorithm",
+ widget, "active-id",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ /* Make sure the combo box has an active item. */
+ if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (widget)) == NULL)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+
+ text = _("Always sign outgoing messages when using this account");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 3, 4, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ smime_ext, "sign-by-default",
+ widget, "active",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ g_object_bind_property_full (
+ smime_ext, "signing-certificate",
+ widget, "sensitive",
+ G_BINDING_SYNC_CREATE,
+ mail_config_security_page_string_has_text,
+ NULL,
+ NULL, (GDestroyNotify) NULL);
+
+ /* Add extra padding between signing stuff and encryption stuff. */
+ gtk_widget_set_margin_bottom (widget, 6);
+
+ text = _("Encryption certificate:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 4, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 4, 1, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ smime_ext, "encryption-certificate",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ entry = GTK_ENTRY (widget);
+
+ widget = gtk_button_new_with_label (_("Select"));
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 4, 1, 1);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (mail_config_security_page_select_encrypt_cert),
+ entry);
+
+ widget = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
+ gtk_grid_attach (GTK_GRID (container), widget, 3, 4, 1, 1);
+ gtk_widget_show (widget);
+
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (mail_config_security_page_clear_cert),
+ entry);
+
+ text = _("Always encrypt outgoing messages when using this account");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 5, 4, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ smime_ext, "encrypt-by-default",
+ widget, "active",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ g_object_bind_property_full (
+ smime_ext, "encryption-certificate",
+ widget, "sensitive",
+ G_BINDING_SYNC_CREATE,
+ mail_config_security_page_string_has_text,
+ NULL,
+ NULL, (GDestroyNotify) NULL);
+
+ text = _("Always encrypt to myself when sending encrypted messages");
+ widget = gtk_check_button_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 6, 4, 1);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ smime_ext, "encrypt-to-self",
+ widget, "active",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL);
+
+ g_object_bind_property_full (
+ smime_ext, "encryption-certificate",
+ widget, "sensitive",
+ G_BINDING_SYNC_CREATE,
+ mail_config_security_page_string_has_text,
+ NULL,
+ NULL, (GDestroyNotify) NULL);
+
+#endif /* HAVE_NSS */
+
+ g_object_unref (size_group);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static void
+e_mail_config_security_page_class_init (EMailConfigSecurityPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigSecurityPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_security_page_set_property;
+ object_class->get_property = mail_config_security_page_get_property;
+ object_class->dispose = mail_config_security_page_dispose;
+ object_class->constructed = mail_config_security_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IDENTITY_SOURCE,
+ g_param_spec_object (
+ "identity-source",
+ "Identity Source",
+ "Mail identity source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_security_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Security");
+ interface->sort_order = E_MAIL_CONFIG_SECURITY_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_security_page_init (EMailConfigSecurityPage *page)
+{
+ page->priv = E_MAIL_CONFIG_SECURITY_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_security_page_new (ESource *identity_source)
+{
+ g_return_val_if_fail (E_IS_SOURCE (identity_source), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_SECURITY_PAGE,
+ "identity-source", identity_source, NULL);
+}
+
+ESource *
+e_mail_config_security_page_get_identity_source (EMailConfigSecurityPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SECURITY_PAGE (page), NULL);
+
+ return page->priv->identity_source;
+}
+
diff --git a/mail/e-mail-config-security-page.h b/mail/e-mail-config-security-page.h
new file mode 100644
index 0000000000..79174eaed0
--- /dev/null
+++ b/mail/e-mail-config-security-page.h
@@ -0,0 +1,73 @@
+/*
+ * e-mail-config-security-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_SECURITY_PAGE_H
+#define E_MAIL_CONFIG_SECURITY_PAGE_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-source.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SECURITY_PAGE \
+ (e_mail_config_security_page_get_type ())
+#define E_MAIL_CONFIG_SECURITY_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SECURITY_PAGE, EMailConfigSecurityPage))
+#define E_MAIL_CONFIG_SECURITY_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SECURITY_PAGE, EMailConfigSecurityPageClass))
+#define E_IS_MAIL_CONFIG_SECURITY_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SECURITY_PAGE))
+#define E_IS_MAIL_CONFIG_SECURITY_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SECURITY_PAGE))
+#define E_MAIL_CONFIG_SECURITY_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SECURITY_PAGE, EMailConfigSecurityPageClass))
+
+#define E_MAIL_CONFIG_SECURITY_PAGE_SORT_ORDER (600)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigSecurityPage EMailConfigSecurityPage;
+typedef struct _EMailConfigSecurityPageClass EMailConfigSecurityPageClass;
+typedef struct _EMailConfigSecurityPagePrivate EMailConfigSecurityPagePrivate;
+
+struct _EMailConfigSecurityPage {
+ GtkBox parent;
+ EMailConfigSecurityPagePrivate *priv;
+};
+
+struct _EMailConfigSecurityPageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_security_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_security_page_new (ESource *identity_source);
+ESource * e_mail_config_security_page_get_identity_source
+ (EMailConfigSecurityPage *page);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_SECURITY_PAGE_H */
+
diff --git a/mail/e-mail-config-sending-page.c b/mail/e-mail-config-sending-page.c
new file mode 100644
index 0000000000..198a3ea4ac
--- /dev/null
+++ b/mail/e-mail-config-sending-page.c
@@ -0,0 +1,70 @@
+/*
+ * e-mail-config-sending-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-sending-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/e-source-mail-transport.h>
+
+/* Forward Declarations */
+static void e_mail_config_sending_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigSendingPage,
+ e_mail_config_sending_page,
+ E_TYPE_MAIL_CONFIG_SERVICE_PAGE,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_sending_page_interface_init))
+
+static void
+e_mail_config_sending_page_class_init (EMailConfigSendingPageClass *class)
+{
+ EMailConfigServicePageClass *service_page_class;
+
+ service_page_class = E_MAIL_CONFIG_SERVICE_PAGE_CLASS (class);
+ service_page_class->extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+ service_page_class->provider_type = CAMEL_PROVIDER_TRANSPORT;
+ service_page_class->default_backend_name = "smtp";
+}
+
+static void
+e_mail_config_sending_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Sending Email");
+ interface->sort_order = E_MAIL_CONFIG_SENDING_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_sending_page_init (EMailConfigSendingPage *page)
+{
+}
+
+EMailConfigPage *
+e_mail_config_sending_page_new (ESourceRegistry *registry)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_SENDING_PAGE,
+ "registry", registry, NULL);
+}
+
diff --git a/mail/e-mail-config-sending-page.h b/mail/e-mail-config-sending-page.h
new file mode 100644
index 0000000000..4727602c95
--- /dev/null
+++ b/mail/e-mail-config-sending-page.h
@@ -0,0 +1,68 @@
+/*
+ * e-mail-config-sending-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_SENDING_PAGE_H
+#define E_MAIL_CONFIG_SENDING_PAGE_H
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-service-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SENDING_PAGE \
+ (e_mail_config_sending_page_get_type ())
+#define E_MAIL_CONFIG_SENDING_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SENDING_PAGE, EMailConfigSendingPage))
+#define E_MAIL_CONFIG_SENDING_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SENDING_PAGE, EMailConfigSendingPageClass))
+#define E_IS_MAIL_CONFIG_SENDING_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SENDING_PAGE))
+#define E_IS_MAIL_CONFIG_SENDING_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SENDING_PAGE))
+#define E_MAIL_CONFIG_SENDING_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SENDING_PAGE, EMailConfigSendingPageClass))
+
+#define E_MAIL_CONFIG_SENDING_PAGE_SORT_ORDER (400)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigSendingPage EMailConfigSendingPage;
+typedef struct _EMailConfigSendingPageClass EMailConfigSendingPageClass;
+typedef struct _EMailConfigSendingPagePrivate EMailConfigSendingPagePrivate;
+
+struct _EMailConfigSendingPage {
+ EMailConfigServicePage parent;
+};
+
+struct _EMailConfigSendingPageClass {
+ EMailConfigServicePageClass parent_class;
+};
+
+GType e_mail_config_sending_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_sending_page_new (ESourceRegistry *registry);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_SENDING_PAGE_H */
+
diff --git a/mail/e-mail-config-service-backend.c b/mail/e-mail-config-service-backend.c
new file mode 100644
index 0000000000..a4c97fcd18
--- /dev/null
+++ b/mail/e-mail-config-service-backend.c
@@ -0,0 +1,514 @@
+/*
+ * e-mail-config-service-backend.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-service-backend.h"
+
+#include <libedataserver/e-source-camel.h>
+#include <libedataserver/e-source-backend.h>
+#include <libedataserver/e-source-collection.h>
+
+#include <mail/e-mail-config-receiving-page.h>
+#include <mail/e-mail-config-sending-page.h>
+
+#define E_MAIL_CONFIG_SERVICE_BACKEND_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND, EMailConfigServiceBackendPrivate))
+
+struct _EMailConfigServiceBackendPrivate {
+ ESource *source;
+ ESource *collection;
+};
+
+enum {
+ PROP_0,
+ PROP_COLLECTION,
+ PROP_SELECTABLE,
+ PROP_SOURCE
+};
+
+G_DEFINE_ABSTRACT_TYPE (
+ EMailConfigServiceBackend,
+ e_mail_config_service_backend,
+ E_TYPE_EXTENSION)
+
+static void
+mail_config_service_backend_init_collection (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+
+ /* Use the new_collection() method to initialize the "collection"
+ * property. This assumes we're editing a new account. If we're
+ * editing an existing account, the initial "collection" property
+ * value should be overridden with the existing collection source. */
+
+ g_return_if_fail (backend->priv->collection == NULL);
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_if_fail (class->new_collection != NULL);
+
+ backend->priv->collection = class->new_collection (backend);
+}
+
+static void
+mail_config_service_backend_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COLLECTION:
+ e_mail_config_service_backend_set_collection (
+ E_MAIL_CONFIG_SERVICE_BACKEND (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SOURCE:
+ e_mail_config_service_backend_set_source (
+ E_MAIL_CONFIG_SERVICE_BACKEND (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_service_backend_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COLLECTION:
+ g_value_set_object (
+ value,
+ e_mail_config_service_backend_get_collection (
+ E_MAIL_CONFIG_SERVICE_BACKEND (object)));
+ return;
+
+ case PROP_SELECTABLE:
+ g_value_set_boolean (
+ value,
+ e_mail_config_service_backend_get_selectable (
+ E_MAIL_CONFIG_SERVICE_BACKEND (object)));
+ return;
+
+ case PROP_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_service_backend_get_source (
+ E_MAIL_CONFIG_SERVICE_BACKEND (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_service_backend_dispose (GObject *object)
+{
+ EMailConfigServiceBackendPrivate *priv;
+
+ priv = E_MAIL_CONFIG_SERVICE_BACKEND_GET_PRIVATE (object);
+
+ if (priv->source != NULL) {
+ g_object_unref (priv->source);
+ priv->source = NULL;
+ }
+
+ if (priv->collection != NULL) {
+ g_object_unref (priv->collection);
+ priv->collection = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_service_backend_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_service_backend_constructed (GObject *object)
+{
+ EMailConfigServiceBackend *backend;
+
+ backend = E_MAIL_CONFIG_SERVICE_BACKEND (object);
+ mail_config_service_backend_init_collection (backend);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_service_backend_parent_class)->
+ constructed (object);
+}
+
+static gboolean
+mail_config_service_backend_get_selectable (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServicePage *page;
+ CamelProvider *provider;
+ gboolean selectable = TRUE;
+
+ page = e_mail_config_service_backend_get_page (backend);
+ provider = e_mail_config_service_backend_get_provider (backend);
+
+ if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider))
+ selectable = E_IS_MAIL_CONFIG_RECEIVING_PAGE (page);
+
+ return selectable;
+}
+
+static ESource *
+mail_config_service_backend_new_collection (EMailConfigServiceBackend *backend)
+{
+ /* This is typically only used for groupware backends. */
+ return NULL;
+}
+
+static void
+mail_config_service_backend_insert_widgets (EMailConfigServiceBackend *backend,
+ GtkBox *parent)
+{
+ /* does nothing */
+}
+
+static void
+mail_config_service_backend_setup_defaults (EMailConfigServiceBackend *backend)
+{
+ /* does nothing */
+}
+
+static gboolean
+mail_config_service_backend_auto_configure (EMailConfigServiceBackend *backend,
+ EMailAutoconfig *autoconfig)
+{
+ return FALSE;
+}
+
+static gboolean
+mail_config_service_backend_check_complete (EMailConfigServiceBackend *backend)
+{
+ return TRUE;
+}
+
+static void
+mail_config_service_backend_commit_changes (EMailConfigServiceBackend *backend)
+{
+ /* does nothing */
+}
+
+static void
+e_mail_config_service_backend_class_init (EMailConfigServiceBackendClass *class)
+{
+ GObjectClass *object_class;
+ EExtensionClass *extension_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigServiceBackendPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_service_backend_set_property;
+ object_class->get_property = mail_config_service_backend_get_property;
+ object_class->dispose = mail_config_service_backend_dispose;
+ object_class->constructed = mail_config_service_backend_constructed;
+
+ extension_class = E_EXTENSION_CLASS (class);
+ extension_class->extensible_type = E_TYPE_MAIL_CONFIG_SERVICE_PAGE;
+
+ class->get_selectable = mail_config_service_backend_get_selectable;
+ class->new_collection = mail_config_service_backend_new_collection;
+ class->insert_widgets = mail_config_service_backend_insert_widgets;
+ class->setup_defaults = mail_config_service_backend_setup_defaults;
+ class->auto_configure = mail_config_service_backend_auto_configure;
+ class->check_complete = mail_config_service_backend_check_complete;
+ class->commit_changes = mail_config_service_backend_commit_changes;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COLLECTION,
+ g_param_spec_object (
+ "collection",
+ "Collection",
+ "Optional collection ESource",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTABLE,
+ g_param_spec_boolean (
+ "selectable",
+ "Selectable",
+ "Whether the backend is user selectable",
+ TRUE, /* not applied */
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE,
+ g_param_spec_object (
+ "source",
+ "Source",
+ "The ESource being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_service_backend_init (EMailConfigServiceBackend *backend)
+{
+ backend->priv = E_MAIL_CONFIG_SERVICE_BACKEND_GET_PRIVATE (backend);
+}
+
+EMailConfigServicePage *
+e_mail_config_service_backend_get_page (EMailConfigServiceBackend *backend)
+{
+ EExtensible *extensible;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ extensible = e_extension_get_extensible (E_EXTENSION (backend));
+
+ return E_MAIL_CONFIG_SERVICE_PAGE (extensible);
+}
+
+ESource *
+e_mail_config_service_backend_get_source (EMailConfigServiceBackend *backend)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ return backend->priv->source;
+}
+
+void
+e_mail_config_service_backend_set_source (EMailConfigServiceBackend *backend,
+ ESource *source)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+
+ if (source != NULL) {
+ g_return_if_fail (E_IS_SOURCE (source));
+ g_object_ref (source);
+ }
+
+ if (backend->priv->source != NULL)
+ g_object_unref (backend->priv->source);
+
+ backend->priv->source = source;
+
+ g_object_notify (G_OBJECT (backend), "source");
+}
+
+ESource *
+e_mail_config_service_backend_get_collection (EMailConfigServiceBackend *backend)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ return backend->priv->collection;
+}
+
+void
+e_mail_config_service_backend_set_collection (EMailConfigServiceBackend *backend,
+ ESource *collection)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+
+ if (collection != NULL) {
+ g_return_if_fail (E_IS_SOURCE (collection));
+ g_object_ref (collection);
+ }
+
+ if (backend->priv->collection != NULL)
+ g_object_unref (backend->priv->collection);
+
+ backend->priv->collection = collection;
+
+ g_object_notify (G_OBJECT (backend), "collection");
+}
+
+CamelProvider *
+e_mail_config_service_backend_get_provider (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_val_if_fail (class->backend_name != NULL, NULL);
+
+ return camel_provider_get (class->backend_name, NULL);
+}
+
+CamelSettings *
+e_mail_config_service_backend_get_settings (EMailConfigServiceBackend *backend)
+{
+ ESource *source;
+ ESourceCamel *camel_extension = NULL;
+ EMailConfigServicePage *page;
+ EMailConfigServicePageClass *page_class;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ page = e_mail_config_service_backend_get_page (backend);
+ page_class = E_MAIL_CONFIG_SERVICE_PAGE_GET_CLASS (page);
+
+ /* Which ESource do we pull the CamelSettings from? This is a
+ * little tricky because we have to handle the following cases:
+ *
+ * 1) A stand-alone mail account.
+ *
+ * 2) A collection with a specialized backend (e.g. ews).
+ *
+ * 3) A collection that uses standard backends (e.g. yahoo).
+ *
+ * So the semantics are as follows. They work for now but may
+ * need further tweaking as we support more collection types.
+ *
+ * 1) If the service backend defines a collection source,
+ * assume the CamelSettings will be pulled from there.
+ *
+ * 2) If we have a collection source, try extracting the
+ * ESourceCamel extension for the collection source's
+ * backend name.
+ *
+ * 3) If steps 1 or 2 fail, pull the CamelSettings from
+ * the service backend's own scratch source.
+ */
+
+ source = e_mail_config_service_backend_get_collection (backend);
+ if (source != NULL) {
+ ESourceBackend *backend_extension;
+ const gchar *backend_name;
+ const gchar *extension_name;
+
+ extension_name = E_SOURCE_EXTENSION_COLLECTION;
+ backend_extension =
+ e_source_get_extension (source, extension_name);
+ backend_name =
+ e_source_backend_get_backend_name (backend_extension);
+
+ extension_name =
+ e_source_camel_get_extension_name (backend_name);
+ camel_extension =
+ e_source_get_extension (source, extension_name);
+ }
+
+ if (camel_extension == NULL) {
+ ESourceBackend *backend_extension;
+ const gchar *backend_name;
+ const gchar *extension_name;
+
+ source = e_mail_config_service_backend_get_source (backend);
+
+ extension_name = page_class->extension_name;
+ backend_extension =
+ e_source_get_extension (source, extension_name);
+ backend_name =
+ e_source_backend_get_backend_name (backend_extension);
+
+ extension_name =
+ e_source_camel_get_extension_name (backend_name);
+ camel_extension =
+ e_source_get_extension (source, extension_name);
+ }
+
+ return e_source_camel_get_settings (camel_extension);
+}
+
+gboolean
+e_mail_config_service_backend_get_selectable (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), FALSE);
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_val_if_fail (class->get_selectable != NULL, FALSE);
+
+ return class->get_selectable (backend);
+}
+
+void
+e_mail_config_service_backend_insert_widgets (EMailConfigServiceBackend *backend,
+ GtkBox *parent)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_return_if_fail (GTK_IS_BOX (parent));
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_if_fail (class->insert_widgets != NULL);
+
+ class->insert_widgets (backend, parent);
+}
+
+void
+e_mail_config_service_backend_setup_defaults (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_if_fail (class->setup_defaults != NULL);
+
+ return class->setup_defaults (backend);
+}
+
+gboolean
+e_mail_config_service_backend_auto_configure (EMailConfigServiceBackend *backend,
+ EMailAutoconfig *autoconfig)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), FALSE);
+ g_return_val_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig), FALSE);
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_val_if_fail (class->auto_configure != NULL, FALSE);
+
+ return class->auto_configure (backend, autoconfig);
+}
+
+gboolean
+e_mail_config_service_backend_check_complete (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), FALSE);
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_val_if_fail (class->check_complete != NULL, FALSE);
+
+ return class->check_complete (backend);
+}
+
+void
+e_mail_config_service_backend_commit_changes (EMailConfigServiceBackend *backend)
+{
+ EMailConfigServiceBackendClass *class;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_return_if_fail (class->commit_changes != NULL);
+
+ class->commit_changes (backend);
+}
+
diff --git a/mail/e-mail-config-service-backend.h b/mail/e-mail-config-service-backend.h
new file mode 100644
index 0000000000..6ba4ad3d13
--- /dev/null
+++ b/mail/e-mail-config-service-backend.h
@@ -0,0 +1,121 @@
+/*
+ * e-mail-config-service-backend.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_SERVICE_BACKEND_H
+#define E_MAIL_CONFIG_SERVICE_BACKEND_H
+
+#include <gtk/gtk.h>
+#include <camel/camel.h>
+#include <libebackend/e-extension.h>
+#include <libedataserver/e-source.h>
+
+#include <mail/e-mail-autoconfig.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SERVICE_BACKEND \
+ (e_mail_config_service_backend_get_type ())
+#define E_MAIL_CONFIG_SERVICE_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND, EMailConfigServiceBackend))
+#define E_MAIL_CONFIG_SERVICE_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND, EMailConfigServiceBackendClass))
+#define E_IS_MAIL_CONFIG_SERVICE_BACKEND(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND))
+#define E_IS_MAIL_CONFIG_SERVICE_BACKEND_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND))
+#define E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND, EMailConfigServiceBackendClass))
+
+G_BEGIN_DECLS
+
+struct _EMailConfigServicePage;
+
+typedef struct _EMailConfigServiceBackend EMailConfigServiceBackend;
+typedef struct _EMailConfigServiceBackendClass EMailConfigServiceBackendClass;
+typedef struct _EMailConfigServiceBackendPrivate EMailConfigServiceBackendPrivate;
+
+struct _EMailConfigServiceBackend {
+ EExtension parent;
+ EMailConfigServiceBackendPrivate *priv;
+};
+
+struct _EMailConfigServiceBackendClass {
+ EExtensionClass parent_class;
+
+ const gchar *backend_name;
+
+ gboolean (*get_selectable)
+ (EMailConfigServiceBackend *backend);
+ ESource * (*new_collection)
+ (EMailConfigServiceBackend *backend);
+ void (*insert_widgets)
+ (EMailConfigServiceBackend *backend,
+ GtkBox *parent);
+ void (*setup_defaults)
+ (EMailConfigServiceBackend *backend);
+ gboolean (*auto_configure)
+ (EMailConfigServiceBackend *backend,
+ EMailAutoconfig *autoconfig);
+ gboolean (*check_complete)
+ (EMailConfigServiceBackend *backend);
+ void (*commit_changes)
+ (EMailConfigServiceBackend *backend);
+};
+
+GType e_mail_config_service_backend_get_type
+ (void) G_GNUC_CONST;
+struct _EMailConfigServicePage *
+ e_mail_config_service_backend_get_page
+ (EMailConfigServiceBackend *backend);
+ESource * e_mail_config_service_backend_get_source
+ (EMailConfigServiceBackend *backend);
+void e_mail_config_service_backend_set_source
+ (EMailConfigServiceBackend *backend,
+ ESource *source);
+ESource * e_mail_config_service_backend_get_collection
+ (EMailConfigServiceBackend *backend);
+void e_mail_config_service_backend_set_collection
+ (EMailConfigServiceBackend *backend,
+ ESource *collection);
+CamelProvider * e_mail_config_service_backend_get_provider
+ (EMailConfigServiceBackend *backend);
+CamelSettings * e_mail_config_service_backend_get_settings
+ (EMailConfigServiceBackend *backend);
+gboolean e_mail_config_service_backend_get_selectable
+ (EMailConfigServiceBackend *backend);
+void e_mail_config_service_backend_insert_widgets
+ (EMailConfigServiceBackend *backend,
+ GtkBox *parent);
+void e_mail_config_service_backend_setup_defaults
+ (EMailConfigServiceBackend *backend);
+gboolean e_mail_config_service_backend_auto_configure
+ (EMailConfigServiceBackend *backend,
+ EMailAutoconfig *autoconfig);
+gboolean e_mail_config_service_backend_check_complete
+ (EMailConfigServiceBackend *backend);
+void e_mail_config_service_backend_commit_changes
+ (EMailConfigServiceBackend *backend);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_SERVICE_BACKEND_H */
+
diff --git a/mail/e-mail-config-service-notebook.c b/mail/e-mail-config-service-notebook.c
new file mode 100644
index 0000000000..757cd902da
--- /dev/null
+++ b/mail/e-mail-config-service-notebook.c
@@ -0,0 +1,365 @@
+/*
+ * e-mail-config-service-notebook.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-service-notebook.h"
+
+#define E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, EMailConfigServiceNotebookPrivate))
+
+#define CHILD_BACKEND_KEY_FORMAT \
+ "__e_mail_config_service_notebook_%p_child_backend__"
+
+struct _EMailConfigServiceNotebookPrivate {
+ EMailConfigServiceBackend *active_backend;
+ gchar *child_backend_key;
+};
+
+enum {
+ PROP_0,
+ PROP_ACTIVE_BACKEND
+};
+
+enum {
+ PROP_CHILD_0,
+ PROP_CHILD_BACKEND
+};
+
+G_DEFINE_TYPE (
+ EMailConfigServiceNotebook,
+ e_mail_config_service_notebook,
+ GTK_TYPE_NOTEBOOK)
+
+static void
+mail_config_service_notebook_set_child_backend (EMailConfigServiceNotebook *notebook,
+ GtkWidget *child,
+ EMailConfigServiceBackend *backend)
+{
+ const gchar *key;
+
+ key = notebook->priv->child_backend_key;
+
+ if (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend))
+ g_object_set_data_full (
+ G_OBJECT (child), key,
+ g_object_ref (backend),
+ (GDestroyNotify) g_object_unref);
+}
+
+static EMailConfigServiceBackend *
+mail_config_service_notebook_get_child_backend (EMailConfigServiceNotebook *notebook,
+ GtkWidget *child)
+{
+ const gchar *key;
+
+ key = notebook->priv->child_backend_key;
+
+ return g_object_get_data (G_OBJECT (child), key);
+}
+
+static gboolean
+mail_config_service_notebook_page_num_to_backend (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer user_data)
+{
+ EMailConfigServiceBackend *backend;
+ GtkNotebook *notebook;
+ GtkWidget *child;
+ gint page_num;
+
+ /* The binding's source and target are the same instance. */
+ notebook = GTK_NOTEBOOK (g_binding_get_source (binding));
+
+ page_num = g_value_get_int (source_value);
+ child = gtk_notebook_get_nth_page (notebook, page_num);
+
+ if (child != NULL)
+ backend = mail_config_service_notebook_get_child_backend (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), child);
+ else
+ backend = NULL;
+
+ g_value_set_object (target_value, backend);
+
+ return TRUE;
+}
+
+static gboolean
+mail_config_service_notebook_backend_to_page_num (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer user_data)
+{
+ EMailConfigServiceBackend *backend;
+ GtkNotebook *notebook;
+ gint n_pages, ii;
+
+ /* The binding's source and target are the same instance. */
+ notebook = GTK_NOTEBOOK (g_binding_get_source (binding));
+
+ backend = g_value_get_object (source_value);
+ n_pages = gtk_notebook_get_n_pages (notebook);
+
+ for (ii = 0; ii < n_pages; ii++) {
+ GtkWidget *child;
+ EMailConfigServiceBackend *candidate;
+
+ child = gtk_notebook_get_nth_page (notebook, ii);
+ candidate = mail_config_service_notebook_get_child_backend (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), child);
+
+ if (backend == candidate) {
+ g_value_set_int (target_value, ii);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+mail_config_service_notebook_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE_BACKEND:
+ e_mail_config_service_notebook_set_active_backend (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_service_notebook_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_service_notebook_get_active_backend (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_service_notebook_dispose (GObject *object)
+{
+ EMailConfigServiceNotebookPrivate *priv;
+
+ priv = E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE (object);
+
+ if (priv->active_backend != NULL) {
+ g_object_unref (priv->active_backend);
+ priv->active_backend = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_service_notebook_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_service_notebook_finalize (GObject *object)
+{
+ EMailConfigServiceNotebookPrivate *priv;
+
+ priv = E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE (object);
+
+ g_free (priv->child_backend_key);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_service_notebook_parent_class)->
+ finalize (object);
+}
+
+static void
+mail_config_service_notebook_constructed (GObject *object)
+{
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_service_notebook_parent_class)->
+ constructed (object);
+
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (object), FALSE);
+
+ /* Current page is still -1 so skip G_BINDING_SYNC_CREATE. */
+ g_object_bind_property_full (
+ object, "page",
+ object, "active-backend",
+ G_BINDING_BIDIRECTIONAL,
+ mail_config_service_notebook_page_num_to_backend,
+ mail_config_service_notebook_backend_to_page_num,
+ NULL, (GDestroyNotify) NULL);
+}
+
+static void
+mail_config_service_notebook_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CHILD_BACKEND:
+ mail_config_service_notebook_set_child_backend (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (container),
+ child, g_value_get_object (value));
+ return;
+ }
+
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (
+ container, property_id, pspec);
+}
+
+static void
+mail_config_service_notebook_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CHILD_BACKEND:
+ g_value_set_object (
+ value,
+ mail_config_service_notebook_get_child_backend (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (container), child));
+ return;
+ }
+
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (
+ container, property_id, pspec);
+}
+
+static void
+e_mail_config_service_notebook_class_init (EMailConfigServiceNotebookClass *class)
+{
+ GObjectClass *object_class;
+ GtkContainerClass *container_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigServiceNotebookPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_service_notebook_set_property;
+ object_class->get_property = mail_config_service_notebook_get_property;
+ object_class->dispose = mail_config_service_notebook_dispose;
+ object_class->finalize = mail_config_service_notebook_finalize;
+ object_class->constructed = mail_config_service_notebook_constructed;
+
+ container_class = GTK_CONTAINER_CLASS (class);
+ container_class->set_child_property = mail_config_service_notebook_set_child_property;
+ container_class->get_child_property = mail_config_service_notebook_get_child_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVE_BACKEND,
+ g_param_spec_object (
+ "active-backend",
+ "Active Backend",
+ "The service backend for the current page",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /* Child property for notebook pages. */
+ gtk_container_class_install_child_property (
+ container_class,
+ PROP_CHILD_BACKEND,
+ g_param_spec_object (
+ "backend",
+ "Backend",
+ "The service backend for this page",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_service_notebook_init (EMailConfigServiceNotebook *notebook)
+{
+ gchar *key;
+
+ notebook->priv = E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_PRIVATE (notebook);
+
+ key = g_strdup_printf (CHILD_BACKEND_KEY_FORMAT, notebook);
+ notebook->priv->child_backend_key = key;
+}
+
+GtkWidget *
+e_mail_config_service_notebook_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, NULL);
+}
+
+gint
+e_mail_config_service_notebook_add_page (EMailConfigServiceNotebook *notebook,
+ EMailConfigServiceBackend *backend,
+ GtkWidget *child)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), -1);
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), -1);
+ g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+
+ gtk_widget_show (child);
+
+ mail_config_service_notebook_set_child_backend (
+ notebook, child, backend);
+
+ return gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child, NULL);
+}
+
+EMailConfigServiceBackend *
+e_mail_config_service_notebook_get_active_backend (EMailConfigServiceNotebook *notebook)
+{
+ g_return_val_if_fail (
+ E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook), NULL);
+
+ return notebook->priv->active_backend;
+}
+
+void
+e_mail_config_service_notebook_set_active_backend (EMailConfigServiceNotebook *notebook,
+ EMailConfigServiceBackend *backend)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK (notebook));
+
+ if (backend != NULL) {
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_object_ref (backend);
+ }
+
+ if (notebook->priv->active_backend != NULL)
+ g_object_unref (notebook->priv->active_backend);
+
+ notebook->priv->active_backend = backend;
+
+ g_object_notify (G_OBJECT (notebook), "active-backend");
+}
+
diff --git a/mail/e-mail-config-service-notebook.h b/mail/e-mail-config-service-notebook.h
new file mode 100644
index 0000000000..db339e9a93
--- /dev/null
+++ b/mail/e-mail-config-service-notebook.h
@@ -0,0 +1,77 @@
+/*
+ * e-mail-config-service-notebook.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_SERVICE_NOTEBOOK_H
+#define E_MAIL_CONFIG_SERVICE_NOTEBOOK_H
+
+#include <gtk/gtk.h>
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK \
+ (e_mail_config_service_notebook_get_type ())
+#define E_MAIL_CONFIG_SERVICE_NOTEBOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, EMailConfigServiceNotebook))
+#define E_MAIL_CONFIG_SERVICE_NOTEBOOK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, EMailConfigServiceNotebookClass))
+#define E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK))
+#define E_IS_MAIL_CONFIG_SERVICE_NOTEBOOK_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK))
+#define E_MAIL_CONFIG_SERVICE_NOTEBOOK_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_NOTEBOOK, EMailConfigServiceNotebookClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigServiceNotebook EMailConfigServiceNotebook;
+typedef struct _EMailConfigServiceNotebookClass EMailConfigServiceNotebookClass;
+typedef struct _EMailConfigServiceNotebookPrivate EMailConfigServiceNotebookPrivate;
+
+struct _EMailConfigServiceNotebook {
+ GtkNotebook parent;
+ EMailConfigServiceNotebookPrivate *priv;
+};
+
+struct _EMailConfigServiceNotebookClass {
+ GtkNotebookClass parent_class;
+};
+
+GType e_mail_config_service_notebook_get_type
+ (void) G_GNUC_CONST;
+GtkWidget * e_mail_config_service_notebook_new
+ (void);
+gint e_mail_config_service_notebook_add_page
+ (EMailConfigServiceNotebook *notebook,
+ EMailConfigServiceBackend *backend,
+ GtkWidget *child);
+EMailConfigServiceBackend *
+ e_mail_config_service_notebook_get_active_backend
+ (EMailConfigServiceNotebook *notebook);
+void e_mail_config_service_notebook_set_active_backend
+ (EMailConfigServiceNotebook *notebook,
+ EMailConfigServiceBackend *backend);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_SERVICE_NOTEBOOK_H */
+
diff --git a/mail/e-mail-config-service-page.c b/mail/e-mail-config-service-page.c
new file mode 100644
index 0000000000..1f53ed5ddb
--- /dev/null
+++ b/mail/e-mail-config-service-page.c
@@ -0,0 +1,1039 @@
+/*
+ * e-mail-config-service-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-service-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <camel/camel.h>
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-backend.h>
+
+#include <libevolution-utils/e-alert-sink.h>
+#include <libevolution-utils/e-alert-dialog.h>
+#include <misc/e-activity-bar.h>
+#include <misc/e-alert-bar.h>
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-service-notebook.h>
+
+#define E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_PAGE, EMailConfigServicePagePrivate))
+
+/* Used for autoconfiguration. */
+#define POP3_BACKEND_NAME "pop"
+#define IMAP_BACKEND_NAME "imapx"
+#define SMTP_BACKEND_NAME "smtp"
+
+typedef struct _Candidate Candidate;
+
+struct _EMailConfigServicePagePrivate {
+ ESourceRegistry *registry;
+ EMailConfigServiceBackend *active_backend;
+ gchar *email_address;
+
+ GHashTable *backends;
+ GPtrArray *candidates;
+
+ /* Hidden candidates are not listed in the
+ * combo box but can still be accessed through
+ * e_mail_config_service_page_lookup_backend(). */
+ GPtrArray *hidden_candidates;
+
+ GtkWidget *type_combo;
+ GtkWidget *type_label;
+ GtkWidget *desc_label;
+ GtkWidget *notebook;
+ GtkWidget *activity_bar;
+ GtkWidget *alert_bar;
+
+ /* Combo box list store */
+ GtkListStore *list_store;
+};
+
+struct _Candidate {
+ gchar *name;
+ EMailConfigServiceBackend *backend;
+
+ CamelProvider *provider;
+ CamelSettings *settings;
+ gulong settings_notify_handler_id;
+
+ GtkWidget *widget;
+};
+
+enum {
+ PROP_0,
+ PROP_ACTIVE_BACKEND,
+ PROP_EMAIL_ADDRESS,
+ PROP_REGISTRY
+};
+
+enum {
+ COLUMN_BACKEND_NAME,
+ COLUMN_DISPLAY_NAME,
+ COLUMN_SELECTABLE,
+ NUM_COLUMNS
+};
+
+/* Forward Declarations */
+static void e_mail_config_service_page_alert_sink_init
+ (EAlertSinkInterface *interface);
+static void e_mail_config_service_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (
+ EMailConfigServicePage,
+ e_mail_config_service_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_ALERT_SINK,
+ e_mail_config_service_page_alert_sink_init)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_service_page_interface_init))
+
+static void
+mail_config_service_page_settings_notify_cb (CamelSettings *settings,
+ GParamSpec *pspec,
+ EMailConfigPage *page)
+{
+ e_mail_config_page_changed (page);
+}
+
+static Candidate *
+mail_config_service_page_new_candidate (EMailConfigServicePage *page,
+ ESource *scratch_source,
+ ESource *opt_collection)
+{
+ Candidate *candidate;
+ CamelProvider *provider;
+ CamelSettings *settings;
+ ESourceBackend *extension;
+ EMailConfigServiceBackend *backend;
+ EMailConfigServicePageClass *class;
+ const gchar *extension_name;
+ const gchar *backend_name;
+ gulong handler_id;
+
+ /* Get the backend name for this scratch source. */
+ class = E_MAIL_CONFIG_SERVICE_PAGE_GET_CLASS (page);
+ extension_name = class->extension_name;
+ extension = e_source_get_extension (scratch_source, extension_name);
+ backend_name = e_source_backend_get_backend_name (extension);
+ g_return_val_if_fail (backend_name != NULL, NULL);
+
+ /* Make sure we have a corresponding EMailConfigServicePageBackend. */
+ backend = g_hash_table_lookup (page->priv->backends, backend_name);
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend), NULL);
+
+ /* Make sure we have a corresponding CamelProvider. */
+ provider = e_mail_config_service_backend_get_provider (backend);
+ g_return_val_if_fail (provider != NULL, NULL);
+
+ /* Need to give the backend a scratch source and (if provided) a
+ * scratch collection source before we can extract a CamelSettings
+ * instance, since the CamelSettings instance comes from either the
+ * scratch collection source or else the scratch source. */
+ e_mail_config_service_backend_set_source (backend, scratch_source);
+ if (opt_collection != NULL)
+ e_mail_config_service_backend_set_collection (
+ backend, opt_collection);
+
+ /* Make sure we have a corresponding CamelSettings. */
+ settings = e_mail_config_service_backend_get_settings (backend);
+ g_return_val_if_fail (CAMEL_IS_SETTINGS (settings), NULL);
+
+ candidate = g_slice_new0 (Candidate);
+ candidate->name = g_strdup (backend_name);
+ candidate->backend = g_object_ref (backend);
+ candidate->provider = provider;
+ candidate->settings = g_object_ref (settings);
+
+ /* Remove the backend so it can't be reused. If another scratch
+ * source with the same backend name gets added, the hash table
+ * lookup will fail and emit a runtime warning, which we want. */
+ g_hash_table_remove (page->priv->backends, backend_name);
+
+ /* Emit "changed" signals for subsequent CamelSettings changes. */
+ handler_id = g_signal_connect (
+ candidate->settings, "notify",
+ G_CALLBACK (mail_config_service_page_settings_notify_cb), page);
+ candidate->settings_notify_handler_id = handler_id;
+
+ return candidate;
+}
+
+static void
+mail_config_service_page_free_candidate (Candidate *candidate)
+{
+ g_free (candidate->name);
+
+ if (candidate->backend != NULL)
+ g_object_unref (candidate->backend);
+
+ if (candidate->settings != NULL) {
+ g_signal_handler_disconnect (
+ candidate->settings,
+ candidate->settings_notify_handler_id);
+ g_object_unref (candidate->settings);
+ }
+
+ if (candidate->widget != NULL)
+ g_object_unref (candidate->widget);
+
+ g_slice_free (Candidate, candidate);
+}
+
+static void
+mail_config_service_page_init_backends (EMailConfigServicePage *page)
+{
+ GList *list, *iter;
+
+ page->priv->backends = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+
+ list = e_extensible_list_extensions (
+ E_EXTENSIBLE (page), E_TYPE_MAIL_CONFIG_SERVICE_BACKEND);
+
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ EMailConfigServiceBackend *backend;
+ EMailConfigServiceBackendClass *class;
+
+ backend = E_MAIL_CONFIG_SERVICE_BACKEND (iter->data);
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+
+ if (class->backend_name != NULL)
+ g_hash_table_insert (
+ page->priv->backends,
+ g_strdup (class->backend_name),
+ g_object_ref (backend));
+ }
+
+ g_list_free (list);
+}
+
+static gboolean
+mail_config_service_page_backend_to_id (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer user_data)
+{
+ EMailConfigServiceBackend *backend;
+ EMailConfigServiceBackendClass *backend_class;
+
+ backend = g_value_get_object (source_value);
+ g_return_val_if_fail (backend != NULL, FALSE);
+
+ backend_class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+ g_value_set_string (target_value, backend_class->backend_name);
+
+ return TRUE;
+}
+
+static gboolean
+mail_config_service_page_id_to_backend (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer user_data)
+{
+ EMailConfigServiceBackend *backend = NULL;
+ GObject *source_object;
+ const gchar *backend_name;
+
+ source_object = g_binding_get_source (binding);
+ backend_name = g_value_get_string (source_value);
+
+ if (backend_name != NULL)
+ backend = e_mail_config_service_page_lookup_backend (
+ E_MAIL_CONFIG_SERVICE_PAGE (source_object),
+ backend_name);
+
+ g_value_set_object (target_value, backend);
+
+ return TRUE;
+}
+
+static gboolean
+mail_config_service_page_backend_name_to_description (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer user_data)
+{
+ CamelProvider *provider;
+ const gchar *description;
+ const gchar *backend_name;
+
+ backend_name = g_value_get_string (source_value);
+
+ /* XXX Silly special case. */
+ if (backend_name == NULL)
+ backend_name = "none";
+
+ provider = camel_provider_get (backend_name, NULL);
+
+ if (provider != NULL && provider->description != NULL)
+ description = g_dgettext (
+ provider->translation_domain,
+ provider->description);
+ else
+ description = "";
+
+ g_value_set_string (target_value, description);
+
+ return TRUE;
+}
+
+static Candidate *
+mail_config_service_page_get_active_candidate (EMailConfigServicePage *page)
+{
+ GtkComboBox *combo_box;
+ gint active;
+
+ combo_box = GTK_COMBO_BOX (page->priv->type_combo);
+ active = gtk_combo_box_get_active (combo_box);
+ g_return_val_if_fail (active >= 0, NULL);
+
+ return g_ptr_array_index (page->priv->candidates, active);
+}
+
+static void
+mail_config_service_page_set_registry (EMailConfigServicePage *page,
+ ESourceRegistry *registry)
+{
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (page->priv->registry == NULL);
+
+ page->priv->registry = g_object_ref (registry);
+}
+
+static void
+mail_config_service_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE_BACKEND:
+ e_mail_config_service_page_set_active_backend (
+ E_MAIL_CONFIG_SERVICE_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_EMAIL_ADDRESS:
+ e_mail_config_service_page_set_email_address (
+ E_MAIL_CONFIG_SERVICE_PAGE (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_REGISTRY:
+ mail_config_service_page_set_registry (
+ E_MAIL_CONFIG_SERVICE_PAGE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_service_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_service_page_get_active_backend (
+ E_MAIL_CONFIG_SERVICE_PAGE (object)));
+ return;
+
+ case PROP_EMAIL_ADDRESS:
+ g_value_set_string (
+ value,
+ e_mail_config_service_page_get_email_address (
+ E_MAIL_CONFIG_SERVICE_PAGE (object)));
+ return;
+
+ case PROP_REGISTRY:
+ g_value_set_object (
+ value,
+ e_mail_config_service_page_get_registry (
+ E_MAIL_CONFIG_SERVICE_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_service_page_dispose (GObject *object)
+{
+ EMailConfigServicePagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE (object);
+
+ if (priv->registry != NULL) {
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
+
+ if (priv->active_backend != NULL) {
+ g_object_unref (priv->active_backend);
+ priv->active_backend = NULL;
+ }
+
+ g_hash_table_remove_all (priv->backends);
+ g_ptr_array_set_size (priv->candidates, 0);
+ g_ptr_array_set_size (priv->hidden_candidates, 0);
+
+ if (priv->list_store != NULL) {
+ g_object_unref (priv->list_store);
+ priv->list_store = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_service_page_parent_class)->dispose (object);
+}
+
+static void
+mail_config_service_page_finalize (GObject *object)
+{
+ EMailConfigServicePagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE (object);
+
+ g_free (priv->email_address);
+ g_hash_table_destroy (priv->backends);
+ g_ptr_array_free (priv->candidates, TRUE);
+ g_ptr_array_free (priv->hidden_candidates, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_service_page_parent_class)->finalize (object);
+}
+
+static void
+mail_config_service_page_constructed (GObject *object)
+{
+ EMailConfigServicePage *page;
+
+ page = E_MAIL_CONFIG_SERVICE_PAGE (object);
+
+ mail_config_service_page_init_backends (page);
+}
+
+static void
+mail_config_service_page_submit_alert (EAlertSink *alert_sink,
+ EAlert *alert)
+{
+ EMailConfigServicePagePrivate *priv;
+ EAlertBar *alert_bar;
+ GtkWidget *dialog;
+ gpointer parent;
+
+ priv = E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE (alert_sink);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (alert_sink));
+ parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
+
+ switch (e_alert_get_message_type (alert)) {
+ case GTK_MESSAGE_INFO:
+ case GTK_MESSAGE_WARNING:
+ case GTK_MESSAGE_ERROR:
+ alert_bar = E_ALERT_BAR (priv->alert_bar);
+ e_alert_bar_add_alert (alert_bar, alert);
+ break;
+
+ default:
+ dialog = e_alert_dialog_new (parent, alert);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ break;
+ }
+}
+
+static void
+mail_config_service_page_setup_defaults (EMailConfigPage *page)
+{
+ EMailConfigServicePageClass *class;
+ EMailConfigServicePagePrivate *priv;
+ guint ii;
+
+ class = E_MAIL_CONFIG_SERVICE_PAGE_GET_CLASS (page);
+ priv = E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE (page);
+
+ for (ii = 0; ii < priv->candidates->len; ii++) {
+ Candidate *candidate;
+
+ candidate = priv->candidates->pdata[ii];
+ g_return_if_fail (candidate != NULL);
+
+ e_mail_config_service_backend_setup_defaults (
+ candidate->backend);
+ }
+
+ /* XXX Not sure if we need to call setup_defaults() for
+ * hidden candidates. Hold off until a need arises. */
+
+ if (class->default_backend_name != NULL)
+ gtk_combo_box_set_active_id (
+ GTK_COMBO_BOX (priv->type_combo),
+ class->default_backend_name);
+}
+
+static gboolean
+mail_config_service_page_check_complete (EMailConfigPage *page)
+{
+ EMailConfigServicePagePrivate *priv;
+ Candidate *candidate;
+ GtkComboBox *type_combo;
+
+ priv = E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE (page);
+
+ /* Make sure the combo box has an active item. */
+ type_combo = GTK_COMBO_BOX (priv->type_combo);
+ if (gtk_combo_box_get_active_id (type_combo) == NULL)
+ return FALSE;
+
+ candidate = mail_config_service_page_get_active_candidate (
+ E_MAIL_CONFIG_SERVICE_PAGE (page));
+ g_return_val_if_fail (candidate != NULL, FALSE);
+
+ return e_mail_config_service_backend_check_complete (
+ candidate->backend);
+}
+
+static void
+mail_config_service_page_commit_changes (EMailConfigPage *page,
+ GQueue *source_queue)
+{
+ Candidate *candidate;
+
+ candidate = mail_config_service_page_get_active_candidate (
+ E_MAIL_CONFIG_SERVICE_PAGE (page));
+ g_return_if_fail (candidate != NULL);
+
+ e_mail_config_service_backend_commit_changes (candidate->backend);
+}
+
+static void
+e_mail_config_service_page_class_init (EMailConfigServicePageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigServicePagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_service_page_set_property;
+ object_class->get_property = mail_config_service_page_get_property;
+ object_class->dispose = mail_config_service_page_dispose;
+ object_class->finalize = mail_config_service_page_finalize;
+ object_class->constructed = mail_config_service_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVE_BACKEND,
+ g_param_spec_object (
+ "active-backend",
+ "Active Backend",
+ "The active service backend",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EMAIL_ADDRESS,
+ g_param_spec_string (
+ "email-address",
+ "Email Address",
+ "The user's email address",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_REGISTRY,
+ g_param_spec_object (
+ "registry",
+ "Registry",
+ "Data source registry",
+ E_TYPE_SOURCE_REGISTRY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_service_page_alert_sink_init (EAlertSinkInterface *interface)
+{
+ interface->submit_alert = mail_config_service_page_submit_alert;
+}
+
+static void
+e_mail_config_service_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->setup_defaults = mail_config_service_page_setup_defaults;
+ interface->check_complete = mail_config_service_page_check_complete;
+ interface->commit_changes = mail_config_service_page_commit_changes;
+}
+
+static void
+e_mail_config_service_page_init (EMailConfigServicePage *page)
+{
+ GPtrArray *candidates;
+ GPtrArray *hidden_candidates;
+ PangoAttribute *attr;
+ PangoAttrList *attr_list;
+ GtkLabel *label;
+ GtkWidget *frame;
+ GtkWidget *widget;
+ GtkWidget *container;
+ GtkTreeModel *tree_model;
+ GtkCellRenderer *renderer;
+
+ /* The candidates array holds scratch ESources, one for each
+ * item in the "type" combo box. Scratch ESources are never
+ * added to the registry, so backend extensions can make any
+ * changes they want to them. Whichever scratch ESource is
+ * "active" (selected in the "type" combo box) when the user
+ * clicks OK wins and is written to disk. The others are
+ * discarded. */
+ candidates = g_ptr_array_new_with_free_func (
+ (GDestroyNotify) mail_config_service_page_free_candidate);
+
+ /* Hidden candidates are not listed in the "type" combo box
+ * but their scratch ESource can still be "active". This is
+ * a hack to accommodate groupware backends. Usually when a
+ * hidden candidate is active the service page will not be
+ * visible anyway. */
+ hidden_candidates = g_ptr_array_new_with_free_func (
+ (GDestroyNotify) mail_config_service_page_free_candidate);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ page->priv = E_MAIL_CONFIG_SERVICE_PAGE_GET_PRIVATE (page);
+ page->priv->candidates = candidates;
+ page->priv->hidden_candidates = hidden_candidates;
+
+ /* Build a filtered model for the combo box, where row
+ * visibility is determined by the "selectable" column. */
+
+ page->priv->list_store = gtk_list_store_new (
+ NUM_COLUMNS,
+ G_TYPE_STRING, /* COLUMN_BACKEND_NAME */
+ G_TYPE_STRING, /* COLUMN_DISPLAY_NAME */
+ G_TYPE_BOOLEAN); /* COLUMN_SELECTABLE */
+
+ tree_model = gtk_tree_model_filter_new (
+ GTK_TREE_MODEL (page->priv->list_store), NULL);
+
+ gtk_tree_model_filter_set_visible_column (
+ GTK_TREE_MODEL_FILTER (tree_model), COLUMN_SELECTABLE);
+
+ /* Either the combo box or the label is shown, never both.
+ * But we create both widgets and keep them both up-to-date
+ * regardless just because it makes the logic simpler. */
+
+ container = GTK_WIDGET (page);
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 12);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ attr_list = pango_attr_list_new ();
+
+ attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
+ pango_attr_list_insert (attr_list, attr);
+
+ widget = gtk_label_new_with_mnemonic (_("Server _Type:"));
+ gtk_widget_set_margin_right (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_combo_box_new_with_model (tree_model);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_combo_box_set_id_column (
+ GTK_COMBO_BOX (widget), COLUMN_BACKEND_NAME);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 0, 1, 1);
+ page->priv->type_combo = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (
+ GTK_CELL_LAYOUT (widget), renderer, TRUE);
+ gtk_cell_layout_add_attribute (
+ GTK_CELL_LAYOUT (widget), renderer,
+ "text", COLUMN_DISPLAY_NAME);
+
+ widget = gtk_label_new (NULL);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_attributes (GTK_LABEL (widget), attr_list);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 0, 1, 1);
+ page->priv->type_label = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (_("Description:"));
+ gtk_widget_set_margin_right (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.0);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 2, 1);
+ page->priv->desc_label = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ pango_attr_list_unref (attr_list);
+
+ container = GTK_WIDGET (page);
+
+ widget = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ widget = e_mail_config_service_notebook_new ();
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ page->priv->notebook = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ /* Visibility is bound to the EActivityBar. */
+
+ frame = widget;
+
+ widget = e_activity_bar_new ();
+ gtk_container_add (GTK_CONTAINER (frame), widget);
+ page->priv->activity_bar = widget; /* not referenced */
+ /* EActivityBar controls its own visibility. */
+
+ g_object_bind_property (
+ widget, "visible",
+ frame, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ widget = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ /* Visibility is bound to the EAlertBar. */
+
+ frame = widget;
+
+ widget = e_alert_bar_new ();
+ gtk_container_add (GTK_CONTAINER (frame), widget);
+ page->priv->alert_bar = widget; /* not referenced */
+ /* EAlertBar controls its own visibility. */
+
+ g_object_bind_property (
+ widget, "visible",
+ frame, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ /* Keep the notebook's active page number synchronized with our
+ * own "active-backend" property. Avoid G_BINDING_SYNC_CREATE
+ * since we haven't added any notebook pages. */
+ g_object_bind_property (
+ page, "active-backend",
+ page->priv->notebook, "active-backend",
+ G_BINDING_BIDIRECTIONAL);
+
+ /* Keep the combo box's active row number synchronized with our
+ * own "active-backend" property. Avoid G_BINDING_SYNC_CREATE
+ * since we haven't added any combo box rows. */
+ g_object_bind_property_full (
+ page, "active-backend",
+ page->priv->type_combo, "active-id",
+ G_BINDING_BIDIRECTIONAL,
+ mail_config_service_page_backend_to_id,
+ mail_config_service_page_id_to_backend,
+ NULL, (GDestroyNotify) NULL);
+
+ /* This keeps the description field up-to-date. */
+ g_object_bind_property_full (
+ page->priv->type_combo, "active-id",
+ page->priv->desc_label, "label",
+ G_BINDING_DEFAULT,
+ mail_config_service_page_backend_name_to_description,
+ NULL,
+ NULL, (GDestroyNotify) NULL);
+
+ /* For the "Server Type", either the combo
+ * box or the label is visible, never both. */
+ g_object_bind_property (
+ page->priv->type_combo, "visible",
+ page->priv->type_label, "visible",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_INVERT_BOOLEAN);
+
+ g_signal_connect_swapped (
+ page->priv->type_combo, "changed",
+ G_CALLBACK (e_mail_config_page_changed), page);
+
+ g_object_unref (tree_model);
+}
+
+EMailConfigServiceBackend *
+e_mail_config_service_page_get_active_backend (EMailConfigServicePage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page), NULL);
+
+ return page->priv->active_backend;
+}
+
+void
+e_mail_config_service_page_set_active_backend (EMailConfigServicePage *page,
+ EMailConfigServiceBackend *backend)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page));
+
+ if (backend != NULL) {
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_object_ref (backend);
+ }
+
+ if (page->priv->active_backend != NULL)
+ g_object_unref (page->priv->active_backend);
+
+ page->priv->active_backend = backend;
+
+ g_object_notify (G_OBJECT (page), "active-backend");
+}
+
+const gchar *
+e_mail_config_service_page_get_email_address (EMailConfigServicePage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page), NULL);
+
+ return page->priv->email_address;
+}
+
+void
+e_mail_config_service_page_set_email_address (EMailConfigServicePage *page,
+ const gchar *email_address)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page));
+
+ g_free (page->priv->email_address);
+ page->priv->email_address = g_strdup (email_address);
+
+ g_object_notify (G_OBJECT (page), "email-address");
+}
+
+ESourceRegistry *
+e_mail_config_service_page_get_registry (EMailConfigServicePage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page), NULL);
+
+ return page->priv->registry;
+}
+
+EMailConfigServiceBackend *
+e_mail_config_service_page_add_scratch_source (EMailConfigServicePage *page,
+ ESource *scratch_source,
+ ESource *opt_collection)
+{
+ GtkWidget *widget;
+ GtkLabel *type_label;
+ GtkComboBox *type_combo;
+ GtkTreeIter iter;
+ Candidate *candidate;
+ const gchar *display_name;
+ gboolean selectable;
+ gint page_num;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (scratch_source), NULL);
+
+ if (opt_collection != NULL)
+ g_return_val_if_fail (E_IS_SOURCE (opt_collection), NULL);
+
+ type_label = GTK_LABEL (page->priv->type_label);
+ type_combo = GTK_COMBO_BOX (page->priv->type_combo);
+
+ candidate = mail_config_service_page_new_candidate (
+ page, scratch_source, opt_collection);
+ g_return_val_if_fail (candidate != NULL, NULL);
+
+ widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ e_mail_config_service_backend_insert_widgets (
+ candidate->backend, GTK_BOX (widget));
+ candidate->widget = g_object_ref_sink (widget);
+ gtk_widget_show (widget);
+
+ g_ptr_array_add (page->priv->candidates, candidate);
+
+ display_name = g_dgettext (
+ candidate->provider->translation_domain,
+ candidate->provider->name);
+
+ page_num = e_mail_config_service_notebook_add_page (
+ E_MAIL_CONFIG_SERVICE_NOTEBOOK (page->priv->notebook),
+ candidate->backend, widget);
+
+ selectable = e_mail_config_service_backend_get_selectable (
+ candidate->backend);
+
+ gtk_list_store_append (page->priv->list_store, &iter);
+
+ gtk_list_store_set (
+ page->priv->list_store, &iter,
+ COLUMN_BACKEND_NAME, candidate->name,
+ COLUMN_DISPLAY_NAME, display_name,
+ COLUMN_SELECTABLE, selectable,
+ -1);
+
+ /* The type label is only visible if we have one scratch source,
+ * so just always set the label text to the most recently added
+ * scratch source. */
+ gtk_label_set_text (type_label, display_name);
+
+ /* If no combo box row is active yet, choose the new row. */
+ if (gtk_combo_box_get_active_id (type_combo) == NULL)
+ gtk_combo_box_set_active_id (type_combo, candidate->name);
+
+ /* If the page number of the newly-added notebook page is zero,
+ * show the "type" label. Otherwise show the "type" combo box.
+ * There's an inverted "visible" binding between the combo box
+ * and label, so we only need to change one of the widgets. */
+ gtk_widget_set_visible (GTK_WIDGET (type_combo), page_num > 0);
+
+ return candidate->backend;
+}
+
+EMailConfigServiceBackend *
+e_mail_config_service_page_lookup_backend (EMailConfigServicePage *page,
+ const gchar *backend_name)
+{
+ guint index;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page), NULL);
+ g_return_val_if_fail (backend_name != NULL, NULL);
+
+ for (index = 0; index < page->priv->candidates->len; index++) {
+ Candidate *candidate;
+
+ candidate = page->priv->candidates->pdata[index];
+
+ if (g_strcmp0 (backend_name, candidate->name) == 0)
+ return candidate->backend;
+ }
+
+ return NULL;
+}
+
+EActivity *
+e_mail_config_service_page_new_activity (EMailConfigServicePage *page)
+{
+ EActivity *activity;
+ EActivityBar *activity_bar;
+ GCancellable *cancellable;
+
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page), NULL);
+
+ /* Clear any previous alerts. */
+ e_alert_bar_clear (E_ALERT_BAR (page->priv->alert_bar));
+
+ activity = e_activity_new ();
+
+ e_activity_set_alert_sink (activity, E_ALERT_SINK (page));
+
+ cancellable = camel_operation_new ();
+ e_activity_set_cancellable (activity, cancellable);
+ g_object_unref (cancellable);
+
+ activity_bar = E_ACTIVITY_BAR (page->priv->activity_bar);
+ e_activity_bar_set_activity (activity_bar, activity);
+
+ return activity;
+}
+
+void
+e_mail_config_service_page_auto_configure (EMailConfigServicePage *page,
+ EMailAutoconfig *autoconfig)
+{
+ EMailConfigServiceBackend *pop3 = NULL;
+ EMailConfigServiceBackend *imap = NULL;
+ EMailConfigServiceBackend *smtp = NULL;
+ guint ii;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_PAGE (page));
+ g_return_if_fail (E_IS_MAIL_AUTOCONFIG (autoconfig));
+
+ for (ii = 0; ii < page->priv->candidates->len; ii++) {
+ EMailConfigServiceBackendClass *class;
+ EMailConfigServiceBackend *backend;
+ Candidate *candidate;
+ gboolean configured;
+
+ candidate = page->priv->candidates->pdata[ii];
+
+ backend = candidate->backend;
+ class = E_MAIL_CONFIG_SERVICE_BACKEND_GET_CLASS (backend);
+
+ configured = e_mail_config_service_backend_auto_configure (
+ backend, autoconfig);
+
+ /* XXX There's a few specific backends to check for.
+ * It requires that we know about these backends,
+ * which violates the abstraction, but we need to
+ * break our own rule to be practical here. */
+ if (g_strcmp0 (class->backend_name, POP3_BACKEND_NAME) == 0)
+ pop3 = configured ? backend : NULL;
+ if (g_strcmp0 (class->backend_name, IMAP_BACKEND_NAME) == 0)
+ imap = configured ? backend : NULL;
+ if (g_strcmp0 (class->backend_name, SMTP_BACKEND_NAME) == 0)
+ smtp = configured ? backend : NULL;
+ }
+
+ /* Select POP3 before IMAP. If both are present we want IMAP. */
+ if (pop3 != NULL)
+ e_mail_config_service_page_set_active_backend (page, pop3);
+ if (imap != NULL)
+ e_mail_config_service_page_set_active_backend (page, imap);
+ if (smtp != NULL)
+ e_mail_config_service_page_set_active_backend (page, smtp);
+}
+
diff --git a/mail/e-mail-config-service-page.h b/mail/e-mail-config-service-page.h
new file mode 100644
index 0000000000..3c5a40e1c0
--- /dev/null
+++ b/mail/e-mail-config-service-page.h
@@ -0,0 +1,107 @@
+/*
+ * e-mail-config-service-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/* XXX This is very similar to ESourceConfig for address books and
+ * calendars, but not similar enough to easily unify the APIs.
+ * Probably with more thought and effort it could be done. */
+
+#ifndef E_MAIL_CONFIG_SERVICE_PAGE_H
+#define E_MAIL_CONFIG_SERVICE_PAGE_H
+
+#include <gtk/gtk.h>
+#include <camel/camel.h>
+#include <libedataserver/e-source-extension.h>
+#include <libedataserver/e-source-registry.h>
+
+#include <e-util/e-activity.h>
+#include <mail/e-mail-autoconfig.h>
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SERVICE_PAGE \
+ (e_mail_config_service_page_get_type ())
+#define E_MAIL_CONFIG_SERVICE_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_PAGE, EMailConfigServicePage))
+#define E_MAIL_CONFIG_SERVICE_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SERVICE_PAGE, EMailConfigServicePageClass))
+#define E_IS_MAIL_CONFIG_SERVICE_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_PAGE))
+#define E_IS_MAIL_CONFIG_SERVICE_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SERVICE_PAGE))
+#define E_MAIL_CONFIG_SERVICE_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SERVICE_PAGE, EMailConfigServicePageClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigServicePage EMailConfigServicePage;
+typedef struct _EMailConfigServicePageClass EMailConfigServicePageClass;
+typedef struct _EMailConfigServicePagePrivate EMailConfigServicePagePrivate;
+
+struct _EMailConfigServicePage {
+ GtkBox parent;
+ EMailConfigServicePagePrivate *priv;
+};
+
+struct _EMailConfigServicePageClass {
+ GtkBoxClass parent_class;
+
+ const gchar *extension_name;
+ CamelProviderType provider_type;
+ const gchar *default_backend_name;
+};
+
+GType e_mail_config_service_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigServiceBackend *
+ e_mail_config_service_page_get_active_backend
+ (EMailConfigServicePage *page);
+void e_mail_config_service_page_set_active_backend
+ (EMailConfigServicePage *page,
+ EMailConfigServiceBackend *backend);
+const gchar * e_mail_config_service_page_get_email_address
+ (EMailConfigServicePage *page);
+void e_mail_config_service_page_set_email_address
+ (EMailConfigServicePage *page,
+ const gchar *email_address);
+ESourceRegistry *
+ e_mail_config_service_page_get_registry
+ (EMailConfigServicePage *page);
+EMailConfigServiceBackend *
+ e_mail_config_service_page_add_scratch_source
+ (EMailConfigServicePage *page,
+ ESource *scratch_source,
+ ESource *opt_collection);
+EMailConfigServiceBackend *
+ e_mail_config_service_page_lookup_backend
+ (EMailConfigServicePage *page,
+ const gchar *backend_name);
+EActivity * e_mail_config_service_page_new_activity
+ (EMailConfigServicePage *page);
+void e_mail_config_service_page_auto_configure
+ (EMailConfigServicePage *page,
+ EMailAutoconfig *autoconfig);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_SERVICE_PAGE_H */
+
diff --git a/mail/e-mail-config-sidebar.c b/mail/e-mail-config-sidebar.c
new file mode 100644
index 0000000000..91d2dbaf81
--- /dev/null
+++ b/mail/e-mail-config-sidebar.c
@@ -0,0 +1,416 @@
+/*
+ * e-mail-config-sidebar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-sidebar.h"
+
+#define E_MAIL_CONFIG_SIDEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_SIDEBAR, EMailConfigSidebarPrivate))
+
+struct _EMailConfigSidebarPrivate {
+ EMailConfigNotebook *notebook;
+ gint active;
+
+ GHashTable *buttons_to_pages;
+ GHashTable *pages_to_buttons;
+
+ gulong page_added_handler_id;
+ gulong page_removed_handler_id;
+ gulong page_reordered_handler_id;
+};
+
+enum {
+ PROP_0,
+ PROP_ACTIVE,
+ PROP_NOTEBOOK
+};
+
+G_DEFINE_TYPE (
+ EMailConfigSidebar,
+ e_mail_config_sidebar,
+ GTK_TYPE_BUTTON_BOX)
+
+static void
+mail_config_sidebar_button_toggled (GtkToggleButton *button,
+ EMailConfigSidebar *sidebar)
+{
+ if (gtk_toggle_button_get_active (button)) {
+ GHashTable *hash_table;
+ GtkNotebook *notebook;
+ GtkWidget *page;
+ gint page_num;
+
+ hash_table = sidebar->priv->buttons_to_pages;
+ page = g_hash_table_lookup (hash_table, button);
+ g_return_if_fail (GTK_IS_WIDGET (page));
+
+ notebook = GTK_NOTEBOOK (sidebar->priv->notebook);
+ page_num = gtk_notebook_page_num (notebook, page);
+ e_mail_config_sidebar_set_active (sidebar, page_num);
+ }
+}
+
+static void
+mail_config_sidebar_notebook_page_added (GtkNotebook *notebook,
+ GtkWidget *page,
+ guint page_num,
+ EMailConfigSidebar *sidebar)
+{
+ GtkRadioButton *group_member;
+ GtkWidget *button;
+ GList *keys;
+ gchar *tab_label = NULL;
+
+ /* Grab another radio button if we have any. */
+ keys = g_hash_table_get_keys (sidebar->priv->buttons_to_pages);
+ group_member = (keys != NULL) ? GTK_RADIO_BUTTON (keys->data) : NULL;
+ g_list_free (keys);
+
+ gtk_container_child_get (
+ GTK_CONTAINER (notebook), page,
+ "tab-label", &tab_label, NULL);
+
+ button = gtk_radio_button_new_with_label_from_widget (
+ group_member, tab_label);
+ g_object_set (button, "draw-indicator", FALSE, NULL);
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_box_pack_start (GTK_BOX (sidebar), button, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (sidebar), button, page_num);
+ gtk_widget_show (button);
+
+ g_signal_connect (
+ button, "toggled",
+ G_CALLBACK (mail_config_sidebar_button_toggled), sidebar);
+
+ g_hash_table_insert (
+ sidebar->priv->pages_to_buttons,
+ g_object_ref (page), g_object_ref (button));
+
+ g_hash_table_insert (
+ sidebar->priv->buttons_to_pages,
+ g_object_ref (button), g_object_ref (page));
+}
+
+static void
+mail_config_sidebar_notebook_page_removed (GtkNotebook *notebook,
+ GtkWidget *page,
+ guint page_num,
+ EMailConfigSidebar *sidebar)
+{
+ GHashTable *hash_table;
+ GtkWidget *button;
+
+ hash_table = sidebar->priv->pages_to_buttons;
+ button = g_hash_table_lookup (hash_table, page);
+ g_return_if_fail (GTK_IS_WIDGET (button));
+
+ gtk_container_remove (GTK_CONTAINER (sidebar), button);
+
+ g_hash_table_remove (sidebar->priv->pages_to_buttons, page);
+ g_hash_table_remove (sidebar->priv->buttons_to_pages, button);
+}
+
+static void
+mail_config_sidebar_notebook_page_reordered (GtkNotebook *notebook,
+ GtkWidget *page,
+ guint page_num,
+ EMailConfigSidebar *sidebar)
+{
+ GHashTable *hash_table;
+ GtkWidget *button;
+
+ hash_table = sidebar->priv->pages_to_buttons;
+ button = g_hash_table_lookup (hash_table, page);
+ g_return_if_fail (GTK_IS_WIDGET (button));
+
+ gtk_box_reorder_child (GTK_BOX (sidebar), button, page_num);
+}
+
+static void
+mail_config_sidebar_set_notebook (EMailConfigSidebar *sidebar,
+ EMailConfigNotebook *notebook)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook));
+ g_return_if_fail (sidebar->priv->notebook == NULL);
+
+ sidebar->priv->notebook = g_object_ref (notebook);
+}
+
+static void
+mail_config_sidebar_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE:
+ e_mail_config_sidebar_set_active (
+ E_MAIL_CONFIG_SIDEBAR (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_NOTEBOOK:
+ mail_config_sidebar_set_notebook (
+ E_MAIL_CONFIG_SIDEBAR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_sidebar_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACTIVE:
+ g_value_set_int (
+ value,
+ e_mail_config_sidebar_get_active (
+ E_MAIL_CONFIG_SIDEBAR (object)));
+ return;
+
+ case PROP_NOTEBOOK:
+ g_value_set_object (
+ value,
+ e_mail_config_sidebar_get_notebook (
+ E_MAIL_CONFIG_SIDEBAR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_sidebar_dispose (GObject *object)
+{
+ EMailConfigSidebarPrivate *priv;
+
+ priv = E_MAIL_CONFIG_SIDEBAR_GET_PRIVATE (object);
+
+ if (priv->notebook != NULL) {
+ g_signal_handler_disconnect (
+ priv->notebook, priv->page_added_handler_id);
+ g_signal_handler_disconnect (
+ priv->notebook, priv->page_removed_handler_id);
+ g_signal_handler_disconnect (
+ priv->notebook, priv->page_reordered_handler_id);
+ g_object_unref (priv->notebook);
+ priv->notebook = NULL;
+ }
+
+ g_hash_table_remove_all (priv->buttons_to_pages);
+ g_hash_table_remove_all (priv->pages_to_buttons);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_sidebar_parent_class)->dispose (object);
+}
+
+static void
+mail_config_sidebar_finalize (GObject *object)
+{
+ EMailConfigSidebarPrivate *priv;
+
+ priv = E_MAIL_CONFIG_SIDEBAR_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->buttons_to_pages);
+ g_hash_table_destroy (priv->pages_to_buttons);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_sidebar_parent_class)->finalize (object);
+}
+
+static void
+mail_config_sidebar_constructed (GObject *object)
+{
+ EMailConfigSidebar *sidebar;
+ GtkNotebook *notebook;
+ gulong handler_id;
+ gint n_pages, ii;
+
+ sidebar = E_MAIL_CONFIG_SIDEBAR (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_sidebar_parent_class)->
+ constructed (object);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (sidebar), GTK_ORIENTATION_VERTICAL);
+
+ gtk_button_box_set_layout (
+ GTK_BUTTON_BOX (sidebar), GTK_BUTTONBOX_START);
+
+ gtk_box_set_homogeneous (GTK_BOX (sidebar), TRUE);
+ gtk_box_set_spacing (GTK_BOX (sidebar), 6);
+
+ /* Add buttons for existing notebook pages before
+ * binding to properties or connecting to signals. */
+
+ notebook = GTK_NOTEBOOK (sidebar->priv->notebook);
+ n_pages = gtk_notebook_get_n_pages (notebook);
+
+ for (ii = 0; ii < n_pages; ii++) {
+ GtkWidget *page;
+
+ page = gtk_notebook_get_nth_page (notebook, ii);
+ mail_config_sidebar_notebook_page_added (
+ notebook, page, (guint) ii, sidebar);
+ }
+
+ g_object_bind_property (
+ sidebar, "active",
+ notebook, "page",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ handler_id = g_signal_connect (
+ notebook, "page-added",
+ G_CALLBACK (mail_config_sidebar_notebook_page_added),
+ sidebar);
+ sidebar->priv->page_added_handler_id = handler_id;
+
+ handler_id = g_signal_connect (
+ notebook, "page-removed",
+ G_CALLBACK (mail_config_sidebar_notebook_page_removed),
+ sidebar);
+ sidebar->priv->page_removed_handler_id = handler_id;
+
+ handler_id = g_signal_connect (
+ notebook, "page-reordered",
+ G_CALLBACK (mail_config_sidebar_notebook_page_reordered),
+ sidebar);
+ sidebar->priv->page_reordered_handler_id = handler_id;
+}
+
+static void
+e_mail_config_sidebar_class_init (EMailConfigSidebarClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigSidebarPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_sidebar_set_property;
+ object_class->get_property = mail_config_sidebar_get_property;
+ object_class->dispose = mail_config_sidebar_dispose;
+ object_class->finalize = mail_config_sidebar_finalize;
+ object_class->constructed = mail_config_sidebar_constructed;
+
+ /* Use the same constraints as GtkNotebook:page. */
+ g_object_class_install_property (
+ object_class,
+ PROP_ACTIVE,
+ g_param_spec_int (
+ "active",
+ "Active",
+ "Index of the currently active button",
+ -1, G_MAXINT, -1,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_NOTEBOOK,
+ g_param_spec_object (
+ "notebook",
+ "Notebook",
+ "Mail configuration notebook",
+ E_TYPE_MAIL_CONFIG_NOTEBOOK,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_sidebar_init (EMailConfigSidebar *sidebar)
+{
+ GHashTable *buttons_to_pages;
+ GHashTable *pages_to_buttons;
+
+ buttons_to_pages = g_hash_table_new_full (
+ (GHashFunc) g_direct_hash,
+ (GEqualFunc) g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+
+ pages_to_buttons = g_hash_table_new_full (
+ (GHashFunc) g_direct_hash,
+ (GEqualFunc) g_direct_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+
+ sidebar->priv = E_MAIL_CONFIG_SIDEBAR_GET_PRIVATE (sidebar);
+ sidebar->priv->buttons_to_pages = buttons_to_pages;
+ sidebar->priv->pages_to_buttons = pages_to_buttons;
+}
+
+GtkWidget *
+e_mail_config_sidebar_new (EMailConfigNotebook *notebook)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_SIDEBAR,
+ "notebook", notebook, NULL);
+}
+
+gint
+e_mail_config_sidebar_get_active (EMailConfigSidebar *sidebar)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SIDEBAR (sidebar), -1);
+
+ return sidebar->priv->active;
+}
+
+void
+e_mail_config_sidebar_set_active (EMailConfigSidebar *sidebar,
+ gint active)
+{
+ GtkNotebook *notebook;
+ GtkWidget *page;
+
+ g_return_if_fail (E_IS_MAIL_CONFIG_SIDEBAR (sidebar));
+
+ notebook = GTK_NOTEBOOK (sidebar->priv->notebook);
+ page = gtk_notebook_get_nth_page (notebook, active);
+
+ sidebar->priv->active = (page != NULL) ? active : -1;
+
+ g_object_notify (G_OBJECT (sidebar), "active");
+
+ if (page != NULL) {
+ GHashTable *hash_table;
+ GtkToggleButton *button;
+
+ hash_table = sidebar->priv->pages_to_buttons;
+ button = g_hash_table_lookup (hash_table, page);
+ gtk_toggle_button_set_active (button, TRUE);
+ }
+}
+
+EMailConfigNotebook *
+e_mail_config_sidebar_get_notebook (EMailConfigSidebar *sidebar)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SIDEBAR (sidebar), NULL);
+
+ return sidebar->priv->notebook;
+}
+
diff --git a/mail/e-mail-config-sidebar.h b/mail/e-mail-config-sidebar.h
new file mode 100644
index 0000000000..50f272ef4e
--- /dev/null
+++ b/mail/e-mail-config-sidebar.h
@@ -0,0 +1,72 @@
+/*
+ * e-mail-config-sidebar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_SIDEBAR_H
+#define E_MAIL_CONFIG_SIDEBAR_H
+
+#include <mail/e-mail-config-notebook.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SIDEBAR \
+ (e_mail_config_sidebar_get_type ())
+#define E_MAIL_CONFIG_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SIDEBAR, EMailConfigSidebar))
+#define E_MAIL_CONFIG_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SIDEBAR, EMailConfigSidebarClass))
+#define E_IS_MAIL_CONFIG_SIDEBAR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SIDEBAR))
+#define E_IS_MAIL_CONFIG_SIDEBAR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SIDEBAR))
+#define E_MAIL_CONFIG_SIDEBAR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SIDEBAR, EMailConfigSidebarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigSidebar EMailConfigSidebar;
+typedef struct _EMailConfigSidebarClass EMailConfigSidebarClass;
+typedef struct _EMailConfigSidebarPrivate EMailConfigSidebarPrivate;
+
+struct _EMailConfigSidebar {
+ GtkButtonBox parent;
+ EMailConfigSidebarPrivate *priv;
+};
+
+struct _EMailConfigSidebarClass {
+ GtkButtonBoxClass parent_class;
+};
+
+GType e_mail_config_sidebar_get_type (void) G_GNUC_CONST;
+GtkWidget * e_mail_config_sidebar_new (EMailConfigNotebook *notebook);
+gint e_mail_config_sidebar_get_active
+ (EMailConfigSidebar *sidebar);
+void e_mail_config_sidebar_set_active
+ (EMailConfigSidebar *sidebar,
+ gint active);
+EMailConfigNotebook *
+ e_mail_config_sidebar_get_notebook
+ (EMailConfigSidebar *sidebar);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_SIDEBAR_H */
+
diff --git a/mail/e-mail-config-summary-page.c b/mail/e-mail-config-summary-page.c
new file mode 100644
index 0000000000..db6520ab1f
--- /dev/null
+++ b/mail/e-mail-config-summary-page.c
@@ -0,0 +1,1064 @@
+/*
+ * e-mail-config-summary-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-summary-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <camel/camel.h>
+
+#include <libebackend/e-extensible.h>
+#include <libedataserver/e-source-authentication.h>
+#include <libedataserver/e-source-collection.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-source-mail-transport.h>
+#include <libedataserver/e-source-security.h>
+
+#define E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_SUMMARY_PAGE, EMailConfigSummaryPagePrivate))
+
+struct _EMailConfigSummaryPagePrivate {
+ gchar *account_name;
+ ESource *account_source;
+ ESource *identity_source;
+ ESource *transport_source;
+ EMailConfigServiceBackend *account_backend;
+ EMailConfigServiceBackend *transport_backend;
+
+ gulong account_source_changed_id;
+ gulong identity_source_changed_id;
+ gulong transport_source_changed_id;
+
+ /* Widgets (not referenced) */
+ GtkLabel *name_label;
+ GtkLabel *address_label;
+ GtkLabel *recv_backend_label;
+ GtkLabel *recv_host_label;
+ GtkLabel *recv_user_label;
+ GtkLabel *recv_security_label;
+ GtkLabel *send_backend_label;
+ GtkLabel *send_host_label;
+ GtkLabel *send_user_label;
+ GtkLabel *send_security_label;
+ GtkEntry *account_name_entry;
+};
+
+enum {
+ PROP_0,
+ PROP_ACCOUNT_NAME,
+ PROP_ACCOUNT_BACKEND,
+ PROP_ACCOUNT_SOURCE,
+ PROP_IDENTITY_SOURCE,
+ PROP_TRANSPORT_BACKEND,
+ PROP_TRANSPORT_SOURCE
+};
+
+enum {
+ REFRESH,
+ LAST_SIGNAL
+};
+
+static gulong signals[LAST_SIGNAL];
+
+/* Forward Declarations */
+static void e_mail_config_summary_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigSummaryPage,
+ e_mail_config_summary_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_summary_page_interface_init))
+
+/* Helper for mail_config_summary_page_refresh() */
+static void
+mail_config_summary_page_refresh_auth_labels (ESource *source,
+ GtkLabel *host_label,
+ GtkLabel *user_label)
+{
+ ESourceAuthentication *extension;
+ const gchar *extension_name;
+ const gchar *value;
+
+ extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
+ if (!e_source_has_extension (source, extension_name))
+ return;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ value = e_source_authentication_get_host (extension);
+ gtk_label_set_text (host_label, value);
+
+ value = e_source_authentication_get_user (extension);
+ gtk_label_set_text (user_label, value);
+}
+
+/* Helper for mail_config_summary_page_refresh() */
+static void
+mail_config_summary_page_refresh_security_label (ESource *source,
+ GtkLabel *security_label)
+{
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+ ESourceSecurity *extension;
+ const gchar *extension_name;
+ const gchar *value;
+
+ extension_name = E_SOURCE_EXTENSION_SECURITY;
+ if (!e_source_has_extension (source, extension_name))
+ return;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ /* XXX This is a pain in the butt, but we want to avoid hard-coding
+ * string values from the CamelNetworkSecurityMethod enum class
+ * in case they change in the future. */
+ enum_class = g_type_class_ref (CAMEL_TYPE_NETWORK_SECURITY_METHOD);
+ value = e_source_security_get_method (extension);
+ if (value != NULL)
+ enum_value = g_enum_get_value_by_nick (enum_class, value);
+ else
+ enum_value = NULL;
+ if (enum_value == NULL) {
+ gtk_label_set_text (security_label, value);
+ } else switch ((CamelNetworkSecurityMethod) enum_value->value) {
+ case CAMEL_NETWORK_SECURITY_METHOD_NONE:
+ gtk_label_set_text (security_label, _("None"));
+ break;
+ case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT:
+ gtk_label_set_text (security_label, _("SSL"));
+ break;
+ case CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT:
+ gtk_label_set_text (security_label, _("TLS"));
+ break;
+ }
+ g_type_class_unref (enum_class);
+}
+
+static void
+mail_config_summary_page_source_changed (ESource *source,
+ EMailConfigSummaryPage *page)
+{
+ e_mail_config_summary_page_refresh (page);
+}
+
+static void
+mail_config_summary_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_NAME:
+ e_mail_config_summary_page_set_account_name (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_ACCOUNT_BACKEND:
+ e_mail_config_summary_page_set_account_backend (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ e_mail_config_summary_page_set_identity_source (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_TRANSPORT_BACKEND:
+ e_mail_config_summary_page_set_transport_backend (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_summary_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_NAME:
+ g_value_set_string (
+ value,
+ e_mail_config_summary_page_get_account_name (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object)));
+ return;
+
+ case PROP_ACCOUNT_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_summary_page_get_account_backend (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object)));
+ return;
+
+ case PROP_ACCOUNT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_summary_page_get_account_source (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object)));
+ return;
+
+ case PROP_IDENTITY_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_summary_page_get_identity_source (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object)));
+ return;
+
+ case PROP_TRANSPORT_BACKEND:
+ g_value_set_object (
+ value,
+ e_mail_config_summary_page_get_transport_backend (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object)));
+ return;
+
+ case PROP_TRANSPORT_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_summary_page_get_transport_source (
+ E_MAIL_CONFIG_SUMMARY_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_summary_page_dispose (GObject *object)
+{
+ EMailConfigSummaryPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE (object);
+
+ if (priv->account_source != NULL) {
+ g_signal_handler_disconnect (
+ priv->account_source,
+ priv->account_source_changed_id);
+ g_object_unref (priv->account_source);
+ priv->account_source = NULL;
+ priv->account_source_changed_id = 0;
+ }
+
+ if (priv->identity_source != NULL) {
+ g_signal_handler_disconnect (
+ priv->identity_source,
+ priv->identity_source_changed_id);
+ g_object_unref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ if (priv->transport_source != NULL) {
+ g_signal_handler_disconnect (
+ priv->transport_source,
+ priv->transport_source_changed_id);
+ g_object_unref (priv->transport_source);
+ priv->transport_source = NULL;
+ priv->transport_source_changed_id = 0;
+ }
+
+ if (priv->account_backend != NULL) {
+ g_object_unref (priv->account_backend);
+ priv->account_backend = NULL;
+ }
+
+ if (priv->transport_backend != NULL) {
+ g_object_unref (priv->transport_backend);
+ priv->transport_backend = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_summary_page_parent_class)->
+ dispose (object);
+}
+
+static void
+mail_config_summary_page_finalize (GObject *object)
+{
+ EMailConfigSummaryPagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE (object);
+
+ g_free (priv->account_name);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_summary_page_parent_class)->
+ finalize (object);
+}
+
+static void
+mail_config_summary_page_constructed (GObject *object)
+{
+ EMailConfigSummaryPage *page;
+ GtkLabel *label;
+ GtkWidget *widget;
+ GtkWidget *container;
+ GtkSizeGroup *size_group;
+ const gchar *text;
+ gchar *markup;
+
+ page = E_MAIL_CONFIG_SUMMARY_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_summary_page_parent_class)->
+ constructed (object);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ /* This page is dense with information,
+ * so put extra space between sections. */
+ gtk_box_set_spacing (GTK_BOX (page), 24);
+
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ text = _("This is a summary of the settings which will be used "
+ "to access your mail.");
+ widget = gtk_label_new (text);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ /*** Account Information ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Account Information");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Type the name by which you would like to refer to "
+ "this account.\nFor example, \"Work\" or \"Personal\".");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 2, 1);
+ gtk_widget_show (widget);
+
+ text = _("_Name:");
+ widget = gtk_label_new_with_mnemonic (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ label = GTK_LABEL (widget);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_label_set_mnemonic_widget (label, widget);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ page->priv->account_name_entry = GTK_ENTRY (widget);
+ gtk_widget_show (widget);
+
+ /* This entry affects the "check-complete" result. */
+ g_signal_connect_swapped (
+ widget, "changed",
+ G_CALLBACK (e_mail_config_page_changed), page);
+
+ g_object_bind_property (
+ widget, "text",
+ page, "account-name",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ /*** Details ***/
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 12);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ text = _("Personal Details");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 3, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Full Name:");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 2, 1);
+ page->priv->name_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ text = _("Email Address:");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 2, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 2, 1);
+ page->priv->address_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ text = _("Receiving");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_margin_top (widget, 6);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 3, 1, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Sending");
+ markup = g_markup_printf_escaped ("<b>%s</b>", text);
+ widget = gtk_label_new (markup);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_margin_top (widget, 6);
+ gtk_size_group_add_widget (size_group, widget);
+ gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 3, 1, 1);
+ gtk_widget_show (widget);
+ g_free (markup);
+
+ text = _("Server Type:");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 4, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 4, 1, 1);
+ page->priv->recv_backend_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 4, 1, 1);
+ page->priv->send_backend_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ text = _("Server:");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 5, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 5, 1, 1);
+ page->priv->recv_host_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 5, 1, 1);
+ page->priv->send_host_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ text = _("Username:");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 6, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 6, 1, 1);
+ page->priv->recv_user_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 6, 1, 1);
+ page->priv->send_user_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ text = _("Security:");
+ widget = gtk_label_new (text);
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 7, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 7, 1, 1);
+ page->priv->recv_security_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ widget = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 7, 1, 1);
+ page->priv->send_security_label = GTK_LABEL (widget);
+ gtk_widget_show (widget);
+
+ g_object_unref (size_group);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static void
+mail_config_summary_page_refresh (EMailConfigSummaryPage *page)
+{
+ EMailConfigSummaryPagePrivate *priv;
+ ESource *source;
+ gboolean account_is_transport = FALSE;
+
+ priv = E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE (page);
+
+ /* Clear all labels. */
+ gtk_label_set_text (priv->name_label, "");
+ gtk_label_set_text (priv->address_label, "");
+ gtk_label_set_text (priv->recv_backend_label, "");
+ gtk_label_set_text (priv->recv_host_label, "");
+ gtk_label_set_text (priv->recv_user_label, "");
+ gtk_label_set_text (priv->recv_security_label, "");
+ gtk_label_set_text (priv->send_backend_label, "");
+ gtk_label_set_text (priv->send_host_label, "");
+ gtk_label_set_text (priv->send_user_label, "");
+ gtk_label_set_text (priv->send_security_label, "");
+
+ source = e_mail_config_summary_page_get_identity_source (page);
+
+ if (source != NULL) {
+ ESourceMailIdentity *extension;
+ const gchar *extension_name;
+ const gchar *value;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (source, extension_name);
+
+ value = e_source_mail_identity_get_name (extension);
+ gtk_label_set_text (priv->name_label, value);
+
+ value = e_source_mail_identity_get_address (extension);
+ gtk_label_set_text (priv->address_label, value);
+ }
+
+ source = e_mail_config_summary_page_get_account_source (page);
+
+ if (source != NULL) {
+ ESourceBackend *extension;
+ const gchar *extension_name;
+ const gchar *value;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+
+ value = e_source_backend_get_backend_name (extension);
+ gtk_label_set_text (priv->recv_backend_label, value);
+
+ mail_config_summary_page_refresh_auth_labels (
+ source,
+ priv->recv_host_label,
+ priv->recv_user_label);
+
+ mail_config_summary_page_refresh_security_label (
+ source,
+ priv->recv_security_label);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+ if (e_source_has_extension (source, extension_name))
+ account_is_transport = TRUE;
+ }
+
+ if (account_is_transport)
+ source = e_mail_config_summary_page_get_account_source (page);
+ else
+ source = e_mail_config_summary_page_get_transport_source (page);
+
+ if (source != NULL) {
+ ESourceBackend *extension;
+ const gchar *extension_name;
+ const gchar *value;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
+ extension = e_source_get_extension (source, extension_name);
+
+ value = e_source_backend_get_backend_name (extension);
+ gtk_label_set_text (priv->send_backend_label, value);
+
+ mail_config_summary_page_refresh_auth_labels (
+ source,
+ priv->send_host_label,
+ priv->send_user_label);
+
+ mail_config_summary_page_refresh_security_label (
+ source,
+ priv->send_security_label);
+ }
+}
+
+static gboolean
+mail_config_summary_page_check_complete (EMailConfigPage *page)
+{
+ EMailConfigSummaryPagePrivate *priv;
+ gchar *stripped_text;
+ const gchar *text;
+ gboolean complete;
+
+ priv = E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE (page);
+
+ /* Strip the account name of leading and trailing
+ * whitespace as e_source_set_display_name() does. */
+ text = gtk_entry_get_text (priv->account_name_entry);
+ stripped_text = g_strstrip (g_strdup ((text != NULL) ? text : ""));
+ complete = (*stripped_text != '\0');
+ g_free (stripped_text);
+
+ return complete;
+}
+
+static void
+mail_config_summary_page_commit_changes (EMailConfigPage *page,
+ GQueue *source_queue)
+{
+ EMailConfigSummaryPagePrivate *priv;
+ EMailConfigServiceBackend *backend;
+ ESource *account_source;
+ ESource *identity_source;
+ ESource *transport_source;
+ ESource *collection_source;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ const gchar *parent_uid;
+ const gchar *text;
+
+ priv = E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE (page);
+
+ backend = e_mail_config_summary_page_get_account_backend (
+ E_MAIL_CONFIG_SUMMARY_PAGE (page));
+ account_source =
+ e_mail_config_service_backend_get_source (backend);
+ collection_source =
+ e_mail_config_service_backend_get_collection (backend);
+
+ /* The transport backend is NULL when the Sending Page is hidden. */
+ backend = e_mail_config_summary_page_get_transport_backend (
+ E_MAIL_CONFIG_SUMMARY_PAGE (page));
+ transport_source = (backend != NULL) ?
+ e_mail_config_service_backend_get_source (backend) : NULL;
+
+ identity_source = e_mail_config_summary_page_get_identity_source (
+ E_MAIL_CONFIG_SUMMARY_PAGE (page));
+
+ text = gtk_entry_get_text (priv->account_name_entry);
+ e_source_set_display_name (account_source, text);
+ e_source_set_display_name (identity_source, text);
+ if (transport_source != NULL)
+ e_source_set_display_name (transport_source, text);
+ if (collection_source != NULL)
+ e_source_set_display_name (collection_source, text);
+
+ /* Setup parent/child relationships and cross-references. */
+
+ if (collection_source != NULL) {
+ parent_uid = e_source_get_uid (collection_source);
+ e_source_set_parent (account_source, parent_uid);
+ e_source_set_parent (identity_source, parent_uid);
+ if (transport_source != NULL)
+ e_source_set_parent (transport_source, parent_uid);
+ } else {
+ parent_uid = e_source_get_uid (account_source);
+ e_source_set_parent (identity_source, parent_uid);
+ if (transport_source != NULL)
+ e_source_set_parent (transport_source, parent_uid);
+ }
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (account_source, extension_name);
+ e_source_mail_account_set_identity_uid (
+ E_SOURCE_MAIL_ACCOUNT (extension),
+ e_source_get_uid (identity_source));
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ extension = e_source_get_extension (identity_source, extension_name);
+ if (transport_source != NULL)
+ e_source_mail_submission_set_transport_uid (
+ E_SOURCE_MAIL_SUBMISSION (extension),
+ e_source_get_uid (transport_source));
+}
+
+static void
+e_mail_config_summary_page_class_init (EMailConfigSummaryPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigSummaryPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_summary_page_set_property;
+ object_class->get_property = mail_config_summary_page_get_property;
+ object_class->dispose = mail_config_summary_page_dispose;
+ object_class->finalize = mail_config_summary_page_finalize;
+ object_class->constructed = mail_config_summary_page_constructed;
+
+ class->refresh = mail_config_summary_page_refresh;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_NAME,
+ g_param_spec_string (
+ "account-name",
+ "Account Name",
+ "Display name for the mail account",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_BACKEND,
+ g_param_spec_object (
+ "account-backend",
+ "Account Backend",
+ "Active mail account service backend",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ACCOUNT_SOURCE,
+ g_param_spec_object (
+ "account-source",
+ "Account Source",
+ "Mail account source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IDENTITY_SOURCE,
+ g_param_spec_object (
+ "identity-source",
+ "Identity Source",
+ "Mail identity source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TRANSPORT_BACKEND,
+ g_param_spec_object (
+ "transport-backend",
+ "Transport Backend",
+ "Active mail transport service backend",
+ E_TYPE_MAIL_CONFIG_SERVICE_BACKEND,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TRANSPORT_SOURCE,
+ g_param_spec_object (
+ "transport-source",
+ "Transport Source",
+ "Mail transport source being edited",
+ E_TYPE_SOURCE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[REFRESH] = g_signal_new (
+ "refresh",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMailConfigSummaryPageClass, refresh),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_mail_config_summary_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Account Summary");
+ interface->sort_order = E_MAIL_CONFIG_SUMMARY_PAGE_SORT_ORDER;
+ interface->check_complete = mail_config_summary_page_check_complete;
+ interface->commit_changes = mail_config_summary_page_commit_changes;
+}
+
+static void
+e_mail_config_summary_page_init (EMailConfigSummaryPage *page)
+{
+ page->priv = E_MAIL_CONFIG_SUMMARY_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_summary_page_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_CONFIG_SUMMARY_PAGE, NULL);
+}
+
+void
+e_mail_config_summary_page_refresh (EMailConfigSummaryPage *page)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page));
+
+ g_signal_emit (page, signals[REFRESH], 0);
+}
+
+const gchar *
+e_mail_config_summary_page_get_account_name (EMailConfigSummaryPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page), NULL);
+
+ return page->priv->account_name;
+}
+
+void
+e_mail_config_summary_page_set_account_name (EMailConfigSummaryPage *page,
+ const gchar *account_name)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page));
+
+ if (account_name == NULL)
+ account_name = "";
+
+ g_free (page->priv->account_name);
+ page->priv->account_name = g_strdup (account_name);
+
+ g_object_notify (G_OBJECT (page), "account-name");
+}
+
+EMailConfigServiceBackend *
+e_mail_config_summary_page_get_account_backend (EMailConfigSummaryPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page), NULL);
+
+ return page->priv->account_backend;
+}
+
+void
+e_mail_config_summary_page_set_account_backend (EMailConfigSummaryPage *page,
+ EMailConfigServiceBackend *backend)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page));
+
+ if (backend != NULL) {
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_object_ref (backend);
+ }
+
+ if (page->priv->account_backend != NULL)
+ g_object_unref (page->priv->account_backend);
+
+ page->priv->account_backend = backend;
+
+ if (page->priv->account_source != NULL) {
+ g_signal_handler_disconnect (
+ page->priv->account_source,
+ page->priv->account_source_changed_id);
+ g_object_unref (page->priv->account_source);
+ page->priv->account_source = NULL;
+ page->priv->account_source_changed_id = 0;
+ }
+
+ if (backend != NULL) {
+ ESource *source;
+ gulong handler_id;
+
+ source = e_mail_config_service_backend_get_source (backend);
+
+ handler_id = g_signal_connect (
+ source, "changed",
+ G_CALLBACK (mail_config_summary_page_source_changed),
+ page);
+
+ page->priv->account_source = g_object_ref (source);
+ page->priv->account_source_changed_id = handler_id;
+ }
+
+ g_object_freeze_notify (G_OBJECT (page));
+ g_object_notify (G_OBJECT (page), "account-backend");
+ g_object_notify (G_OBJECT (page), "account-source");
+ g_object_thaw_notify (G_OBJECT (page));
+
+ e_mail_config_summary_page_refresh (page);
+}
+
+ESource *
+e_mail_config_summary_page_get_account_source (EMailConfigSummaryPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page), NULL);
+
+ return page->priv->account_source;
+}
+
+ESource *
+e_mail_config_summary_page_get_identity_source (EMailConfigSummaryPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page), NULL);
+
+ return page->priv->identity_source;
+}
+
+void
+e_mail_config_summary_page_set_identity_source (EMailConfigSummaryPage *page,
+ ESource *identity_source)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page));
+
+ if (identity_source != NULL) {
+ g_return_if_fail (E_IS_SOURCE (identity_source));
+ g_object_ref (identity_source);
+ }
+
+ if (page->priv->identity_source != NULL) {
+ g_signal_handler_disconnect (
+ page->priv->identity_source,
+ page->priv->identity_source_changed_id);
+ g_object_unref (page->priv->identity_source);
+ }
+
+ page->priv->identity_source = identity_source;
+ page->priv->identity_source_changed_id = 0;
+
+ if (identity_source != NULL) {
+ gulong handler_id;
+
+ handler_id = g_signal_connect (
+ identity_source, "changed",
+ G_CALLBACK (mail_config_summary_page_source_changed),
+ page);
+
+ page->priv->identity_source_changed_id = handler_id;
+ }
+
+ g_object_notify (G_OBJECT (page), "identity-source");
+
+ e_mail_config_summary_page_refresh (page);
+}
+
+EMailConfigServiceBackend *
+e_mail_config_summary_page_get_transport_backend (EMailConfigSummaryPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page), NULL);
+
+ return page->priv->transport_backend;
+}
+
+void
+e_mail_config_summary_page_set_transport_backend (EMailConfigSummaryPage *page,
+ EMailConfigServiceBackend *backend)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page));
+
+ if (backend != NULL) {
+ g_return_if_fail (E_IS_MAIL_CONFIG_SERVICE_BACKEND (backend));
+ g_object_ref (backend);
+ }
+
+ if (page->priv->transport_backend != NULL)
+ g_object_unref (page->priv->transport_backend);
+
+ page->priv->transport_backend = backend;
+
+ if (page->priv->transport_source != NULL) {
+ g_signal_handler_disconnect (
+ page->priv->transport_source,
+ page->priv->transport_source_changed_id);
+ g_object_unref (page->priv->transport_source);
+ page->priv->transport_source = NULL;
+ page->priv->transport_source_changed_id = 0;
+ }
+
+ if (backend != NULL) {
+ ESource *source;
+ gulong handler_id;
+
+ source = e_mail_config_service_backend_get_source (backend);
+
+ handler_id = g_signal_connect (
+ source, "changed",
+ G_CALLBACK (mail_config_summary_page_source_changed),
+ page);
+
+ page->priv->transport_source = g_object_ref (source);
+ page->priv->transport_source_changed_id = handler_id;
+ }
+
+ g_object_freeze_notify (G_OBJECT (page));
+ g_object_notify (G_OBJECT (page), "transport-backend");
+ g_object_notify (G_OBJECT (page), "transport-source");
+ g_object_thaw_notify (G_OBJECT (page));
+
+ e_mail_config_summary_page_refresh (page);
+}
+
+ESource *
+e_mail_config_summary_page_get_transport_source (EMailConfigSummaryPage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_SUMMARY_PAGE (page), NULL);
+
+ return page->priv->transport_source;
+}
+
diff --git a/mail/e-mail-config-summary-page.h b/mail/e-mail-config-summary-page.h
new file mode 100644
index 0000000000..564207c9e1
--- /dev/null
+++ b/mail/e-mail-config-summary-page.h
@@ -0,0 +1,101 @@
+/*
+ * e-mail-config-summary-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_SUMMARY_PAGE_H
+#define E_MAIL_CONFIG_SUMMARY_PAGE_H
+
+#include <gtk/gtk.h>
+#include <libedataserver/e-source.h>
+
+#include <mail/e-mail-config-page.h>
+#include <mail/e-mail-config-service-backend.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_SUMMARY_PAGE \
+ (e_mail_config_summary_page_get_type ())
+#define E_MAIL_CONFIG_SUMMARY_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_SUMMARY_PAGE, EMailConfigSummaryPage))
+#define E_MAIL_CONFIG_SUMMARY_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_SUMMARY_PAGE, EMailConfigSummaryPageClass))
+#define E_IS_MAIL_CONFIG_SUMMARY_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_SUMMARY_PAGE))
+#define E_IS_MAIL_CONFIG_SUMMARY_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_SUMMARY_PAGE))
+#define E_MAIL_CONFIG_SUMMARY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_SUMMARY_PAGE, EMailConfigSummaryPageClass))
+
+#define E_MAIL_CONFIG_SUMMARY_PAGE_SORT_ORDER (500)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigSummaryPage EMailConfigSummaryPage;
+typedef struct _EMailConfigSummaryPageClass EMailConfigSummaryPageClass;
+typedef struct _EMailConfigSummaryPagePrivate EMailConfigSummaryPagePrivate;
+
+struct _EMailConfigSummaryPage {
+ GtkBox parent;
+ EMailConfigSummaryPagePrivate *priv;
+};
+
+struct _EMailConfigSummaryPageClass {
+ GtkBoxClass parent_class;
+
+ /* Signals */
+ void (*refresh) (EMailConfigSummaryPage *page);
+};
+
+GType e_mail_config_summary_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_summary_page_new (void);
+void e_mail_config_summary_page_refresh
+ (EMailConfigSummaryPage *page);
+const gchar * e_mail_config_summary_page_get_account_name
+ (EMailConfigSummaryPage *page);
+void e_mail_config_summary_page_set_account_name
+ (EMailConfigSummaryPage *page,
+ const gchar *account_name);
+EMailConfigServiceBackend *
+ e_mail_config_summary_page_get_account_backend
+ (EMailConfigSummaryPage *page);
+void e_mail_config_summary_page_set_account_backend
+ (EMailConfigSummaryPage *page,
+ EMailConfigServiceBackend *backend);
+ESource * e_mail_config_summary_page_get_account_source
+ (EMailConfigSummaryPage *page);
+ESource * e_mail_config_summary_page_get_identity_source
+ (EMailConfigSummaryPage *page);
+void e_mail_config_summary_page_set_identity_source
+ (EMailConfigSummaryPage *page,
+ ESource *identity_source);
+EMailConfigServiceBackend *
+ e_mail_config_summary_page_get_transport_backend
+ (EMailConfigSummaryPage *page);
+void e_mail_config_summary_page_set_transport_backend
+ (EMailConfigSummaryPage *page,
+ EMailConfigServiceBackend *backend);
+ESource * e_mail_config_summary_page_get_transport_source
+ (EMailConfigSummaryPage *page);
+
+#endif /* E_MAIL_CONFIG_SUMMARY_PAGE_H */
+
diff --git a/mail/e-mail-config-welcome-page.c b/mail/e-mail-config-welcome-page.c
new file mode 100644
index 0000000000..6cb9fd19a6
--- /dev/null
+++ b/mail/e-mail-config-welcome-page.c
@@ -0,0 +1,203 @@
+/*
+ * e-mail-config-welcome-page.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-welcome-page.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libebackend/e-extensible.h>
+
+#define E_MAIL_CONFIG_WELCOME_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_WELCOME_PAGE, EMailConfigWelcomePagePrivate))
+
+struct _EMailConfigWelcomePagePrivate {
+ gchar *text;
+};
+
+enum {
+ PROP_0,
+ PROP_TEXT
+};
+
+/* Forward Declarations */
+static void e_mail_config_welcome_page_interface_init
+ (EMailConfigPageInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigWelcomePage,
+ e_mail_config_welcome_page,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_EXTENSIBLE, NULL)
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_MAIL_CONFIG_PAGE,
+ e_mail_config_welcome_page_interface_init))
+
+static void
+mail_config_welcome_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TEXT:
+ e_mail_config_welcome_page_set_text (
+ E_MAIL_CONFIG_WELCOME_PAGE (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_welcome_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TEXT:
+ g_value_set_string (
+ value,
+ e_mail_config_welcome_page_get_text (
+ E_MAIL_CONFIG_WELCOME_PAGE (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_welcome_page_finalize (GObject *object)
+{
+ EMailConfigWelcomePagePrivate *priv;
+
+ priv = E_MAIL_CONFIG_WELCOME_PAGE_GET_PRIVATE (object);
+
+ g_free (priv->text);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_mail_config_welcome_page_parent_class)->
+ finalize (object);
+}
+
+static void
+mail_config_welcome_page_constructed (GObject *object)
+{
+ EMailConfigWelcomePage *page;
+ GtkWidget *widget;
+
+ page = E_MAIL_CONFIG_WELCOME_PAGE (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_welcome_page_parent_class)->
+ constructed (object);
+
+ gtk_orientable_set_orientation (
+ GTK_ORIENTABLE (page), GTK_ORIENTATION_VERTICAL);
+
+ gtk_box_set_spacing (GTK_BOX (page), 12);
+
+ gtk_widget_set_valign (GTK_WIDGET (page), GTK_ALIGN_CENTER);
+
+ widget = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (page), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ g_object_bind_property (
+ page, "text",
+ widget, "label",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+
+ e_extensible_load_extensions (E_EXTENSIBLE (page));
+}
+
+static void
+e_mail_config_welcome_page_class_init (EMailConfigWelcomePageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EMailConfigWelcomePagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_welcome_page_set_property;
+ object_class->get_property = mail_config_welcome_page_get_property;
+ object_class->finalize = mail_config_welcome_page_finalize;
+ object_class->constructed = mail_config_welcome_page_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT,
+ g_param_spec_string (
+ "text",
+ "Text",
+ "Welcome message",
+ _("Welcome to the Evolution Mail Configuration "
+ "Assistant.\n\nClick \"Continue\" to begin."),
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_welcome_page_interface_init (EMailConfigPageInterface *interface)
+{
+ interface->title = _("Welcome");
+ interface->page_type = GTK_ASSISTANT_PAGE_INTRO;
+ interface->sort_order = E_MAIL_CONFIG_WELCOME_PAGE_SORT_ORDER;
+}
+
+static void
+e_mail_config_welcome_page_init (EMailConfigWelcomePage *page)
+{
+ page->priv = E_MAIL_CONFIG_WELCOME_PAGE_GET_PRIVATE (page);
+}
+
+EMailConfigPage *
+e_mail_config_welcome_page_new (void)
+{
+ return g_object_new (E_TYPE_MAIL_CONFIG_WELCOME_PAGE, NULL);
+}
+
+const gchar *
+e_mail_config_welcome_page_get_text (EMailConfigWelcomePage *page)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_WELCOME_PAGE (page), NULL);
+
+ return page->priv->text;
+}
+
+void
+e_mail_config_welcome_page_set_text (EMailConfigWelcomePage *page,
+ const gchar *text)
+{
+ g_return_if_fail (E_IS_MAIL_CONFIG_WELCOME_PAGE (page));
+
+ g_free (page->priv->text);
+ page->priv->text = g_strdup ((text != NULL) ? text : "");
+
+ g_object_notify (G_OBJECT (page), "text");
+}
+
diff --git a/mail/e-mail-config-welcome-page.h b/mail/e-mail-config-welcome-page.h
new file mode 100644
index 0000000000..a7665ecc56
--- /dev/null
+++ b/mail/e-mail-config-welcome-page.h
@@ -0,0 +1,75 @@
+/*
+ * e-mail-config-welcome-page.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_WELCOME_PAGE_H
+#define E_MAIL_CONFIG_WELCOME_PAGE_H
+
+#include <gtk/gtk.h>
+
+#include <mail/e-mail-config-page.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_WELCOME_PAGE \
+ (e_mail_config_welcome_page_get_type ())
+#define E_MAIL_CONFIG_WELCOME_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_WELCOME_PAGE, EMailConfigWelcomePage))
+#define E_MAIL_CONFIG_WELCOME_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_WELCOME_PAGE, EMailConfigWelcomePageClass))
+#define E_IS_MAIL_CONFIG_WELCOME_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_WELCOME_PAGE))
+#define E_IS_MAIL_CONFIG_WELCOME_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_WELCOME_PAGE))
+#define E_MAIL_CONFIG_WELCOME_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_WELCOME_PAGE, EMailConfigWelcomePageClass))
+
+#define E_MAIL_CONFIG_WELCOME_PAGE_SORT_ORDER (0)
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigWelcomePage EMailConfigWelcomePage;
+typedef struct _EMailConfigWelcomePageClass EMailConfigWelcomePageClass;
+typedef struct _EMailConfigWelcomePagePrivate EMailConfigWelcomePagePrivate;
+
+struct _EMailConfigWelcomePage {
+ GtkBox parent;
+ EMailConfigWelcomePagePrivate *priv;
+};
+
+struct _EMailConfigWelcomePageClass {
+ GtkBoxClass parent_class;
+};
+
+GType e_mail_config_welcome_page_get_type
+ (void) G_GNUC_CONST;
+EMailConfigPage *
+ e_mail_config_welcome_page_new (void);
+const gchar * e_mail_config_welcome_page_get_text
+ (EMailConfigWelcomePage *page);
+void e_mail_config_welcome_page_set_text
+ (EMailConfigWelcomePage *page,
+ const gchar *text);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_WELCOME_PAGE_H */
+
diff --git a/mail/e-mail-config-window.c b/mail/e-mail-config-window.c
new file mode 100644
index 0000000000..746e1c3e80
--- /dev/null
+++ b/mail/e-mail-config-window.c
@@ -0,0 +1,524 @@
+/*
+ * e-mail-config-window.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "e-mail-config-window.h"
+
+#include <config.h>
+#include <glib/gi18n-lib.h>
+
+#include <libedataserver/e-source-collection.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-submission.h>
+
+#include <libevolution-utils/e-alert-dialog.h>
+#include <libevolution-utils/e-alert-sink.h>
+#include <misc/e-alert-bar.h>
+
+#include <mail/e-mail-config-notebook.h>
+#include <mail/e-mail-config-sidebar.h>
+
+#define E_MAIL_CONFIG_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_MAIL_CONFIG_WINDOW, EMailConfigWindowPrivate))
+
+struct _EMailConfigWindowPrivate {
+ EMailSession *session;
+ ESource *original_source;
+
+ /* Scratch Sources */
+ ESource *account_source;
+ ESource *identity_source;
+ ESource *transport_source;
+ ESource *collection_source; /* optional */
+
+ GtkWidget *notebook; /* not referenced */
+ GtkWidget *alert_bar; /* not referenced */
+};
+
+enum {
+ PROP_0,
+ PROP_ORIGINAL_SOURCE,
+ PROP_SESSION
+};
+
+/* Forward Declarations */
+static void e_mail_config_window_alert_sink_init
+ (EAlertSinkInterface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ EMailConfigWindow,
+ e_mail_config_window,
+ GTK_TYPE_DIALOG,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_ALERT_SINK,
+ e_mail_config_window_alert_sink_init))
+
+static ESource *
+mail_config_window_clone_source (ESource *source)
+{
+ ESource *clone;
+ GDBusObject *dbus_object;
+
+ dbus_object = e_source_ref_dbus_object (source);
+
+ clone = e_source_new (dbus_object, NULL, NULL);
+
+ if (dbus_object != NULL)
+ g_object_unref (dbus_object);
+
+ return clone;
+}
+
+static void
+mail_config_window_setup_scratch_sources (EMailConfigWindow *window)
+{
+ ESource *source;
+ ESource *scratch_source;
+ ESourceRegistry *registry;
+ ESourceMailAccount *account_ext;
+ ESourceMailSubmission *submission_ext;
+ EMailSession *session;
+ const gchar *extension_name;
+ const gchar *uid;
+
+ session = e_mail_config_window_get_session (window);
+ registry = e_mail_session_get_registry (session);
+
+ source = window->priv->original_source;
+ scratch_source = mail_config_window_clone_source (source);
+ window->priv->account_source = scratch_source;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ account_ext = e_source_get_extension (source, extension_name);
+ uid = e_source_mail_account_get_identity_uid (account_ext);
+ source = e_source_registry_ref_source (registry, uid);
+ scratch_source = mail_config_window_clone_source (source);
+ window->priv->identity_source = scratch_source;
+ g_object_unref (source);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ submission_ext = e_source_get_extension (source, extension_name);
+ uid = e_source_mail_submission_get_transport_uid (submission_ext);
+ source = e_source_registry_ref_source (registry, uid);
+ scratch_source = mail_config_window_clone_source (source);
+ window->priv->transport_source = scratch_source;
+ g_object_unref (source);
+
+ extension_name = E_SOURCE_EXTENSION_COLLECTION;
+ source = e_source_registry_find_extension (
+ registry, window->priv->original_source, extension_name);
+ if (source != NULL) {
+ scratch_source = mail_config_window_clone_source (source);
+ window->priv->collection_source = scratch_source;
+ g_object_unref (source);
+ }
+}
+
+static void
+mail_config_window_commit_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EMailConfigWindow *window;
+ EMailConfigNotebook *notebook;
+ GdkWindow *gdk_window;
+ GError *error = NULL;
+
+ window = E_MAIL_CONFIG_WINDOW (user_data);
+ notebook = E_MAIL_CONFIG_NOTEBOOK (object);
+
+ /* Set the cursor back to normal. */
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+ gdk_window_set_cursor (gdk_window, NULL);
+
+ /* Allow user interaction with window content. */
+ gtk_widget_set_sensitive (GTK_WIDGET (window), TRUE);
+
+ e_mail_config_notebook_commit_finish (notebook, result, &error);
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_object_unref (window);
+ g_error_free (error);
+
+ } else if (error != NULL) {
+ e_alert_submit (
+ E_ALERT_SINK (window),
+ "mail:session-message-error",
+ error->message, NULL);
+ g_object_unref (window);
+ g_error_free (error);
+
+ } else {
+ gtk_widget_destroy (GTK_WIDGET (window));
+ }
+}
+
+static void
+mail_config_window_commit (EMailConfigWindow *window)
+{
+ GdkCursor *gdk_cursor;
+ GdkWindow *gdk_window;
+ EMailConfigNotebook *notebook;
+
+ notebook = E_MAIL_CONFIG_NOTEBOOK (window->priv->notebook);
+
+ /* Clear any previous alerts. */
+ e_alert_bar_clear (E_ALERT_BAR (window->priv->alert_bar));
+
+ /* Make the cursor appear busy. */
+ gdk_cursor = gdk_cursor_new (GDK_WATCH);
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+ gdk_window_set_cursor (gdk_window, gdk_cursor);
+ g_object_unref (gdk_cursor);
+
+ /* Prevent user interaction with window content. */
+ gtk_widget_set_sensitive (GTK_WIDGET (window), FALSE);
+
+ /* XXX This operation is not cancellable. */
+ e_mail_config_notebook_commit (
+ notebook, NULL,
+ mail_config_window_commit_cb,
+ g_object_ref (window));
+}
+
+static void
+mail_config_window_set_original_source (EMailConfigWindow *window,
+ ESource *original_source)
+{
+ g_return_if_fail (E_IS_SOURCE (original_source));
+ g_return_if_fail (window->priv->original_source == NULL);
+
+ window->priv->original_source = g_object_ref (original_source);
+}
+
+static void
+mail_config_window_set_session (EMailConfigWindow *window,
+ EMailSession *session)
+{
+ g_return_if_fail (E_IS_MAIL_SESSION (session));
+ g_return_if_fail (window->priv->session == NULL);
+
+ window->priv->session = g_object_ref (session);
+}
+
+static void
+mail_config_window_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORIGINAL_SOURCE:
+ mail_config_window_set_original_source (
+ E_MAIL_CONFIG_WINDOW (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SESSION:
+ mail_config_window_set_session (
+ E_MAIL_CONFIG_WINDOW (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_window_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ORIGINAL_SOURCE:
+ g_value_set_object (
+ value,
+ e_mail_config_window_get_original_source (
+ E_MAIL_CONFIG_WINDOW (object)));
+ return;
+
+ case PROP_SESSION:
+ g_value_set_object (
+ value,
+ e_mail_config_window_get_session (
+ E_MAIL_CONFIG_WINDOW (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_config_window_dispose (GObject *object)
+{
+ EMailConfigWindowPrivate *priv;
+
+ priv = E_MAIL_CONFIG_WINDOW_GET_PRIVATE (object);
+
+ if (priv->session != NULL) {
+ g_object_unref (priv->session);
+ priv->session = NULL;
+ }
+
+ if (priv->original_source != NULL) {
+ g_object_unref (priv->original_source);
+ priv->original_source = NULL;
+ }
+
+ if (priv->account_source != NULL) {
+ g_object_unref (priv->account_source);
+ priv->account_source = NULL;
+ }
+
+ if (priv->identity_source != NULL) {
+ g_object_unref (priv->identity_source);
+ priv->identity_source = NULL;
+ }
+
+ if (priv->transport_source != NULL) {
+ g_object_unref (priv->transport_source);
+ priv->transport_source = NULL;
+ }
+
+ if (priv->collection_source != NULL) {
+ g_object_unref (priv->collection_source);
+ priv->collection_source = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_config_window_parent_class)->dispose (object);
+}
+
+static void
+mail_config_window_constructed (GObject *object)
+{
+ EMailConfigWindow *window;
+ GtkWidget *container;
+ GtkWidget *widget;
+
+ window = E_MAIL_CONFIG_WINDOW (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_mail_config_window_parent_class)->
+ constructed (object);
+
+ mail_config_window_setup_scratch_sources (window);
+
+ gtk_container_set_border_width (GTK_CONTAINER (window), 5);
+ gtk_window_set_title (GTK_WINDOW (window), _("Account Editor"));
+ gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (window),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (window));
+
+ widget = gtk_grid_new ();
+ gtk_grid_set_column_spacing (GTK_GRID (widget), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 5);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = e_alert_bar_new ();
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 3, 1);
+ window->priv->alert_bar = widget; /* not referenced */
+ /* EAlertBar controls its own visibility. */
+
+ /* Add an extra-wide margin to the left and bottom.
+ *
+ * XXX The bottom margin is tricky. We want a 24px margin between
+ * the notebook and the dialog action buttons, but we have to
+ * take style property defaults into consideration:
+ *
+ * 24 - action-area-border (5) - content-area-border (2) = 17
+ */
+ widget = e_mail_config_notebook_new (
+ window->priv->session,
+ window->priv->account_source,
+ window->priv->identity_source,
+ window->priv->transport_source,
+ window->priv->collection_source);
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_widget_set_vexpand (widget, TRUE);
+ gtk_widget_set_margin_bottom (widget, 17);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
+ gtk_grid_attach (GTK_GRID (container), widget, 2, 1, 1, 1);
+ window->priv->notebook = widget; /* not referenced */
+ gtk_widget_show (widget);
+
+ widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
+ gtk_widget_set_vexpand (widget, TRUE);
+ gtk_widget_set_valign (widget, GTK_ALIGN_FILL);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ widget = e_mail_config_sidebar_new (
+ E_MAIL_CONFIG_NOTEBOOK (window->priv->notebook));
+ gtk_widget_set_vexpand (widget, TRUE);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ /* Make the Apply button insensitive when required
+ * fields in the notebook pages are incomplete. */
+
+ widget = gtk_dialog_get_widget_for_response (
+ GTK_DIALOG (window), GTK_RESPONSE_OK);
+
+ g_object_bind_property (
+ window->priv->notebook, "complete",
+ widget, "sensitive",
+ G_BINDING_SYNC_CREATE);
+}
+
+static void
+mail_config_window_response (GtkDialog *dialog,
+ gint response_id)
+{
+ /* Do not chain up. GtkDialog does not implement this method. */
+
+ switch (response_id) {
+ case GTK_RESPONSE_OK:
+ mail_config_window_commit (
+ E_MAIL_CONFIG_WINDOW (dialog));
+ break;
+ case GTK_RESPONSE_CANCEL:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+mail_config_window_submit_alert (EAlertSink *alert_sink,
+ EAlert *alert)
+{
+ EMailConfigWindowPrivate *priv;
+ EAlertBar *alert_bar;
+ GtkWidget *dialog;
+ GtkWindow *parent;
+
+ priv = E_MAIL_CONFIG_WINDOW_GET_PRIVATE (alert_sink);
+
+ switch (e_alert_get_message_type (alert)) {
+ case GTK_MESSAGE_INFO:
+ case GTK_MESSAGE_WARNING:
+ case GTK_MESSAGE_ERROR:
+ alert_bar = E_ALERT_BAR (priv->alert_bar);
+ e_alert_bar_add_alert (alert_bar, alert);
+ break;
+
+ default:
+ parent = GTK_WINDOW (alert_sink);
+ dialog = e_alert_dialog_new (parent, alert);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ break;
+ }
+}
+
+static void
+e_mail_config_window_class_init (EMailConfigWindowClass *class)
+{
+ GObjectClass *object_class;
+ GtkDialogClass *dialog_class;
+
+ g_type_class_add_private (class, sizeof (EMailConfigWindowPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = mail_config_window_set_property;
+ object_class->get_property = mail_config_window_get_property;
+ object_class->dispose = mail_config_window_dispose;
+ object_class->constructed = mail_config_window_constructed;
+
+ dialog_class = GTK_DIALOG_CLASS (class);
+ dialog_class->response = mail_config_window_response;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ORIGINAL_SOURCE,
+ g_param_spec_object (
+ "original-source",
+ "Original Source",
+ "Original mail account source",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SESSION,
+ g_param_spec_object (
+ "session",
+ "Session",
+ "Mail session",
+ E_TYPE_MAIL_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_mail_config_window_alert_sink_init (EAlertSinkInterface *interface)
+{
+ interface->submit_alert = mail_config_window_submit_alert;
+}
+
+static void
+e_mail_config_window_init (EMailConfigWindow *window)
+{
+ window->priv = E_MAIL_CONFIG_WINDOW_GET_PRIVATE (window);
+}
+
+GtkWidget *
+e_mail_config_window_new (EMailSession *session,
+ ESource *original_source)
+{
+ g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
+ g_return_val_if_fail (E_IS_SOURCE (original_source), NULL);
+
+ return g_object_new (
+ E_TYPE_MAIL_CONFIG_WINDOW,
+ "original-source", original_source,
+ "session", session, NULL);
+}
+
+EMailSession *
+e_mail_config_window_get_session (EMailConfigWindow *window)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_WINDOW (window), NULL);
+
+ return window->priv->session;
+}
+
+ESource *
+e_mail_config_window_get_original_source (EMailConfigWindow *window)
+{
+ g_return_val_if_fail (E_IS_MAIL_CONFIG_WINDOW (window), NULL);
+
+ return window->priv->original_source;
+}
+
diff --git a/mail/e-mail-config-window.h b/mail/e-mail-config-window.h
new file mode 100644
index 0000000000..78a7c073b8
--- /dev/null
+++ b/mail/e-mail-config-window.h
@@ -0,0 +1,71 @@
+/*
+ * e-mail-config-window.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef E_MAIL_CONFIG_WINDOW_H
+#define E_MAIL_CONFIG_WINDOW_H
+
+#include <gtk/gtk.h>
+
+#include <libemail-engine/e-mail-session.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_CONFIG_WINDOW \
+ (e_mail_config_window_get_type ())
+#define E_MAIL_CONFIG_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MAIL_CONFIG_WINDOW, EMailConfigWindow))
+#define E_MAIL_CONFIG_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MAIL_CONFIG_WINDOW, EMailConfigWindowClass))
+#define E_IS_MAIL_CONFIG_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MAIL_CONFIG_WINDOW))
+#define E_IS_MAIL_CONFIG_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_MAIL_CONFIG_WINDOW))
+#define E_MAIL_CONFIG_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MAIL_CONFIG_WINDOW, EMailConfigWindowClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailConfigWindow EMailConfigWindow;
+typedef struct _EMailConfigWindowClass EMailConfigWindowClass;
+typedef struct _EMailConfigWindowPrivate EMailConfigWindowPrivate;
+
+struct _EMailConfigWindow {
+ GtkDialog parent;
+ EMailConfigWindowPrivate *priv;
+};
+
+struct _EMailConfigWindowClass {
+ GtkDialogClass parent_class;
+};
+
+GType e_mail_config_window_get_type (void) G_GNUC_CONST;
+GtkWidget * e_mail_config_window_new (EMailSession *session,
+ ESource *original_source);
+EMailSession * e_mail_config_window_get_session
+ (EMailConfigWindow *window);
+ESource * e_mail_config_window_get_original_source
+ (EMailConfigWindow *window);
+
+G_END_DECLS
+
+#endif /* E_MAIL_CONFIG_WINDOW_H */
+
diff --git a/mail/e-mail-folder-pane.c b/mail/e-mail-folder-pane.c
index 7e0457e3bd..03168cec18 100644
--- a/mail/e-mail-folder-pane.c
+++ b/mail/e-mail-folder-pane.c
@@ -74,7 +74,10 @@ folder_pane_set_preview_visible (EMailView *view,
static guint
mail_paned_view_open_selected_mail (EMailPanedView *view)
{
+ EShell *shell;
EMailReader *reader;
+ EMailBackend *backend;
+ ESourceRegistry *registry;
GPtrArray *uids;
gint i;
GtkWindow *window;
@@ -88,6 +91,10 @@ mail_paned_view_open_selected_mail (EMailPanedView *view)
uids = e_mail_reader_get_selected_uids (reader);
g_return_val_if_fail (uids != NULL, 0);
+ backend = e_mail_reader_get_backend (reader);
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+ registry = e_shell_get_registry (shell);
+
/* XXX Either e_mail_reader_get_selected_uids()
* or MessageList should do this itself. */
g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
@@ -97,9 +104,9 @@ mail_paned_view_open_selected_mail (EMailPanedView *view)
return 0;
}
- if (em_utils_folder_is_drafts (folder) ||
- em_utils_folder_is_outbox (folder) ||
- em_utils_folder_is_templates (folder)) {
+ if (em_utils_folder_is_drafts (registry, folder) ||
+ em_utils_folder_is_outbox (registry, folder) ||
+ em_utils_folder_is_templates (registry, folder)) {
em_utils_edit_messages (reader, folder, uids, TRUE);
g_ptr_array_unref (uids);
return 0;
@@ -127,8 +134,8 @@ mail_paned_view_open_selected_mail (EMailPanedView *view)
CAMEL_VEE_FOLDER (folder),
(CamelVeeMessageInfo *) info, &real_uid);
- if (em_utils_folder_is_drafts (real_folder) ||
- em_utils_folder_is_outbox (real_folder)) {
+ if (em_utils_folder_is_drafts (registry, real_folder) ||
+ em_utils_folder_is_outbox (registry, real_folder)) {
GPtrArray *edits;
edits = g_ptr_array_new_with_free_func (
diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c
index ffc5f1a264..a485a1e0d2 100644
--- a/mail/e-mail-migrate.c
+++ b/mail/e-mail-migrate.c
@@ -50,6 +50,9 @@
#include <libedataserver/e-xml-utils.h>
#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-camel.h>
+#include <libedataserver/e-source-registry.h>
+#include <libedataserver/e-source-mail-account.h>
#include <shell/e-shell.h>
#include <shell/e-shell-migrate.h>
@@ -61,9 +64,6 @@
#include <e-util/e-util-private.h>
#include <e-util/e-plugin.h>
-#include <libemail-utils/e-account-utils.h>
-#include <libemail-utils/e-signature-utils.h>
-
#include <libemail-engine/e-mail-folder-utils.h>
#include "e-mail-backend.h"
@@ -221,50 +221,6 @@ cp (const gchar *src,
return FALSE;
}
-#ifndef G_OS_WIN32
-
-#define SUBFOLDER_DIR_NAME "subfolders"
-#define SUBFOLDER_DIR_NAME_LEN 10
-
-static void
-em_update_accounts_2_11 (void)
-{
- EAccountList *accounts;
- EIterator *iter;
- gboolean changed = FALSE;
-
- if (!(accounts = e_get_account_list ()))
- return;
-
- iter = e_list_get_iterator ((EList *) accounts);
- while (e_iterator_is_valid (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
-
- if (g_str_has_prefix (account->source->url, "spool://")) {
- if (g_file_test (account->source->url + 8, G_FILE_TEST_IS_DIR)) {
- gchar *str;
-
- str = g_strdup_printf (
- "spooldir://%s",
- account->source->url + 8);
-
- g_free (account->source->url);
- account->source->url = str;
- changed = TRUE;
- }
- }
-
- e_iterator_next (iter);
- }
-
- g_object_unref (iter);
-
- if (changed)
- e_account_list_save (accounts);
-}
-
-#endif /* !G_OS_WIN32 */
-
static gboolean
emm_setup_initial (const gchar *data_dir)
{
@@ -600,27 +556,67 @@ static gboolean
migrate_mbox_to_maildir (EShellBackend *shell_backend,
EMMigrateSession *session)
{
- CamelService *mbox_service, *maildir_service;
- CamelStore *mbox_store, *maildir_store;
+ EShell *shell;
+ ESource *source;
+ ESourceRegistry *registry;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ CamelService *mbox_service;
+ CamelService *maildir_service;
+ CamelStore *mbox_store;
+ CamelStore *maildir_store;
CamelSettings *settings;
const gchar *data_dir;
+ const gchar *uid;
gchar *path;
struct MigrateStore ms;
+ GError *error = NULL;
data_dir = e_shell_backend_get_data_dir (shell_backend);
+ shell = e_shell_backend_get_shell (shell_backend);
+ registry = e_shell_get_registry (shell);
+
+ source = e_source_new (NULL, NULL, NULL);
+ e_source_set_display_name (source, "local_mbox");
- mbox_service = camel_session_add_service (
- CAMEL_SESSION (session), "local_mbox", "mbox",
- CAMEL_PROVIDER_STORE, NULL);
+ uid = e_source_get_uid (source);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ extension = e_source_get_extension (source, extension_name);
+
+ e_source_backend_set_backend_name (
+ E_SOURCE_BACKEND (extension), "mbox");
+
+ extension_name = e_source_camel_get_extension_name ("mbox");
+ extension = e_source_get_extension (source, extension_name);
+ settings = e_source_camel_get_settings (E_SOURCE_CAMEL (extension));
- settings = camel_service_get_settings (mbox_service);
path = g_build_filename (data_dir, "local_mbox", NULL);
g_object_set (settings, "path", path, NULL);
g_free (path);
- maildir_service = camel_session_add_service (
- CAMEL_SESSION (session), "local", "maildir",
- CAMEL_PROVIDER_STORE, NULL);
+ e_source_registry_commit_source_sync (
+ registry, source, NULL, &error);
+
+ if (error == NULL)
+ mbox_service = camel_session_add_service (
+ CAMEL_SESSION (session), uid, "mbox",
+ CAMEL_PROVIDER_STORE, &error);
+
+ if (error == NULL)
+ maildir_service = camel_session_add_service (
+ CAMEL_SESSION (session), "local", "maildir",
+ CAMEL_PROVIDER_STORE, &error);
+
+ g_object_unref (source);
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ camel_service_set_settings (mbox_service, settings);
settings = camel_service_get_settings (maildir_service);
path = g_build_filename (data_dir, "local", NULL);
@@ -667,412 +663,6 @@ exit:
}
static gboolean
-create_mbox_account (EShellBackend *shell_backend,
- EMMigrateSession *session)
-{
- EMailBackend *mail_backend;
- EMailSession *mail_session;
- CamelService *service;
- CamelURL *url;
- EAccountList *accounts;
- EAccount *account;
- const gchar *data_dir;
- gchar *name, *id, *temp, *uri, *folder_uri;
-
- mail_backend = E_MAIL_BACKEND (shell_backend);
- mail_session = e_mail_backend_get_session (mail_backend);
- data_dir = e_shell_backend_get_data_dir (shell_backend);
-
- account = e_account_new ();
- account->enabled = TRUE;
-
- g_free (account->uid);
- account->uid = g_strdup ("local_mbox");
-
- url = camel_url_new ("mbox:", NULL);
- temp = g_build_filename (data_dir, "local_mbox", NULL);
- camel_url_set_path (url, temp);
- g_free (temp);
-
- uri = camel_url_to_string (url, 0);
- e_account_set_string (account, E_ACCOUNT_SOURCE_URL, uri);
-
-#ifndef G_OS_WIN32
- name = g_locale_to_utf8 (g_get_user_name (), -1, NULL, NULL, NULL);
-#else
- name = g_strdup (g_get_user_name ());
-#endif
-
- id = g_strconcat (name, "@", "localhost", NULL);
- e_account_set_string (account, E_ACCOUNT_ID_NAME, name);
- e_account_set_string (account, E_ACCOUNT_ID_ADDRESS, id);
- e_account_set_string (account, E_ACCOUNT_NAME, id);
-
- accounts = e_get_account_list ();
- if (e_account_list_find (accounts, E_ACCOUNT_ID_ADDRESS, id)) {
- g_object_unref (account);
- goto exit;
- }
-
- /* This will also add it to the EMailSession. */
- e_account_list_add (accounts, account);
-
- service = camel_session_get_service (
- CAMEL_SESSION (mail_session), account->uid);
-
- folder_uri = e_mail_folder_uri_build (
- CAMEL_STORE (service), "Sent");
- e_account_set_string (
- account, E_ACCOUNT_SENT_FOLDER_URI, folder_uri);
- g_free (folder_uri);
-
- folder_uri = e_mail_folder_uri_build (
- CAMEL_STORE (service), "Drafts");
- e_account_set_string (
- account, E_ACCOUNT_DRAFTS_FOLDER_URI, folder_uri);
- g_free (folder_uri);
-
- e_account_list_save (accounts);
-
-exit:
- camel_url_free (url);
- g_free (uri);
- g_free (name);
- g_free (id);
-
- return TRUE;
-}
-
-static void
-change_sent_and_drafts_local_folders (EShellBackend *shell_backend)
-{
- EMailBackend *backend;
- EMailSession *session;
- EAccountList *accounts;
- EIterator *iter;
- const gchar *data_dir;
- gboolean changed = FALSE;
- CamelURL *url;
- gchar *tmp_uri, *drafts_uri, *sent_uri, *old_drafts_uri, *old_sent_uri;
-
- accounts = e_get_account_list ();
- if (!accounts)
- return;
-
- backend = E_MAIL_BACKEND (shell_backend);
- session = e_mail_backend_get_session (backend);
-
- data_dir = e_shell_backend_get_data_dir (shell_backend);
-
- tmp_uri = g_strconcat ("mbox:", data_dir, "/", "local", NULL);
- url = camel_url_new (tmp_uri, NULL);
- g_free (tmp_uri);
-
- g_return_if_fail (url != NULL);
-
- camel_url_set_fragment (url, "Drafts");
- drafts_uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-
- camel_url_set_fragment (url, "Sent");
- sent_uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-
- camel_url_free (url);
-
- tmp_uri = g_strconcat (
- "mbox:", g_get_home_dir (),
- "/.evolution/mail/local", NULL);
- url = camel_url_new (tmp_uri, NULL);
- g_free (tmp_uri);
-
- g_return_if_fail (url != NULL);
-
- camel_url_set_fragment (url, "Drafts");
- old_drafts_uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-
- camel_url_set_fragment (url, "Sent");
- old_sent_uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
-
- camel_url_free (url);
-
- for (iter = e_list_get_iterator ((EList *) accounts);
- e_iterator_is_valid (iter); e_iterator_next (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
- const gchar *uri;
-
- if (!account)
- continue;
-
- uri = e_account_get_string (account, E_ACCOUNT_DRAFTS_FOLDER_URI);
- if (g_strcmp0 (uri, drafts_uri) == 0 ||
- g_strcmp0 (uri, old_drafts_uri) == 0) {
- changed = TRUE;
- e_account_set_string (
- account, E_ACCOUNT_DRAFTS_FOLDER_URI,
- e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_DRAFTS));
- }
-
- uri = e_account_get_string (account, E_ACCOUNT_SENT_FOLDER_URI);
- if (g_strcmp0 (uri, sent_uri) == 0 || g_strcmp0 (uri, old_sent_uri) == 0) {
- changed = TRUE;
- e_account_set_string (
- account, E_ACCOUNT_SENT_FOLDER_URI,
- e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_SENT));
- }
- }
-
- g_object_unref (iter);
- g_free (old_drafts_uri);
- g_free (drafts_uri);
- g_free (old_sent_uri);
- g_free (sent_uri);
-
- if (changed)
- e_account_list_save (accounts);
-}
-
-static void
-em_rename_camel_url_params (CamelURL *url)
-{
- /* This list includes known URL parameters from built-in providers
- * in Camel, as well as from evolution-exchange, evolution-groupwise,
- * and evolution-mapi. Add more as needed. */
- static struct {
- const gchar *url_parameter;
- const gchar *property_name;
- } camel_url_conversion[] = {
- { "account_uid", "account-uid" },
- { "ad_auth", "gc-auth-method" },
- { "ad_browse", "gc-allow-browse" },
- { "ad_expand_groups", "gc-expand-groups" },
- { "ad_limit", "gc-results-limit" },
- { "ad_server", "gc-server-name" },
- { "all_headers", "fetch-headers" },
- { "basic_headers", "fetch-headers" },
- { "cachedconn" "concurrent-connections" },
- { "check_all", "check-all" },
- { "check_lsub", "check-subscribed" },
- { "command", "shell-command" },
- { "delete_after", "delete-after-days" },
- { "delete_expunged", "delete-expunged" },
- { "disable_extensions", "disable-extensions" },
- { "dotfolders", "use-dot-folders" },
- { "filter", "filter-inbox" },
- { "filter_junk", "filter-junk" },
- { "filter_junk_inbox", "filter-junk-inbox" },
- { "folder_hierarchy_relative", "folder-hierarchy-relative" },
- { "imap_custom_headers", "fetch-headers-extra" },
- { "keep_on_server", "keep-on-server" },
- { "oab_offline", "oab-offline" },
- { "oal_selected", "oal-selected" },
- { "offline_sync", "stay-synchronized" },
- { "override_namespace", "use-namespace" },
- { "owa_path", "owa-path" },
- { "owa_url", "owa-url" },
- { "password_exp_warn_period", "password-exp-warn-period" },
- { "real_junk_path", "real-junk-path" },
- { "real_trash_path", "real-trash-path" },
- { "show_short_notation", "short-folder-names" },
- { "soap_port", "soap-port" },
- { "ssl", "security-method" },
- { "sync_offline", "stay-synchronized" },
- { "use_command", "use-shell-command" },
- { "use_idle", "use-idle" },
- { "use_lsub", "use-subscriptions" },
- { "use_qresync", "use-qresync" },
- { "use_ssl", "security-method" },
- { "xstatus", "use-xstatus-headers" }
- };
-
- const gchar *param;
- const gchar *use_param;
- gint ii;
-
- for (ii = 0; ii < G_N_ELEMENTS (camel_url_conversion); ii++) {
- const gchar *key;
- gpointer value;
-
- key = camel_url_conversion[ii].url_parameter;
- value = g_datalist_get_data (&url->params, key);
-
- if (value == NULL)
- continue;
-
- g_datalist_remove_no_notify (&url->params, key);
-
- key = camel_url_conversion[ii].property_name;
-
- /* Deal with a few special enum cases where
- * the parameter value also needs renamed. */
-
- if (strcmp (key, "all_headers") == 0) {
- GEnumClass *enum_class;
- GEnumValue *enum_value;
-
- enum_class = g_type_class_ref (
- CAMEL_TYPE_FETCH_HEADERS_TYPE);
- enum_value = g_enum_get_value (
- enum_class, CAMEL_FETCH_HEADERS_ALL);
- if (enum_value != NULL) {
- g_free (value);
- value = g_strdup (enum_value->value_nick);
- } else
- g_warn_if_reached ();
- g_type_class_unref (enum_class);
- }
-
- if (strcmp (key, "basic_headers") == 0) {
- GEnumClass *enum_class;
- GEnumValue *enum_value;
-
- enum_class = g_type_class_ref (
- CAMEL_TYPE_FETCH_HEADERS_TYPE);
- enum_value = g_enum_get_value (
- enum_class, CAMEL_FETCH_HEADERS_BASIC);
- if (enum_value != NULL) {
- g_free (value);
- value = g_strdup (enum_value->value_nick);
- } else
- g_warn_if_reached ();
- g_type_class_unref (enum_class);
- }
-
- if (strcmp (key, "imap_custom_headers") == 0)
- g_strdelimit (value, " ", ',');
-
- if (strcmp (key, "security-method") == 0) {
- CamelNetworkSecurityMethod method;
- GEnumClass *enum_class;
- GEnumValue *enum_value;
-
- if (strcmp (value, "always") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
- else if (strcmp (value, "1") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
- else if (strcmp (value, "when-possible") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
- else
- method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
-
- enum_class = g_type_class_ref (
- CAMEL_TYPE_NETWORK_SECURITY_METHOD);
- enum_value = g_enum_get_value (enum_class, method);
- if (enum_value != NULL) {
- g_free (value);
- value = g_strdup (enum_value->value_nick);
- } else
- g_warn_if_reached ();
- g_type_class_unref (enum_class);
- }
-
- g_datalist_set_data_full (&url->params, key, value, g_free);
- }
-
- /* A few more adjustments...
- *
- * These are all CAMEL_PROVIDER_CONF_CHECKSPIN settings. The spin
- * button value is bound to "param" and the checkbox state is bound
- * to "use-param". The "use-param" settings are new. If "param"
- * exists but no "use-param", then set "use-param" to "true". */
-
- param = g_datalist_get_data (&url->params, "gc-results-limit");
- use_param = g_datalist_get_data (&url->params, "use-gc-results-limit");
- if (param != NULL && *param != '\0' && use_param == NULL) {
- g_datalist_set_data_full (
- &url->params, "use-gc-results-limit",
- g_strdup ("true"), (GDestroyNotify) g_free);
- }
-
- param = g_datalist_get_data (&url->params, "kerberos");
- if (g_strcmp0 (param, "required") == 0) {
- g_datalist_set_data_full (
- &url->params, "kerberos",
- g_strdup ("true"), (GDestroyNotify) g_free);
- }
-
- param = g_datalist_get_data (
- &url->params, "password-exp-warn-period");
- use_param = g_datalist_get_data (
- &url->params, "use-password-exp-warn-period");
- if (param != NULL && *param != '\0' && use_param == NULL) {
- g_datalist_set_data_full (
- &url->params, "use-password-exp-warn-period",
- g_strdup ("true"), (GDestroyNotify) g_free);
- }
-
- param = g_datalist_get_data (&url->params, "real-junk-path");
- use_param = g_datalist_get_data (&url->params, "use-real-junk-path");
- if (param != NULL && *param != '\0' && use_param == NULL) {
- g_datalist_set_data_full (
- &url->params, "use-real-junk-path",
- g_strdup ("true"), (GDestroyNotify) g_free);
- }
-
- param = g_datalist_get_data (&url->params, "real-trash-path");
- use_param = g_datalist_get_data (&url->params, "use-real-trash-path");
- if (param != NULL && *param != '\0' && use_param == NULL) {
- g_datalist_set_data_full (
- &url->params, "use-real-trash-path",
- g_strdup ("true"), (GDestroyNotify) g_free);
- }
-}
-
-static void
-em_rename_account_params (void)
-{
- EAccountList *account_list;
- EIterator *iterator;
-
- /* XXX As of 3.2, CamelServices store settings in GObject properties,
- * not CamelURL parameters. CamelURL parameters are still used
- * for storage in GConf until we can move account information to
- * key files, but this is only within Evolution. Some of the new
- * GObject property names differ from the old CamelURL parameter
- * names. This routine renames the CamelURL parameter names to
- * the GObject property names for all accounts, both the source
- * and tranport URLs. */
-
- account_list = e_get_account_list ();
- iterator = e_list_get_iterator (E_LIST (account_list));
-
- while (e_iterator_is_valid (iterator)) {
- EAccount *account;
- CamelURL *url = NULL;
-
- /* XXX EIterator misuses const. */
- account = (EAccount *) e_iterator_get (iterator);
-
- if (account->source->url != NULL)
- url = camel_url_new (account->source->url, NULL);
-
- if (url != NULL) {
- em_rename_camel_url_params (url);
- g_free (account->source->url);
- account->source->url = camel_url_to_string (url, 0);
- camel_url_free (url);
- }
-
- url = NULL;
-
- if (account->transport->url != NULL)
- url = camel_url_new (account->transport->url, NULL);
-
- if (url != NULL) {
- em_rename_camel_url_params (url);
- g_free (account->transport->url);
- account->transport->url = camel_url_to_string (url, 0);
- camel_url_free (url);
- }
-
- e_iterator_next (iterator);
- }
-
- g_object_unref (iterator);
- e_account_list_save (account_list);
-}
-
-static gboolean
migrate_local_store (EShellBackend *shell_backend)
{
EMMigrateSession *session;
@@ -1101,8 +691,6 @@ migrate_local_store (EShellBackend *shell_backend)
camel_session_set_online (CAMEL_SESSION (session), FALSE);
migrate_mbox_to_maildir (shell_backend, session);
- create_mbox_account (shell_backend, session);
- change_sent_and_drafts_local_folders (shell_backend);
g_object_unref (session);
@@ -1279,10 +867,6 @@ e_mail_migrate (EShellBackend *shell_backend,
return emm_setup_initial (data_dir);
#ifndef G_OS_WIN32
- if (major < 2 || (major == 2 && minor < 12)) {
- em_update_accounts_2_11 ();
- }
-
if (major < 2 || (major == 2 && minor < 22))
em_update_message_notify_settings_2_21 ();
@@ -1299,10 +883,6 @@ e_mail_migrate (EShellBackend *shell_backend,
em_ensure_proxy_ignore_hosts_being_list ();
}
- /* Rename account URL parameters to
- * match CamelSettings property names. */
- em_rename_account_params ();
-
if (!migrate_local_store (shell_backend))
return FALSE;
diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c
index bd76dd967c..29910d8c4a 100644
--- a/mail/e-mail-paned-view.c
+++ b/mail/e-mail-paned-view.c
@@ -809,6 +809,7 @@ mail_paned_view_update_view_instance (EMailView *view)
EShellWindow *shell_window;
EShellViewClass *shell_view_class;
EShellSettings *shell_settings;
+ ESourceRegistry *registry;
GalViewCollection *view_collection;
GalViewInstance *view_instance;
CamelFolder *folder;
@@ -826,6 +827,7 @@ mail_paned_view_update_view_instance (EMailView *view)
shell_window = e_shell_view_get_shell_window (shell_view);
shell = e_shell_window_get_shell (shell_window);
+ registry = e_shell_get_registry (shell);
shell_settings = e_shell_get_shell_settings (shell);
reader = E_MAIL_READER (view);
@@ -844,9 +846,9 @@ mail_paned_view_update_view_instance (EMailView *view)
e_filename_make_safe (view_id);
outgoing_folder =
- em_utils_folder_is_drafts (folder) ||
- em_utils_folder_is_outbox (folder) ||
- em_utils_folder_is_sent (folder);
+ em_utils_folder_is_drafts (registry, folder) ||
+ em_utils_folder_is_outbox (registry, folder) ||
+ em_utils_folder_is_sent (registry, folder);
if (e_shell_settings_get_boolean (shell_settings, "mail-global-view-setting"))
view_instance = e_shell_view_new_view_instance (
diff --git a/mail/e-mail-reader-utils.c b/mail/e-mail-reader-utils.c
index 6d3f6aafc5..2240523beb 100644
--- a/mail/e-mail-reader-utils.c
+++ b/mail/e-mail-reader-utils.c
@@ -30,6 +30,7 @@
#include <glib/gi18n.h>
#include <libxml/tree.h>
#include <gtkhtml/gtkhtml.h>
+#include <gconf/gconf-client.h>
#include <camel/camel.h>
#include "libevolution-utils/e-alert-dialog.h"
@@ -358,7 +359,9 @@ copy_tree_state (EMailReader *src_reader,
guint
e_mail_reader_open_selected (EMailReader *reader)
{
+ EShell *shell;
EMailBackend *backend;
+ ESourceRegistry *registry;
CamelFolder *folder;
GtkWindow *window;
GPtrArray *views;
@@ -368,6 +371,9 @@ e_mail_reader_open_selected (EMailReader *reader)
g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
backend = e_mail_reader_get_backend (reader);
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+ registry = e_shell_get_registry (shell);
+
folder = e_mail_reader_get_folder (reader);
uids = e_mail_reader_get_selected_uids (reader);
window = e_mail_reader_get_window (reader);
@@ -377,9 +383,9 @@ e_mail_reader_open_selected (EMailReader *reader)
return 0;
}
- if (em_utils_folder_is_drafts (folder) ||
- em_utils_folder_is_outbox (folder) ||
- em_utils_folder_is_templates (folder)) {
+ if (em_utils_folder_is_drafts (registry, folder) ||
+ em_utils_folder_is_outbox (registry, folder) ||
+ em_utils_folder_is_templates (registry, folder)) {
em_utils_edit_messages (reader, folder, uids, TRUE);
return uids->len;
}
@@ -406,8 +412,8 @@ e_mail_reader_open_selected (EMailReader *reader)
CAMEL_VEE_FOLDER (folder),
(CamelVeeMessageInfo *) info, &real_uid);
- if (em_utils_folder_is_drafts (real_folder) ||
- em_utils_folder_is_outbox (real_folder)) {
+ if (em_utils_folder_is_drafts (registry, real_folder) ||
+ em_utils_folder_is_outbox (registry, real_folder)) {
GPtrArray *edits;
edits = g_ptr_array_new ();
@@ -1166,9 +1172,12 @@ void
e_mail_reader_create_filter_from_selected (EMailReader *reader,
gint filter_type)
{
+ EShell *shell;
EActivity *activity;
+ EMailBackend *backend;
AsyncContext *context;
GCancellable *cancellable;
+ ESourceRegistry *registry;
CamelFolder *folder;
GPtrArray *uids;
const gchar *filter_source;
@@ -1176,12 +1185,16 @@ e_mail_reader_create_filter_from_selected (EMailReader *reader,
g_return_if_fail (E_IS_MAIL_READER (reader));
+ backend = e_mail_reader_get_backend (reader);
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+ registry = e_shell_get_registry (shell);
+
folder = e_mail_reader_get_folder (reader);
g_return_if_fail (CAMEL_IS_FOLDER (folder));
- if (em_utils_folder_is_sent (folder))
+ if (em_utils_folder_is_sent (registry, folder))
filter_source = E_FILTER_SOURCE_OUTGOING;
- else if (em_utils_folder_is_outbox (folder))
+ else if (em_utils_folder_is_outbox (registry, folder))
filter_source = E_FILTER_SOURCE_OUTGOING;
else
filter_source = E_FILTER_SOURCE_INCOMING;
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 7fb29acf40..1bd80b20d5 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -28,6 +28,8 @@
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
+#include <libedataserver/e-source-mail-account.h>
+
#ifdef HAVE_XFREE
#include <X11/XF86keysym.h>
#endif
@@ -39,7 +41,6 @@
#include "widgets/misc/e-popup-action.h"
#include "widgets/misc/e-menu-tool-action.h"
-#include "libemail-utils/e-account-utils.h"
#include "libemail-utils/mail-mt.h"
#include "libemail-engine/mail-ops.h"
@@ -892,6 +893,9 @@ static void
action_mail_message_edit_cb (GtkAction *action,
EMailReader *reader)
{
+ EShell *shell;
+ EMailBackend *backend;
+ ESourceRegistry *registry;
CamelFolder *folder;
GPtrArray *uids;
gboolean replace;
@@ -900,11 +904,15 @@ action_mail_message_edit_cb (GtkAction *action,
uids = e_mail_reader_get_selected_uids (reader);
g_return_if_fail (uids != NULL);
+ backend = e_mail_reader_get_backend (reader);
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+ registry = e_shell_get_registry (shell);
+
/* XXX Either e_mail_reader_get_selected_uids()
* or MessageList should do this itself. */
g_ptr_array_set_free_func (uids, (GDestroyNotify) g_free);
- replace = em_utils_folder_is_drafts (folder);
+ replace = em_utils_folder_is_drafts (registry, folder);
em_utils_edit_messages (reader, folder, uids, replace);
g_ptr_array_unref (uids);
@@ -3027,6 +3035,7 @@ mail_reader_set_folder (EMailReader *reader,
EMailReaderPrivate *priv;
EMailDisplay *display;
CamelFolder *previous_folder;
+ ESourceRegistry *registry;
GtkWidget *message_list;
EMailBackend *backend;
EShell *shell;
@@ -3040,7 +3049,9 @@ mail_reader_set_folder (EMailReader *reader,
previous_folder = e_mail_reader_get_folder (reader);
+ backend = e_mail_reader_get_backend (reader);
shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+ registry = e_shell_get_registry (shell);
/* Only synchronize the real folder if we're online. */
if (previous_folder != NULL && (CAMEL_IS_VEE_FOLDER (previous_folder) || e_shell_get_online (shell)))
@@ -3051,9 +3062,9 @@ mail_reader_set_folder (EMailReader *reader,
return;
outgoing = folder != NULL && (
- em_utils_folder_is_drafts (folder) ||
- em_utils_folder_is_outbox (folder) ||
- em_utils_folder_is_sent (folder));
+ em_utils_folder_is_drafts (registry, folder) ||
+ em_utils_folder_is_outbox (registry, folder) ||
+ em_utils_folder_is_sent (registry, folder));
e_web_view_clear (E_WEB_VIEW (display));
@@ -4171,9 +4182,14 @@ e_mail_reader_changed (EMailReader *reader)
guint32
e_mail_reader_check_state (EMailReader *reader)
{
+ EShell *shell;
GPtrArray *uids;
CamelFolder *folder;
CamelStore *store = NULL;
+ EMailBackend *backend;
+ ESourceRegistry *registry;
+ GList *list, *iter;
+ const gchar *extension_name;
const gchar *tag;
gboolean can_clear_flags = FALSE;
gboolean can_flag_completed = FALSE;
@@ -4187,6 +4203,7 @@ e_mail_reader_check_state (EMailReader *reader)
gboolean has_undeleted = FALSE;
gboolean has_unimportant = FALSE;
gboolean has_unread = FALSE;
+ gboolean have_enabled_account = FALSE;
gboolean drafts_or_outbox = FALSE;
gboolean store_supports_vjunk = FALSE;
gboolean is_mailing_list;
@@ -4196,6 +4213,10 @@ e_mail_reader_check_state (EMailReader *reader)
g_return_val_if_fail (E_IS_MAIL_READER (reader), 0);
+ backend = e_mail_reader_get_backend (reader);
+ shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
+ registry = e_shell_get_registry (shell);
+
folder = e_mail_reader_get_folder (reader);
uids = e_mail_reader_get_selected_uids (reader);
@@ -4205,8 +4226,8 @@ e_mail_reader_check_state (EMailReader *reader)
is_junk_folder =
(folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
drafts_or_outbox =
- em_utils_folder_is_drafts (folder) ||
- em_utils_folder_is_outbox (folder);
+ em_utils_folder_is_drafts (registry, folder) ||
+ em_utils_folder_is_outbox (registry, folder);
}
/* Initialize this flag based on whether there are any
@@ -4291,7 +4312,21 @@ e_mail_reader_check_state (EMailReader *reader)
camel_folder_free_message_info (folder, info);
}
- if (e_get_any_enabled_account () != NULL)
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ ESource *source = E_SOURCE (iter->data);
+
+ if (e_source_get_enabled (source)) {
+ have_enabled_account = TRUE;
+ break;
+ }
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ if (have_enabled_account)
state |= E_MAIL_READER_HAVE_ENABLED_ACCOUNT;
if (uids->len == 1)
state |= E_MAIL_READER_SELECTION_SINGLE;
diff --git a/mail/e-mail-ui-session.c b/mail/e-mail-ui-session.c
index 1d3858d166..f5f5bddf3b 100644
--- a/mail/e-mail-ui-session.c
+++ b/mail/e-mail-ui-session.c
@@ -44,13 +44,13 @@
#include <libedataserver/e-flag.h>
#include <libedataserver/e-proxy.h>
+#include <libedataserver/e-source-mail-account.h>
#include <libebackend/e-extensible.h>
#include <libedataserverui/e-passwords.h>
#include "e-mail-account-store.h"
#include "e-util/e-util.h"
-#include "libemail-utils/e-account-utils.h"
#include "libevolution-utils/e-alert-dialog.h"
#include "e-util/e-util-private.h"
@@ -82,11 +82,11 @@ typedef struct _SourceContext SourceContext;
struct _EMailUISessionPrivate {
FILE *filter_logfile;
+ ESourceRegistry *registry;
EMailAccountStore *account_store;
EMailLabelListStore *label_store;
- EAccountList *account_list;
- gulong account_changed_handler_id;
+ gulong source_changed_handler_id;
};
enum {
@@ -475,62 +475,28 @@ source_context_free (SourceContext *context)
}
static void
-mail_ui_session_dispose (GObject *object)
-{
- EMailUISessionPrivate *priv;
-
- priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
-
- if (priv->account_store != NULL) {
- e_mail_account_store_clear (priv->account_store);
- g_object_unref (priv->account_store);
- priv->account_store = NULL;
- }
-
- if (priv->label_store != NULL) {
- g_object_unref (priv->label_store);
- priv->label_store = NULL;
- }
-
- if (priv->account_list != NULL) {
- g_signal_handler_disconnect (
- priv->account_list,
- priv->account_changed_handler_id);
- g_object_unref (priv->account_list);
- priv->account_list = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_mail_ui_session_parent_class)->dispose (object);
-}
-
-static void
-mail_ui_session_account_changed_cb (EAccountList *account_list,
- EAccount *account,
- EMailSession *session)
+mail_ui_session_source_changed_cb (ESourceRegistry *registry,
+ ESource *source,
+ EMailSession *session)
{
EMFolderTreeModel *folder_tree_model;
CamelService *service;
+ const gchar *extension_name;
+ const gchar *uid;
- service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
+ uid = e_source_get_uid (source);
- if (!CAMEL_IS_STORE (service))
+ /* We're only interested in mail account data sources. */
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ if (!e_source_has_extension (source, extension_name))
return;
- /* Update the display name of the corresponding CamelStore.
- * EMailAccountStore listens for "notify" signals from each
- * service so it will detect this and update the model.
- *
- * XXX If EAccount defined GObject properties we could just
- * bind EAccount:name to CamelService:display-name and
- * be done with it. Oh well.
- */
-
- camel_service_set_display_name (service, account->name);
+ /* There should be a CamelStore with the same UID. */
+ service = camel_session_get_service (CAMEL_SESSION (session), uid);
+ g_return_if_fail (CAMEL_IS_STORE (service));
/* Remove the store from the folder tree model and, if the
- * account is still enabled, re-add it. Easier than trying
+ * source is still enabled, re-add it. Easier than trying
* to update the model with the store in place.
*
* em_folder_tree_model_add_store() already knows which types
@@ -542,34 +508,76 @@ mail_ui_session_account_changed_cb (EAccountList *account_list,
em_folder_tree_model_remove_store (
folder_tree_model, CAMEL_STORE (service));
- if (account->enabled)
+ if (e_source_get_enabled (source))
em_folder_tree_model_add_store (
folder_tree_model, CAMEL_STORE (service));
}
static gboolean
-mail_ui_session_initialize_stores_idle (gpointer user_data)
+mail_ui_session_add_service_cb (SourceContext *context)
{
- EMailUISession *session = user_data;
- EMailAccountStore *account_store;
- EAccount *account;
+ EMailAccountStore *store;
+
+ /* The CamelService should be fully initialized by now. */
+ store = e_mail_ui_session_get_account_store (context->session);
+ e_mail_account_store_add_service (store, context->service);
+
+ return FALSE;
+}
+
+static void
+mail_ui_session_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_ACCOUNT_STORE:
+ g_value_set_object (
+ value,
+ e_mail_ui_session_get_account_store (
+ E_MAIL_UI_SESSION (object)));
+ return;
+
+ case PROP_LABEL_STORE:
+ g_value_set_object (
+ value,
+ e_mail_ui_session_get_label_store (
+ E_MAIL_UI_SESSION (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- g_return_val_if_fail (session != NULL, FALSE);
+static void
+mail_ui_session_dispose (GObject *object)
+{
+ EMailUISessionPrivate *priv;
- account_store = e_mail_ui_session_get_account_store (session);
+ priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
- /* Initialize which account is default. */
- account = e_get_default_account ();
- if (account != NULL) {
- CamelService *service;
+ if (priv->registry != NULL) {
+ g_signal_handler_disconnect (
+ priv->registry,
+ priv->source_changed_handler_id);
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
- service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
- e_mail_account_store_set_default_service (
- account_store, service);
+ if (priv->account_store != NULL) {
+ e_mail_account_store_clear (priv->account_store);
+ g_object_unref (priv->account_store);
+ priv->account_store = NULL;
}
- return FALSE;
+ if (priv->label_store != NULL) {
+ g_object_unref (priv->label_store);
+ priv->label_store = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_mail_ui_session_parent_class)->dispose (object);
}
static void
@@ -577,19 +585,19 @@ mail_ui_session_constructed (GObject *object)
{
EMailUISessionPrivate *priv;
EMFolderTreeModel *folder_tree_model;
+ ESourceRegistry *registry;
EMailSession *session;
- EMailUISession *uisession;
- EAccountList *account_list;
gulong handler_id;
session = E_MAIL_SESSION (object);
- uisession = E_MAIL_UI_SESSION (object);
- uisession->priv = priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
+ priv = E_MAIL_UI_SESSION_GET_PRIVATE (object);
priv->account_store = e_mail_account_store_new (session);
- account_list = e_get_account_list ();
- uisession->priv->account_list = g_object_ref (account_list);
+ /* Keep our own reference to the ESourceRegistry so we
+ * can easily disconnect signal handlers in dispose(). */
+ registry = e_mail_session_get_registry (session);
+ priv->registry = g_object_ref (registry);
/* XXX Make sure the folder tree model is created before we
* add built-in CamelStores so it gets signals from the
@@ -601,19 +609,62 @@ mail_ui_session_constructed (GObject *object)
* FIXME EMailSession should just own the default instance.
*/
folder_tree_model = em_folder_tree_model_get_default ();
+ em_folder_tree_model_set_session (folder_tree_model, session);
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (e_mail_ui_session_parent_class)->constructed (object);
- em_folder_tree_model_set_session (folder_tree_model, session);
-
- g_idle_add (mail_ui_session_initialize_stores_idle, object);
+ /* Listen for registry changes. */
handler_id = g_signal_connect (
- account_list, "account-changed",
- G_CALLBACK (mail_ui_session_account_changed_cb), session);
- priv->account_changed_handler_id = handler_id;
+ registry, "source-changed",
+ G_CALLBACK (mail_ui_session_source_changed_cb), session);
+ priv->source_changed_handler_id = handler_id;
+}
+static CamelService *
+mail_ui_session_add_service (CamelSession *session,
+ const gchar *uid,
+ const gchar *protocol,
+ CamelProviderType type,
+ GError **error)
+{
+ CamelService *service;
+
+ /* Chain up to parent's constructed() method. */
+ service = CAMEL_SESSION_CLASS (e_mail_ui_session_parent_class)->
+ add_service (session, uid, protocol, type, error);
+
+ /* Inform the EMailAccountStore of the new CamelService
+ * from an idle callback so the service has a chance to
+ * fully initialize first. */
+ if (CAMEL_IS_STORE (service)) {
+ SourceContext *context;
+
+ context = g_slice_new0 (SourceContext);
+ context->session = g_object_ref (session);
+ context->service = g_object_ref (service);
+
+ g_idle_add_full (
+ G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc) mail_ui_session_add_service_cb,
+ context, (GDestroyNotify) source_context_free);
+ }
+
+ return service;
+}
+
+static void
+mail_ui_session_remove_service (CamelSession *session,
+ CamelService *service)
+{
+ EMailAccountStore *store;
+ EMailUISession *ui_session;
+
+ /* Passing a NULL parent window skips confirmation prompts. */
+ ui_session = E_MAIL_UI_SESSION (session);
+ store = e_mail_ui_session_get_account_store (ui_session);
+ e_mail_account_store_remove_service (store, NULL, service);
}
static gint
@@ -659,8 +710,8 @@ mail_ui_session_alert_user (CamelSession *session,
static CamelFilterDriver *
mail_ui_session_get_filter_driver (CamelSession *session,
- const gchar *type,
- GError **error)
+ const gchar *type,
+ GError **error)
{
return (CamelFilterDriver *) mail_call_main (
MAIL_CALL_p_ppp, (MailMainFunc) main_get_filter_driver,
@@ -668,80 +719,14 @@ mail_ui_session_get_filter_driver (CamelSession *session,
}
static void
-mail_ui_session_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+mail_ui_session_refresh_service (EMailSession *session,
+ CamelService *service)
{
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
+ g_debug ("*** Refreshing %s ***",
+ camel_service_get_display_name (service));
-static void
-mail_ui_session_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_ACCOUNT_STORE:
- g_value_set_object (
- value,
- e_mail_ui_session_get_account_store (
- E_MAIL_UI_SESSION (object)));
- return;
-
- case PROP_LABEL_STORE:
- g_value_set_object (
- value,
- e_mail_ui_session_get_label_store (
- E_MAIL_UI_SESSION (object)));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static gboolean
-mail_ui_session_add_service_cb (SourceContext *context)
-{
- EMailAccountStore *store;
-
- store = e_mail_ui_session_get_account_store (context->session);
- e_mail_account_store_add_service (store, context->service);
-
- return FALSE;
-}
-
-static CamelService *
-mail_ui_session_add_service (CamelSession *session,
- const gchar *uid,
- const gchar *protocol,
- CamelProviderType type,
- GError **error)
-{
- CamelService *service;
-
- /* Chain up to parent's constructed() method. */
- service = CAMEL_SESSION_CLASS (e_mail_ui_session_parent_class)->
- add_service (session, uid, protocol, type, error);
-
- /* Inform the EMailAccountStore of the new CamelService
- * from an idle callback so the service has a chance to
- * fully initialize first. */
- if (CAMEL_IS_STORE (service)) {
- SourceContext *context;
-
- context = g_slice_new0 (SourceContext);
- context->session = g_object_ref (session);
- context->service = g_object_ref (service);
-
- g_idle_add_full (
- G_PRIORITY_DEFAULT_IDLE,
- (GSourceFunc) mail_ui_session_add_service_cb,
- context, (GDestroyNotify) source_context_free);
- }
-
- return service;
+ if (camel_session_get_online (CAMEL_SESSION (session)))
+ mail_receive_service (service);
}
static EMVFolderContext *
@@ -755,23 +740,24 @@ e_mail_ui_session_class_init (EMailUISessionClass *class)
{
GObjectClass *object_class;
CamelSessionClass *session_class;
- EMailSessionClass *emailsession_class;
+ EMailSessionClass *mail_session_class;
g_type_class_add_private (class, sizeof (EMailUISessionPrivate));
object_class = G_OBJECT_CLASS (class);
- object_class->set_property = mail_ui_session_set_property;
object_class->get_property = mail_ui_session_get_property;
object_class->dispose = mail_ui_session_dispose;
object_class->constructed = mail_ui_session_constructed;
session_class = CAMEL_SESSION_CLASS (class);
+ session_class->add_service = mail_ui_session_add_service;
+ session_class->remove_service = mail_ui_session_remove_service;
session_class->alert_user = mail_ui_session_alert_user;
session_class->get_filter_driver = mail_ui_session_get_filter_driver;
- session_class->add_service = mail_ui_session_add_service;
- emailsession_class = E_MAIL_SESSION_CLASS (class);
- emailsession_class->create_vfolder_context = mail_ui_session_create_vfolder_context;
+ mail_session_class = E_MAIL_SESSION_CLASS (class);
+ mail_session_class->create_vfolder_context = mail_ui_session_create_vfolder_context;
+ mail_session_class->refresh_service = mail_ui_session_refresh_service;
g_object_class_install_property (
object_class,
@@ -803,16 +789,19 @@ e_mail_ui_session_init (EMailUISession *session)
}
EMailSession *
-e_mail_ui_session_new (void)
+e_mail_ui_session_new (ESourceRegistry *registry)
{
const gchar *user_data_dir;
const gchar *user_cache_dir;
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
user_data_dir = mail_session_get_data_dir ();
user_cache_dir = mail_session_get_cache_dir ();
return g_object_new (
E_TYPE_MAIL_UI_SESSION,
+ "registry", registry,
"user-data-dir", user_data_dir,
"user-cache-dir", user_cache_dir,
NULL);
diff --git a/mail/e-mail-ui-session.h b/mail/e-mail-ui-session.h
index 7efb472590..ebab600cdb 100644
--- a/mail/e-mail-ui-session.h
+++ b/mail/e-mail-ui-session.h
@@ -76,7 +76,7 @@ struct _EMailUISessionClass {
};
GType e_mail_ui_session_get_type (void);
-EMailSession * e_mail_ui_session_new (void);
+EMailSession * e_mail_ui_session_new (ESourceRegistry *registry);
EMailAccountStore *
e_mail_ui_session_get_account_store
(EMailUISession *session);
diff --git a/mail/e-mail.h b/mail/e-mail.h
index 3b0d02dcab..694b8e384b 100644
--- a/mail/e-mail.h
+++ b/mail/e-mail.h
@@ -20,6 +20,7 @@
#define E_MAIL_H
#include <mail/e-mail-attachment-bar.h>
+#include <mail/e-mail-authenticator.h>
#include <mail/e-mail-backend.h>
#include <mail/e-mail-browser.h>
#include <mail/e-mail-display.h>
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
deleted file mode 100644
index 8919c0cef4..0000000000
--- a/mail/em-account-editor.c
+++ /dev/null
@@ -1,5834 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Dan Winship <danw@ximian.com>
- * Jeffrey Stedfast <fejj@ximian.com>
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/*
- * work before merge can occur:
- *
- * verify behaviour.
- * work out what to do with the startup assistant.
- *
- * also need to work out:
- * how to remove unecessary items from a service url once
- * configured (removing settings from other types).
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-
-#include <string.h>
-#include <stdarg.h>
-
-#include <libedataserverui/e-client-utils.h>
-#include <libedataserverui/e-passwords.h>
-
-#include <shell/e-shell.h>
-
-#include <e-util/e-util.h>
-#include <libevolution-utils/e-alert-dialog.h>
-#include <e-util/e-dialog-utils.h>
-#include <e-util/e-util-private.h>
-
-#include <libemail-utils/e-account-utils.h>
-#include <libemail-utils/e-signature-list.h>
-#include <libemail-utils/e-signature-utils.h>
-#include <libemail-utils/mail-mt.h>
-
-#include <libemail-engine/e-mail-folder-utils.h>
-#include <libemail-engine/mail-ops.h>
-
-#include <widgets/misc/e-auth-combo-box.h>
-#include <widgets/misc/e-signature-editor.h>
-#include <widgets/misc/e-port-entry.h>
-
-#include "e-mail-account-store.h"
-#include "e-mail-backend.h"
-#include "e-mail-junk-options.h"
-#include "e-mail-ui-session.h"
-#include "em-account-editor.h"
-#include "em-config.h"
-#include "em-folder-selection-button.h"
-#include "em-utils.h"
-#include "mail-guess-servers.h"
-#include "mail-send-recv.h"
-
-#if defined (HAVE_NSS) && defined (ENABLE_SMIME)
-#include <smime/gui/e-cert-selector.h>
-#endif
-
-#define EM_ACCOUNT_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorPrivate))
-
-/* Option widgets whose sensitivity depends on another widget, such
- * as a checkbox being active, are indented to the right slightly for
- * better visual clarity. This specifies how far to the right. */
-#define INDENT_MARGIN 24
-
-#define EM_ACCOUNT_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorPrivate))
-
-#define d(x)
-
-/* econfig item for the extra config hings */
-struct _receive_options_item {
- EMConfigItem item;
-
- /* Only CAMEL_PROVIDER_CONF_ENTRYs GtkEntrys are stored here.
- * The auto-detect camel provider code will probably be removed */
- GHashTable *extra_table;
-};
-
-typedef struct _EMAccountEditorService {
- EMAccountEditor *emae; /* parent pointer, for callbacks */
-
- /* NOTE: keep all widgets together, first frame last check_dialog */
- GtkWidget *frame;
- GtkWidget *container;
-
- GtkComboBox *providers;
-
- GtkLabel *description;
- GtkLabel *hostlabel;
- GtkEntry *hostname;
- GtkLabel *portlabel;
- EPortEntry *port;
- GtkLabel *userlabel;
- GtkEntry *username;
- GtkLabel *pathlabel;
- GtkWidget *pathentry;
-
- GtkWidget *ssl_frame;
- GtkComboBox *use_ssl;
- GtkWidget *ssl_hbox;
- GtkWidget *no_ssl;
-
- GtkWidget *auth_frame;
- GtkComboBox *authtype;
-
- GtkWidget *authitem;
- GtkToggleButton *remember;
- GtkButton *check_supported;
- GtkToggleButton *needs_auth;
- gboolean requires_auth;
-
- GCancellable *checking;
- GtkWidget *check_dialog;
-
- const gchar *protocol;
- CamelProviderType type;
- CamelSettings *settings;
-
- gboolean visible_auth;
- gboolean visible_host;
- gboolean visible_path;
- gboolean visible_port;
- gboolean visible_user;
-} EMAccountEditorService;
-
-struct _EMAccountEditorPrivate {
-
- EMailBackend *backend;
- EAccount *modified_account;
- EAccount *original_account;
- gboolean new_account;
-
- struct _EMConfig *config;
- GList *providers;
-
- /* signatures */
- GtkComboBox *signatures_dropdown;
- guint sig_added_id;
- guint sig_removed_id;
- guint sig_changed_id;
- const gchar *sig_uid;
-
- /* incoming mail */
- EMAccountEditorService source;
-
- /* extra incoming config */
- CamelProvider *extra_provider;
- GSList *extra_items; /* this is freed by the econfig automatically */
-
- /* outgoing mail */
- EMAccountEditorService transport;
-
- /* account management */
- GtkEntry *identity_entries[5];
- GtkToggleButton *default_account;
- GtkWidget *management_frame;
-
- /* special folders */
- GtkButton *drafts_folder_button;
- GtkButton *sent_folder_button;
- GtkToggleButton *trash_folder_check;
- GtkButton *trash_folder_button;
- GtkToggleButton *junk_folder_check;
- GtkButton *junk_folder_button;
- GtkButton *restore_folders_button;
-
- /* Security */
- GtkEntry *pgp_key;
- GtkToggleButton *pgp_encrypt_to_self;
- GtkToggleButton *pgp_always_sign;
- GtkToggleButton *pgp_no_imip_sign;
- GtkToggleButton *pgp_always_trust;
-
- GtkToggleButton *smime_sign_default;
- GtkEntry *smime_sign_key;
- GtkButton *smime_sign_key_select;
- GtkButton *smime_sign_key_clear;
- GtkButton *smime_sign_select;
- GtkToggleButton *smime_encrypt_default;
- GtkToggleButton *smime_encrypt_to_self;
- GtkEntry *smime_encrypt_key;
- GtkButton *smime_encrypt_key_select;
- GtkButton *smime_encrypt_key_clear;
-
- /* Review */
- GtkLabel *review_name;
- GtkLabel *review_email;
- GtkLabel *send_name;
- GtkLabel *send_stype;
- GtkLabel *send_saddress;
- GtkLabel *send_encryption;
- GtkLabel *receive_name;
- GtkLabel *receive_stype;
- GtkLabel *receive_saddress;
- GtkLabel *receive_encryption;
- GtkWidget *review_box;
-
- /* google and yahoo specific data*/
- gboolean is_gmail;
- gboolean is_yahoo;
-
- GtkWidget *calendar;
- GtkWidget *tasks;
- GtkWidget *gcontacts;
- GtkWidget *info_label;
-
- GtkWidget *account_label;
- GtkWidget *gmail_link;
- GtkWidget *yahoo_cal_box;
- GtkWidget *yahoo_cal_entry;
-
- /* for e-config callbacks, each page sets up its widgets, then they are dealed out by the get_widget callback in order*/
- GHashTable *widgets;
-
- /* for assistant page preparation */
- guint identity_set : 1;
- guint receive_set : 1;
- guint receive_opt_set : 1;
- guint send_set : 1;
- guint review_set : 1;
-
- ServerData *selected_server;
-};
-
-enum {
- PROP_0,
- PROP_BACKEND,
- PROP_MODIFIED_ACCOUNT,
- PROP_ORIGINAL_ACCOUNT,
- PROP_STORE_PROVIDER,
- PROP_STORE_REQUIRES_AUTH,
- PROP_STORE_SETTINGS,
- PROP_STORE_VISIBLE_AUTH,
- PROP_STORE_VISIBLE_HOST,
- PROP_STORE_VISIBLE_PATH,
- PROP_STORE_VISIBLE_PORT,
- PROP_STORE_VISIBLE_USER,
- PROP_TRANSPORT_PROVIDER,
- PROP_TRANSPORT_REQUIRES_AUTH,
- PROP_TRANSPORT_SETTINGS,
- PROP_TRANSPORT_VISIBLE_AUTH,
- PROP_TRANSPORT_VISIBLE_HOST,
- PROP_TRANSPORT_VISIBLE_PATH,
- PROP_TRANSPORT_VISIBLE_PORT,
- PROP_TRANSPORT_VISIBLE_USER
-};
-
-static void em_account_editor_construct (EMAccountEditor *emae, EMAccountEditorType type, const gchar *id);
-static void emae_account_folder_changed (EMFolderSelectionButton *folder, EMAccountEditor *emae);
-
-G_DEFINE_TYPE (EMAccountEditor, em_account_editor, G_TYPE_OBJECT)
-
-static void
-emae_config_gone_cb (gpointer pemae,
- GObject *pconfig)
-{
- EMAccountEditor *emae = pemae;
- struct _EMConfig *config = (struct _EMConfig *) pconfig;
-
- if (!emae)
- return;
-
- if (emae->config == config)
- emae->config = NULL;
-
- if (emae->priv && emae->priv->config == config)
- emae->priv->config = NULL;
-}
-
-static void
-emae_config_target_changed_cb (EMAccountEditor *emae)
-{
- e_config_target_changed (
- (EConfig *) emae->config,
- E_CONFIG_TARGET_CHANGED_STATE);
-}
-
-static gint
-emae_provider_compare (const CamelProvider *p1,
- const CamelProvider *p2)
-{
- /* The "none" provider comes first. */
- if (g_strcmp0 (p1->protocol, "none") == 0)
- return -1;
- if (g_strcmp0 (p2->protocol, "none") == 0)
- return 1;
-
- /* Then sort remote providers before local providers. */
- if (p1->flags & CAMEL_PROVIDER_IS_REMOTE) {
- if (p2->flags & CAMEL_PROVIDER_IS_REMOTE)
- return 0;
- return -1;
- } else {
- if (p2->flags & CAMEL_PROVIDER_IS_REMOTE)
- return 1;
- return 0;
- }
-}
-
-static GList *
-emae_list_providers (void)
-{
- GList *list, *link;
- GQueue trash = G_QUEUE_INIT;
-
- list = camel_provider_list (TRUE);
- list = g_list_sort (list, (GCompareFunc) emae_provider_compare);
-
- /* Keep only providers with a "mail" or "news" domain. */
-
- for (link = list; link != NULL; link = g_list_next (link)) {
- CamelProvider *provider = link->data;
- gboolean mail_or_news_domain;
-
- mail_or_news_domain =
- (g_strcmp0 (provider->domain, "mail") == 0) ||
- (g_strcmp0 (provider->domain, "news") == 0);
-
- if (mail_or_news_domain)
- continue;
-
- g_queue_push_tail (&trash, link);
- }
-
- while ((link = g_queue_pop_head (&trash)) != NULL)
- list = g_list_remove_link (list, link);
-
- return list;
-}
-
-static void
-emae_set_original_account (EMAccountEditor *emae,
- EAccount *original_account)
-{
- EAccount *modified_account;
-
- g_return_if_fail (emae->priv->original_account == NULL);
-
- /* Editing an existing account. */
- if (original_account != NULL) {
- gchar *xml;
-
- xml = e_account_to_xml (original_account);
- modified_account = e_account_new_from_xml (xml);
- g_free (xml);
-
- g_object_ref (original_account);
- if (emae->type != EMAE_PAGES)
- emae->do_signature = TRUE;
-
- /* thus the emae_setup_service() will pick protocols from the account */
- emae->priv->source.protocol = NULL;
- emae->priv->transport.protocol = NULL;
-
- /* Creating a new account. */
- } else {
- modified_account = e_account_new ();
- modified_account->enabled = TRUE;
- emae->priv->new_account = TRUE;
- }
-
- emae->priv->original_account = original_account;
- emae->priv->modified_account = modified_account;
-}
-
-static void
-emae_set_backend (EMAccountEditor *emae,
- EMailBackend *backend)
-{
- g_return_if_fail (E_IS_MAIL_BACKEND (backend));
- g_return_if_fail (emae->priv->backend == NULL);
-
- emae->priv->backend = g_object_ref (backend);
-}
-
-static CamelProvider *
-emae_get_store_provider (EMAccountEditor *emae)
-{
- CamelProvider *provider = NULL;
- const gchar *protocol;
-
- protocol = emae->priv->source.protocol;
-
- if (protocol != NULL)
- provider = camel_provider_get (protocol, NULL);
-
- return provider;
-}
-
-static gboolean
-emae_get_store_requires_auth (EMAccountEditor *emae)
-{
- return emae->priv->source.requires_auth;
-}
-
-static void
-emae_set_store_requires_auth (EMAccountEditor *emae,
- gboolean requires_auth)
-{
- emae->priv->source.requires_auth = requires_auth;
-
- g_object_notify (G_OBJECT (emae), "store-requires-auth");
-}
-
-static CamelSettings *
-emae_get_store_settings (EMAccountEditor *emae)
-{
- return emae->priv->source.settings;
-}
-
-static void
-emae_set_store_settings (EMAccountEditor *emae,
- CamelSettings *settings)
-{
- if (settings != NULL)
- g_object_ref (settings);
-
- if (emae->priv->source.settings != NULL) {
- g_signal_handlers_disconnect_by_func (
- emae->priv->source.settings,
- emae_config_target_changed_cb, emae);
- g_object_unref (emae->priv->source.settings);
- }
-
- emae->priv->source.settings = settings;
-
- g_object_notify (G_OBJECT (emae), "store-settings");
-}
-
-static gboolean
-emae_get_store_visible_auth (EMAccountEditor *emae)
-{
- return emae->priv->source.visible_auth;
-}
-
-static void
-emae_set_store_visible_auth (EMAccountEditor *emae,
- gboolean visible_auth)
-{
- emae->priv->source.visible_auth = visible_auth;
-
- g_object_notify (G_OBJECT (emae), "store-visible-auth");
-}
-
-static gboolean
-emae_get_store_visible_host (EMAccountEditor *emae)
-{
- return emae->priv->source.visible_host;
-}
-
-static void
-emae_set_store_visible_host (EMAccountEditor *emae,
- gboolean visible_host)
-{
- emae->priv->source.visible_host = visible_host;
-
- g_object_notify (G_OBJECT (emae), "store-visible-host");
-}
-
-static gboolean
-emae_get_store_visible_path (EMAccountEditor *emae)
-{
- return emae->priv->source.visible_path;
-}
-
-static void
-emae_set_store_visible_path (EMAccountEditor *emae,
- gboolean visible_path)
-{
- emae->priv->source.visible_path = visible_path;
-
- g_object_notify (G_OBJECT (emae), "store-visible-path");
-}
-
-static gboolean
-emae_get_store_visible_port (EMAccountEditor *emae)
-{
- return emae->priv->source.visible_port;
-}
-
-static void
-emae_set_store_visible_port (EMAccountEditor *emae,
- gboolean visible_port)
-{
- emae->priv->source.visible_port = visible_port;
-
- g_object_notify (G_OBJECT (emae), "store-visible-port");
-}
-
-static gboolean
-emae_get_store_visible_user (EMAccountEditor *emae)
-{
- return emae->priv->source.visible_user;
-}
-
-static void
-emae_set_store_visible_user (EMAccountEditor *emae,
- gboolean visible_user)
-{
- emae->priv->source.visible_user = visible_user;
-
- g_object_notify (G_OBJECT (emae), "store-visible-user");
-}
-
-static CamelProvider *
-emae_get_transport_provider (EMAccountEditor *emae)
-{
- CamelProvider *provider = NULL;
- const gchar *protocol;
-
- protocol = emae->priv->transport.protocol;
-
- if (protocol != NULL)
- provider = camel_provider_get (protocol, NULL);
-
- return provider;
-}
-
-static gboolean
-emae_get_transport_requires_auth (EMAccountEditor *emae)
-{
- return emae->priv->transport.requires_auth;
-}
-
-static void
-emae_set_transport_requires_auth (EMAccountEditor *emae,
- gboolean requires_auth)
-{
- emae->priv->transport.requires_auth = requires_auth;
-
- g_object_notify (G_OBJECT (emae), "transport-requires-auth");
-}
-
-static CamelSettings *
-emae_get_transport_settings (EMAccountEditor *emae)
-{
- return emae->priv->transport.settings;
-}
-
-static void
-emae_set_transport_settings (EMAccountEditor *emae,
- CamelSettings *settings)
-{
- if (settings != NULL)
- g_object_ref (settings);
-
- if (emae->priv->transport.settings != NULL) {
- g_signal_handlers_disconnect_by_func (
- emae->priv->transport.settings,
- emae_config_target_changed_cb, emae);
- g_object_unref (emae->priv->transport.settings);
- }
-
- emae->priv->transport.settings = settings;
-
- g_object_notify (G_OBJECT (emae), "transport-settings");
-}
-
-static gboolean
-emae_get_transport_visible_auth (EMAccountEditor *emae)
-{
- return emae->priv->transport.visible_auth;
-}
-
-static void
-emae_set_transport_visible_auth (EMAccountEditor *emae,
- gboolean visible_auth)
-{
- emae->priv->transport.visible_auth = visible_auth;
-
- g_object_notify (G_OBJECT (emae), "transport-visible-auth");
-}
-
-static gboolean
-emae_get_transport_visible_host (EMAccountEditor *emae)
-{
- return emae->priv->transport.visible_host;
-}
-
-static void
-emae_set_transport_visible_host (EMAccountEditor *emae,
- gboolean visible_host)
-{
- emae->priv->transport.visible_host = visible_host;
-
- g_object_notify (G_OBJECT (emae), "transport-visible-host");
-}
-
-static gboolean
-emae_get_transport_visible_path (EMAccountEditor *emae)
-{
- return emae->priv->transport.visible_path;
-}
-
-static void
-emae_set_transport_visible_path (EMAccountEditor *emae,
- gboolean visible_path)
-{
- emae->priv->transport.visible_path = visible_path;
-
- g_object_notify (G_OBJECT (emae), "transport-visible-path");
-}
-
-static gboolean
-emae_get_transport_visible_port (EMAccountEditor *emae)
-{
- return emae->priv->transport.visible_port;
-}
-
-static void
-emae_set_transport_visible_port (EMAccountEditor *emae,
- gboolean visible_port)
-{
- emae->priv->transport.visible_port = visible_port;
-
- g_object_notify (G_OBJECT (emae), "transport-visible-port");
-}
-
-static gboolean
-emae_get_transport_visible_user (EMAccountEditor *emae)
-{
- return emae->priv->transport.visible_user;
-}
-
-static void
-emae_set_transport_visible_user (EMAccountEditor *emae,
- gboolean visible_user)
-{
- emae->priv->transport.visible_user = visible_user;
-
- g_object_notify (G_OBJECT (emae), "transport-visible-user");
-}
-
-static void
-emae_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_BACKEND:
- emae_set_backend (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_object (value));
- return;
-
- case PROP_ORIGINAL_ACCOUNT:
- emae_set_original_account (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_object (value));
- return;
-
- case PROP_STORE_REQUIRES_AUTH:
- emae_set_store_requires_auth (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_STORE_SETTINGS:
- emae_set_store_settings (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_object (value));
- return;
-
- case PROP_STORE_VISIBLE_AUTH:
- emae_set_store_visible_auth (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_STORE_VISIBLE_HOST:
- emae_set_store_visible_host (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_STORE_VISIBLE_PATH:
- emae_set_store_visible_path (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_STORE_VISIBLE_PORT:
- emae_set_store_visible_port (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_STORE_VISIBLE_USER:
- emae_set_store_visible_user (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_TRANSPORT_REQUIRES_AUTH:
- emae_set_transport_requires_auth (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_TRANSPORT_SETTINGS:
- emae_set_transport_settings (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_object (value));
- return;
-
- case PROP_TRANSPORT_VISIBLE_AUTH:
- emae_set_transport_visible_auth (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_TRANSPORT_VISIBLE_HOST:
- emae_set_transport_visible_host (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_TRANSPORT_VISIBLE_PATH:
- emae_set_transport_visible_path (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_TRANSPORT_VISIBLE_PORT:
- emae_set_transport_visible_port (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_TRANSPORT_VISIBLE_USER:
- emae_set_transport_visible_user (
- EM_ACCOUNT_EDITOR (object),
- g_value_get_boolean (value));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-emae_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_BACKEND:
- g_value_set_object (
- value,
- em_account_editor_get_backend (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_MODIFIED_ACCOUNT:
- g_value_set_object (
- value,
- em_account_editor_get_modified_account (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_ORIGINAL_ACCOUNT:
- g_value_set_object (
- value,
- em_account_editor_get_original_account (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_PROVIDER:
- g_value_set_pointer (
- value,
- emae_get_store_provider (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_REQUIRES_AUTH:
- g_value_set_boolean (
- value,
- emae_get_store_requires_auth (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_SETTINGS:
- g_value_set_object (
- value,
- emae_get_store_settings (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_VISIBLE_AUTH:
- g_value_set_boolean (
- value,
- emae_get_store_visible_auth (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_VISIBLE_HOST:
- g_value_set_boolean (
- value,
- emae_get_store_visible_host (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_VISIBLE_PATH:
- g_value_set_boolean (
- value,
- emae_get_store_visible_path (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_VISIBLE_PORT:
- g_value_set_boolean (
- value,
- emae_get_store_visible_port (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_STORE_VISIBLE_USER:
- g_value_set_boolean (
- value,
- emae_get_store_visible_user (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_PROVIDER:
- g_value_set_pointer (
- value,
- emae_get_transport_provider (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_REQUIRES_AUTH:
- g_value_set_boolean (
- value,
- emae_get_transport_requires_auth (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_SETTINGS:
- g_value_set_object (
- value,
- emae_get_transport_settings (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_VISIBLE_AUTH:
- g_value_set_boolean (
- value,
- emae_get_transport_visible_auth (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_VISIBLE_HOST:
- g_value_set_boolean (
- value,
- emae_get_transport_visible_host (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_VISIBLE_PATH:
- g_value_set_boolean (
- value,
- emae_get_transport_visible_path (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_VISIBLE_PORT:
- g_value_set_boolean (
- value,
- emae_get_transport_visible_port (
- EM_ACCOUNT_EDITOR (object)));
- return;
-
- case PROP_TRANSPORT_VISIBLE_USER:
- g_value_set_boolean (
- value,
- emae_get_transport_visible_user (
- EM_ACCOUNT_EDITOR (object)));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-emae_dispose (GObject *object)
-{
- EMAccountEditorPrivate *priv;
-
- priv = EM_ACCOUNT_EDITOR_GET_PRIVATE (object);
-
- if (priv->backend != NULL) {
- g_object_unref (priv->backend);
- priv->backend = NULL;
- }
-
- if (priv->modified_account != NULL) {
- g_signal_handlers_disconnect_by_func (
- priv->modified_account,
- emae_config_target_changed_cb, object);
- g_object_unref (priv->modified_account);
- priv->modified_account = NULL;
- }
-
- if (priv->original_account != NULL) {
- g_object_unref (priv->original_account);
- priv->original_account = NULL;
- }
-
- if (priv->source.settings != NULL) {
- g_signal_handlers_disconnect_by_func (
- priv->source.settings,
- emae_config_target_changed_cb, object);
- g_object_unref (priv->source.settings);
- priv->source.settings = NULL;
- }
-
- if (priv->transport.settings != NULL) {
- g_signal_handlers_disconnect_by_func (
- priv->transport.settings,
- emae_config_target_changed_cb, object);
- g_object_unref (priv->transport.settings);
- priv->transport.settings = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (em_account_editor_parent_class)->dispose (object);
-}
-
-static void
-emae_finalize (GObject *object)
-{
- EMAccountEditor *emae = EM_ACCOUNT_EDITOR (object);
- EMAccountEditorPrivate *priv = emae->priv;
-
- if (priv->config)
- g_object_weak_unref ((GObject *) priv->config, emae_config_gone_cb, emae);
-
- if (priv->sig_added_id) {
- ESignatureList *signatures;
-
- signatures = e_get_signature_list ();
- g_signal_handler_disconnect (signatures, priv->sig_added_id);
- g_signal_handler_disconnect (signatures, priv->sig_removed_id);
- g_signal_handler_disconnect (signatures, priv->sig_changed_id);
- }
-
- g_list_free (priv->providers);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (em_account_editor_parent_class)->finalize (object);
-}
-
-static void
-emae_constructed (GObject *object)
-{
- EMAccountEditor *emae;
-
- emae = EM_ACCOUNT_EDITOR (object);
-
- /* Chain up to parent's constructed() method. */
- G_OBJECT_CLASS (em_account_editor_parent_class)->constructed (object);
-
- emae->priv->providers = emae_list_providers ();
-
- /* Set some defaults on the new account before we get started. */
- if (emae->priv->new_account) {
- EMailBackend *backend;
- EMailSession *session;
-
- backend = em_account_editor_get_backend (emae);
- session = e_mail_backend_get_session (backend);
-
- /* Pick local Drafts folder. */
- e_account_set_string (
- emae->priv->modified_account,
- E_ACCOUNT_DRAFTS_FOLDER_URI,
- e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_DRAFTS));
-
- /* Pick local Sent folder. */
- e_account_set_string (
- emae->priv->modified_account,
- E_ACCOUNT_SENT_FOLDER_URI,
- e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_SENT));
-
- /* Encrypt to self by default. */
- e_account_set_bool (
- emae->priv->modified_account,
- E_ACCOUNT_PGP_ENCRYPT_TO_SELF, TRUE);
- e_account_set_bool (
- emae->priv->modified_account,
- E_ACCOUNT_SMIME_ENCRYPT_TO_SELF, TRUE);
- }
-
- g_signal_connect_swapped (
- emae->priv->modified_account, "changed",
- G_CALLBACK (emae_config_target_changed_cb), emae);
-}
-
-static void
-em_account_editor_class_init (EMAccountEditorClass *class)
-{
- GObjectClass *object_class;
-
- g_type_class_add_private (class, sizeof (EMAccountEditorPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = emae_set_property;
- object_class->get_property = emae_get_property;
- object_class->dispose = emae_dispose;
- object_class->finalize = emae_finalize;
- object_class->constructed = emae_constructed;
-
- g_object_class_install_property (
- object_class,
- PROP_BACKEND,
- g_param_spec_object (
- "backend",
- "Mail Backend",
- NULL,
- E_TYPE_MAIL_BACKEND,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_MODIFIED_ACCOUNT,
- g_param_spec_object (
- "modified-account",
- "Modified Account",
- NULL,
- E_TYPE_ACCOUNT,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_ORIGINAL_ACCOUNT,
- g_param_spec_object (
- "original-account",
- "Original Account",
- NULL,
- E_TYPE_ACCOUNT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_PROVIDER,
- g_param_spec_pointer (
- "store-provider",
- "Store Provider",
- "CamelProvider for the storage service",
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_REQUIRES_AUTH,
- g_param_spec_boolean (
- "store-requires-auth",
- "Store Requires Auth",
- "Storage service requires authentication",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_SETTINGS,
- g_param_spec_object (
- "store-settings",
- "Store Settings",
- "CamelSettings for the storage service",
- CAMEL_TYPE_SETTINGS,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_VISIBLE_AUTH,
- g_param_spec_boolean (
- "store-visible-auth",
- "Store Visible Auth",
- "Show auth widgets for the storage service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_VISIBLE_HOST,
- g_param_spec_boolean (
- "store-visible-host",
- "Store Visible Host",
- "Show host widgets for the storage service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_VISIBLE_PATH,
- g_param_spec_boolean (
- "store-visible-path",
- "Store Visible Path",
- "Show path widgets for the storage service",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_VISIBLE_PORT,
- g_param_spec_boolean (
- "store-visible-port",
- "Store Visible Port",
- "Show port widgets for the storage service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_STORE_VISIBLE_USER,
- g_param_spec_boolean (
- "store-visible-user",
- "Store Visible User",
- "Show user widgets for the storage service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_PROVIDER,
- g_param_spec_pointer (
- "transport-provider",
- "Transport Provider",
- "CamelProvider for the transport service",
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_REQUIRES_AUTH,
- g_param_spec_boolean (
- "transport-requires-auth",
- "Transport Requires Auth",
- "Transport service requires authentication",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_SETTINGS,
- g_param_spec_object (
- "transport-settings",
- "Transport Settings",
- "CamelSettings for the transport service",
- CAMEL_TYPE_SETTINGS,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_VISIBLE_AUTH,
- g_param_spec_boolean (
- "transport-visible-auth",
- "Transport Visible Auth",
- "Show auth widgets for the transport service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_VISIBLE_HOST,
- g_param_spec_boolean (
- "transport-visible-host",
- "Transport Visible Host",
- "Show host widgets for the transport service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_VISIBLE_PATH,
- g_param_spec_boolean (
- "transport-visible-path",
- "Transport Visible Path",
- "Show path widgets for the transport service",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_VISIBLE_PORT,
- g_param_spec_boolean (
- "transport-visible-port",
- "Transport Visible Port",
- "Show port widgets for the transport service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (
- object_class,
- PROP_TRANSPORT_VISIBLE_USER,
- g_param_spec_boolean (
- "transport-visible-user",
- "Transport Visible User",
- "Show user widgets for the transport service",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT |
- G_PARAM_STATIC_STRINGS));
-}
-
-static void
-em_account_editor_init (EMAccountEditor *emae)
-{
- emae->priv = EM_ACCOUNT_EDITOR_GET_PRIVATE (emae);
-
- emae->priv->selected_server = NULL;
- emae->priv->source.emae = emae;
- emae->priv->transport.emae = emae;
- emae->priv->widgets = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Pick default storage and transport protocols. */
- emae->priv->source.protocol = "imapx";
- emae->priv->transport.protocol = "smtp";
-
- emae->priv->is_gmail = FALSE;
- emae->priv->is_yahoo = FALSE;
-}
-
-/**
- * em_account_editor_new:
- * @account:
- * @type:
- *
- * Create a new account editor. If @account is NULL then this is to
- * create a new account, else @account is copied to a working
- * structure and is for editing an existing account.
- *
- * Return value:
- **/
-EMAccountEditor *
-em_account_editor_new (EAccount *account,
- EMAccountEditorType type,
- EMailBackend *backend,
- const gchar *id)
-{
- EMAccountEditor *emae;
-
- g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
-
- emae = g_object_new (
- EM_TYPE_ACCOUNT_EDITOR,
- "original-account", account,
- "backend", backend, NULL);
-
- em_account_editor_construct (emae, type, id);
-
- return emae;
-}
-
-/**
- * em_account_editor_new_for_pages:
- * @account:
- * @type:
- *
- * Create a new account editor. If @account is NULL then this is to
- * create a new account, else @account is copied to a working
- * structure and is for editing an existing account.
- *
- * Return value:
- **/
-EMAccountEditor *
-em_account_editor_new_for_pages (EAccount *account,
- EMAccountEditorType type,
- EMailBackend *backend,
- const gchar *id,
- GtkWidget **pages)
-{
- EMAccountEditor *emae;
-
- g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
-
- emae = g_object_new (
- EM_TYPE_ACCOUNT_EDITOR,
- "original-account", account,
- "backend", backend, NULL);
-
- emae->pages = pages;
- em_account_editor_construct (emae, type, id);
-
- return emae;
-}
-
-EMailBackend *
-em_account_editor_get_backend (EMAccountEditor *emae)
-{
- g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
-
- return emae->priv->backend;
-}
-
-EAccount *
-em_account_editor_get_modified_account (EMAccountEditor *emae)
-{
- g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
-
- return emae->priv->modified_account;
-}
-
-EAccount *
-em_account_editor_get_original_account (EMAccountEditor *emae)
-{
- g_return_val_if_fail (EM_IS_ACCOUNT_EDITOR (emae), NULL);
-
- return emae->priv->original_account;
-}
-
-/* ********************************************************************** */
-
-static gboolean
-is_email (const gchar *address)
-{
- /* This is supposed to check if the address's domain could be
- * an FQDN but alas, it's not worth the pain and suffering. */
- const gchar *at;
-
- at = strchr (address, '@');
- /* make sure we have an '@' and that it's not the first or last gchar */
- if (!at || at == address || *(at + 1) == '\0')
- return FALSE;
-
- return TRUE;
-}
-
-static CamelURL *
-emae_account_url (EMAccountEditor *emae,
- gint urlid)
-{
- EAccount *account;
- CamelURL *url = NULL;
- const gchar *uri;
-
- account = em_account_editor_get_modified_account (emae);
- uri = e_account_get_string (account, urlid);
-
- /* XXX Stupid hack for these stupid transport-only accounts.
- * We've been saving these as invalid URI strings all this
- * time; no protocol, just "//...". Catch it and fix it. */
- if (uri != NULL && g_str_has_prefix (uri, "//"))
- return camel_url_new ("none:", NULL);
-
- if (uri != NULL && *uri != '\0')
- url = camel_url_new (uri, NULL);
-
- if (url == NULL) {
- url = camel_url_new ("dummy:", NULL);
- camel_url_set_protocol (url, NULL);
- }
-
- return url;
-}
-
-/* ********************************************************************** */
-
-static void
-default_folders_clicked (GtkButton *button,
- gpointer user_data)
-{
- EMAccountEditor *emae = user_data;
- EMFolderSelectionButton *folder_button;
- EMailBackend *backend;
- EMailSession *session;
- const gchar *folder_uri;
-
- backend = em_account_editor_get_backend (emae);
- session = e_mail_backend_get_session (backend);
-
- folder_button =
- EM_FOLDER_SELECTION_BUTTON (
- emae->priv->drafts_folder_button);
- folder_uri = e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_DRAFTS);
- em_folder_selection_button_set_folder_uri (folder_button, folder_uri);
- emae_account_folder_changed (folder_button, emae);
-
- folder_button =
- EM_FOLDER_SELECTION_BUTTON (
- emae->priv->sent_folder_button);
- folder_uri = e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_SENT);
- em_folder_selection_button_set_folder_uri (folder_button, folder_uri);
- emae_account_folder_changed (folder_button, emae);
-
- gtk_toggle_button_set_active (emae->priv->trash_folder_check, FALSE);
- gtk_toggle_button_set_active (emae->priv->junk_folder_check, FALSE);
-}
-
-/* The camel provider auto-detect interface should be deprecated.
- * But it still needs to be replaced with something of similar functionality.
- * Just using the normal econfig plugin mechanism should be adequate. */
-static void
-emae_auto_detect_free (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- g_free (key);
- g_free (value);
-}
-
-static void
-emae_auto_detect (EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
- EMAccountEditorService *service = &priv->source;
- CamelProvider *provider;
- GHashTable *auto_detected;
- GSList *l;
- CamelProviderConfEntry *entries;
- gchar *value;
- gint i;
- CamelURL *url;
-
- provider = camel_provider_get (service->protocol, NULL);
-
- if (provider == NULL || provider->extra_conf == NULL)
- return;
-
- entries = provider->extra_conf;
-
- d (printf ("Running auto-detect\n"));
-
- url = emae_account_url (emae, E_ACCOUNT_SOURCE_URL);
- camel_provider_auto_detect (provider, url, &auto_detected, NULL);
- camel_url_free (url);
-
- if (auto_detected == NULL) {
- d (printf (" no values detected\n"));
- return;
- }
-
- for (i = 0; entries[i].type != CAMEL_PROVIDER_CONF_END; i++) {
- struct _receive_options_item *item;
- GtkWidget *w;
-
- if (entries[i].name == NULL
- || (value = g_hash_table_lookup (auto_detected, entries[i].name)) == NULL)
- continue;
-
- /* only 2 providers use this, and they only do it for 3 entries only */
- g_return_if_fail (entries[i].type == CAMEL_PROVIDER_CONF_ENTRY);
-
- w = NULL;
- for (l = emae->priv->extra_items; l; l = g_slist_next (l)) {
- item = l->data;
- if (item->extra_table && (w = g_hash_table_lookup (item->extra_table, entries[i].name)))
- break;
- }
-
- gtk_entry_set_text ((GtkEntry *)w, value?value:"");
- }
-
- g_hash_table_foreach (auto_detected, emae_auto_detect_free, NULL);
- g_hash_table_destroy (auto_detected);
-}
-
-static void
-emae_signature_added (ESignatureList *signatures,
- ESignature *sig,
- EMAccountEditor *emae)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- const gchar *name;
- const gchar *uid;
-
- name = e_signature_get_name (sig);
- uid = e_signature_get_uid (sig);
-
- model = gtk_combo_box_get_model (emae->priv->signatures_dropdown);
-
- gtk_list_store_append ((GtkListStore *) model, &iter);
- gtk_list_store_set ((GtkListStore *) model, &iter, 0, name, 1, uid, -1);
-
- gtk_combo_box_set_active (
- emae->priv->signatures_dropdown,
- gtk_tree_model_iter_n_children (model, NULL) - 1);
-}
-
-static gint
-emae_signature_get_iter (EMAccountEditor *emae,
- ESignature *sig,
- GtkTreeModel **modelp,
- GtkTreeIter *iter)
-{
- GtkTreeModel *model;
- gint found = 0;
-
- model = gtk_combo_box_get_model (emae->priv->signatures_dropdown);
- *modelp = model;
- if (!gtk_tree_model_get_iter_first (model, iter))
- return FALSE;
-
- do {
- const gchar *signature_uid;
- gchar *uid;
-
- signature_uid = e_signature_get_uid (sig);
-
- gtk_tree_model_get (model, iter, 1, &uid, -1);
- if (uid && !strcmp (uid, signature_uid))
- found = TRUE;
- g_free (uid);
- } while (!found && gtk_tree_model_iter_next (model, iter));
-
- return found;
-}
-
-static void
-emae_signature_removed (ESignatureList *signatures,
- ESignature *sig,
- EMAccountEditor *emae)
-{
- GtkTreeIter iter;
- GtkTreeModel *model;
-
- if (emae_signature_get_iter (emae, sig, &model, &iter))
- gtk_list_store_remove ((GtkListStore *) model, &iter);
-}
-
-static void
-emae_signature_changed (ESignatureList *signatures,
- ESignature *sig,
- EMAccountEditor *emae)
-{
- GtkTreeIter iter;
- GtkTreeModel *model;
- const gchar *name;
-
- name = e_signature_get_name (sig);
-
- if (emae_signature_get_iter (emae, sig, &model, &iter))
- gtk_list_store_set ((GtkListStore *) model, &iter, 0, name, -1);
-}
-
-static void
-emae_signaturetype_changed (GtkComboBox *dropdown,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gint id = gtk_combo_box_get_active (dropdown);
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *uid = NULL;
-
- account = em_account_editor_get_modified_account (emae);
-
- if (id != -1) {
- model = gtk_combo_box_get_model (dropdown);
- if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id))
- gtk_tree_model_get (model, &iter, 1, &uid, -1);
- }
-
- e_account_set_string (account, E_ACCOUNT_ID_SIGNATURE, uid);
- g_free (uid);
-}
-
-static void
-emae_signature_new (GtkWidget *widget,
- EMAccountEditor *emae)
-{
- GtkWidget *editor;
- gpointer parent;
-
- parent = gtk_widget_get_toplevel (widget);
- parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
-
- editor = e_signature_editor_new ();
- gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
- gtk_widget_show (editor);
-}
-
-static GtkWidget *
-emae_setup_signatures (EMAccountEditor *emae,
- GtkBuilder *builder)
-{
- EMAccountEditorPrivate *p = emae->priv;
- EAccount *account;
- GtkComboBox *dropdown = (GtkComboBox *)e_builder_get_widget (builder, "signature_dropdown");
- GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
- GtkListStore *store;
- gint i, active = 0;
- GtkTreeIter iter;
- ESignatureList *signatures;
- EIterator *it;
- const gchar *current;
- GtkWidget *button;
-
- account = em_account_editor_get_modified_account (emae);
- current = e_account_get_string (account, E_ACCOUNT_ID_SIGNATURE);
-
- emae->priv->signatures_dropdown = dropdown;
- gtk_widget_show ((GtkWidget *) dropdown);
-
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
-
- gtk_list_store_append (store, &iter);
- /* Translators: "None" as an option for a default signature of an account, part of "Signature: None" */
- gtk_list_store_set (store, &iter, 0, C_("mail-signature", "None"), 1, NULL, -1);
-
- signatures = e_get_signature_list ();
-
- if (p->sig_added_id == 0) {
- p->sig_added_id = g_signal_connect (
- signatures, "signature-added",
- G_CALLBACK (emae_signature_added), emae);
- p->sig_removed_id = g_signal_connect (
- signatures, "signature-removed",
- G_CALLBACK (emae_signature_removed), emae);
- p->sig_changed_id = g_signal_connect (
- signatures, "signature-changed",
- G_CALLBACK (emae_signature_changed), emae);
- }
-
- /* we need to count the 'none' entry before using the index */
- i = 1;
- it = e_list_get_iterator ((EList *) signatures);
- while (e_iterator_is_valid (it)) {
- ESignature *sig = (ESignature *) e_iterator_get (it);
- const gchar *name;
- const gchar *uid;
-
- name = e_signature_get_name (sig);
- uid = e_signature_get_uid (sig);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, name, 1, uid, -1);
-
- if (current && !strcmp (current, uid))
- active = i;
-
- e_iterator_next (it);
- i++;
- }
- g_object_unref (it);
-
- gtk_cell_layout_pack_start ((GtkCellLayout *) dropdown, cell, TRUE);
- gtk_cell_layout_set_attributes ((GtkCellLayout *)dropdown, cell, "text", 0, NULL);
-
- gtk_combo_box_set_model (dropdown, (GtkTreeModel *) store);
- gtk_combo_box_set_active (dropdown, active);
-
- g_signal_connect (
- dropdown, "changed",
- G_CALLBACK (emae_signaturetype_changed), emae);
-
- button = e_builder_get_widget (builder, "sigAddNew");
- g_signal_connect (
- button, "clicked",
- G_CALLBACK (emae_signature_new), emae);
-
- return (GtkWidget *) dropdown;
-}
-
-static void
-emae_receipt_policy_changed (GtkComboBox *dropdown,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gint id = gtk_combo_box_get_active (dropdown);
- GtkTreeModel *model;
- GtkTreeIter iter;
- EAccountReceiptPolicy policy;
-
- account = em_account_editor_get_modified_account (emae);
-
- if (id != -1) {
- model = gtk_combo_box_get_model (dropdown);
- if (gtk_tree_model_iter_nth_child (model, &iter, NULL, id)) {
- gtk_tree_model_get (model, &iter, 1, &policy, -1);
- e_account_set_int (account, E_ACCOUNT_RECEIPT_POLICY, policy);
- }
- }
-}
-
-static GtkWidget *
-emae_setup_receipt_policy (EMAccountEditor *emae,
- GtkBuilder *builder)
-{
- EAccount *account;
- GtkComboBox *dropdown = (GtkComboBox *)e_builder_get_widget (builder, "receipt_policy_dropdown");
- GtkListStore *store;
- GtkCellRenderer *cell;
- gint i = 0, active = 0;
- GtkTreeIter iter;
- EAccountReceiptPolicy current;
- static struct {
- EAccountReceiptPolicy policy;
- const gchar *label;
- } receipt_policies[] = {
- { E_ACCOUNT_RECEIPT_NEVER, N_("Never") },
- { E_ACCOUNT_RECEIPT_ALWAYS, N_("Always") },
- { E_ACCOUNT_RECEIPT_ASK, N_("Ask for each message") }
- };
-
- account = em_account_editor_get_modified_account (emae);
- current = account->receipt_policy;
-
- gtk_widget_show ((GtkWidget *) dropdown);
-
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
-
- for (i = 0; i < 3; ++i) {
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- 0, _(receipt_policies[i].label),
- 1, receipt_policies[i].policy,
- -1);
- if (current == receipt_policies[i].policy)
- active = i;
- }
-
- gtk_combo_box_set_model (dropdown, (GtkTreeModel *) store);
-
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dropdown), cell, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (dropdown), cell, "text", 0, NULL);
-
- gtk_combo_box_set_active (dropdown, active);
-
- g_signal_connect (
- dropdown, "changed",
- G_CALLBACK (emae_receipt_policy_changed), emae);
-
- return (GtkWidget *) dropdown;
-}
-
-static void
-emae_account_entry_changed (GtkEntry *entry,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gchar *text;
- gpointer data;
-
- account = em_account_editor_get_modified_account (emae);
- data = g_object_get_data (G_OBJECT (entry), "account-item");
- text = g_strdup (gtk_entry_get_text (entry));
-
- g_strstrip (text);
-
- e_account_set_string (account, GPOINTER_TO_INT (data), text);
-
- g_free (text);
-}
-
-static GtkEntry *
-emae_account_entry (EMAccountEditor *emae,
- const gchar *name,
- gint item,
- GtkBuilder *builder)
-{
- EAccount *account;
- GtkEntry *entry;
- const gchar *text;
-
- account = em_account_editor_get_modified_account (emae);
- entry = (GtkEntry *) e_builder_get_widget (builder, name);
- text = e_account_get_string (account, item);
- if (text)
- gtk_entry_set_text (entry, text);
- g_object_set_data ((GObject *)entry, "account-item", GINT_TO_POINTER(item));
- g_signal_connect (
- entry, "changed",
- G_CALLBACK (emae_account_entry_changed), emae);
-
- return entry;
-}
-
-static void
-emae_account_toggle_changed (GtkToggleButton *toggle,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gboolean active;
- gpointer data;
-
- account = em_account_editor_get_modified_account (emae);
- data = g_object_get_data (G_OBJECT (toggle), "account-item");
- active = gtk_toggle_button_get_active (toggle);
-
- e_account_set_bool (account, GPOINTER_TO_INT (data), active);
-}
-
-static void
-emae_account_toggle_widget (EMAccountEditor *emae,
- GtkToggleButton *toggle,
- gint item)
-{
- EAccount *account;
- gboolean active;
-
- account = em_account_editor_get_modified_account (emae);
-
- active = e_account_get_bool (account, item);
- gtk_toggle_button_set_active (toggle, active);
-
- g_object_set_data (
- G_OBJECT (toggle), "account-item",
- GINT_TO_POINTER (item));
-
- g_signal_connect (
- toggle, "toggled",
- G_CALLBACK (emae_account_toggle_changed), emae);
-}
-
-static GtkToggleButton *
-emae_account_toggle (EMAccountEditor *emae,
- const gchar *name,
- gint item,
- GtkBuilder *builder)
-{
- GtkToggleButton *toggle;
-
- toggle = (GtkToggleButton *) e_builder_get_widget (builder, name);
- emae_account_toggle_widget (emae, toggle, item);
-
- return toggle;
-}
-
-static void
-emae_account_spinint_changed (GtkSpinButton *spin,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gpointer data;
- gint value;
-
- account = em_account_editor_get_modified_account (emae);
- data = g_object_get_data (G_OBJECT (spin), "account-item");
- value = gtk_spin_button_get_value (spin);
-
- e_account_set_int (account, GPOINTER_TO_INT (data), value);
-}
-
-static void
-emae_account_spinint_widget (EMAccountEditor *emae,
- GtkSpinButton *spin,
- gint item)
-{
- EAccount *account;
- gint v_int;
-
- account = em_account_editor_get_modified_account (emae);
-
- v_int = e_account_get_int (account, item);
- gtk_spin_button_set_value (spin, v_int);
-
- g_object_set_data (
- G_OBJECT (spin), "account-item",
- GINT_TO_POINTER (item));
-
- g_signal_connect (
- spin, "value-changed",
- G_CALLBACK (emae_account_spinint_changed), emae);
-}
-
-static void
-emae_account_folder_changed (EMFolderSelectionButton *folder,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gpointer data;
- const gchar *selection;
-
- account = em_account_editor_get_modified_account (emae);
- data = g_object_get_data (G_OBJECT (folder), "account-item");
- selection = em_folder_selection_button_get_folder_uri (folder);
-
- e_account_set_string (account, GPOINTER_TO_INT (data), selection);
-}
-
-static EMFolderSelectionButton *
-emae_account_folder (EMAccountEditor *emae,
- const gchar *name,
- gint item,
- gint deffolder,
- GtkBuilder *builder)
-{
- EAccount *account;
- EMFolderSelectionButton *folder;
- EMailBackend *backend;
- EMailSession *session;
- const gchar *uri;
-
- account = em_account_editor_get_modified_account (emae);
- backend = em_account_editor_get_backend (emae);
- session = e_mail_backend_get_session (backend);
-
- folder = (EMFolderSelectionButton *) e_builder_get_widget (builder, name);
- em_folder_selection_button_set_session (folder, session);
-
- uri = e_account_get_string (account, item);
- if (uri != NULL) {
- em_folder_selection_button_set_folder_uri (folder, uri);
- } else {
- uri = e_mail_session_get_local_folder_uri (session, deffolder);
- em_folder_selection_button_set_folder_uri (folder, uri);
- }
-
- g_object_set_data ((GObject *)folder, "account-item", GINT_TO_POINTER(item));
- g_object_set_data ((GObject *)folder, "folder-default", GINT_TO_POINTER(deffolder));
- g_signal_connect (
- folder, "selected",
- G_CALLBACK (emae_account_folder_changed), emae);
- gtk_widget_show ((GtkWidget *) folder);
-
- return folder;
-}
-
-#if defined (HAVE_NSS) && defined (ENABLE_SMIME)
-static void
-smime_changed (EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
- gint act;
- const gchar *tmp;
-
- tmp = gtk_entry_get_text (priv->smime_sign_key);
- act = tmp && tmp[0];
- gtk_widget_set_sensitive ((GtkWidget *) priv->smime_sign_key_clear, act);
- gtk_widget_set_sensitive ((GtkWidget *) priv->smime_sign_default, act);
- if (!act)
- gtk_toggle_button_set_active (priv->smime_sign_default, FALSE);
-
- tmp = gtk_entry_get_text (priv->smime_encrypt_key);
- act = tmp && tmp[0];
- gtk_widget_set_sensitive ((GtkWidget *) priv->smime_encrypt_key_clear, act);
- gtk_widget_set_sensitive ((GtkWidget *) priv->smime_encrypt_default, act);
- gtk_widget_set_sensitive ((GtkWidget *) priv->smime_encrypt_to_self, act);
- if (!act) {
- gtk_toggle_button_set_active (priv->smime_encrypt_default, FALSE);
- }
-}
-
-static void
-smime_sign_key_selected (GtkWidget *dialog,
- const gchar *key,
- EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
-
- if (key != NULL) {
- gtk_entry_set_text (priv->smime_sign_key, key);
- smime_changed (emae);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-smime_sign_key_select (GtkWidget *button,
- EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
- GtkWidget *w;
-
- w = e_cert_selector_new (E_CERT_SELECTOR_SIGNER, gtk_entry_get_text (priv->smime_sign_key));
- gtk_window_set_modal ((GtkWindow *) w, TRUE);
- gtk_window_set_transient_for ((GtkWindow *) w, (GtkWindow *) gtk_widget_get_toplevel (button));
- g_signal_connect (
- w, "selected",
- G_CALLBACK (smime_sign_key_selected), emae);
- gtk_widget_show (w);
-}
-
-static void
-smime_sign_key_clear (GtkWidget *w,
- EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
-
- gtk_entry_set_text (priv->smime_sign_key, "");
- smime_changed (emae);
-}
-
-static void
-smime_encrypt_key_selected (GtkWidget *dialog,
- const gchar *key,
- EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
-
- if (key != NULL) {
- gtk_entry_set_text (priv->smime_encrypt_key, key);
- smime_changed (emae);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-static void
-smime_encrypt_key_select (GtkWidget *button,
- EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
- GtkWidget *w;
-
- w = e_cert_selector_new (E_CERT_SELECTOR_RECIPIENT, gtk_entry_get_text (priv->smime_encrypt_key));
- gtk_window_set_modal ((GtkWindow *) w, TRUE);
- gtk_window_set_transient_for ((GtkWindow *) w, (GtkWindow *) gtk_widget_get_toplevel (button));
- g_signal_connect (
- w, "selected",
- G_CALLBACK (smime_encrypt_key_selected), emae);
- gtk_widget_show (w);
-}
-
-static void
-smime_encrypt_key_clear (GtkWidget *w,
- EMAccountEditor *emae)
-{
- EMAccountEditorPrivate *priv = emae->priv;
-
- gtk_entry_set_text (priv->smime_encrypt_key, "");
- smime_changed (emae);
-}
-#endif
-
-/* This is used to map each of the two services in a typical account to
- * the widgets that represent each service. i.e. the receiving (source)
- * service, and the sending (transport) service. It is used throughout
- * the following code to drive each page. */
-static struct _service_info {
- gint account_uri_key;
- gint save_passwd_key;
-
- const gchar *frame;
- const gchar *type_dropdown;
-
- const gchar *container;
- const gchar *description;
- const gchar *hostname;
- const gchar *hostlabel;
- const gchar *port;
- const gchar *portlabel;
- const gchar *username;
- const gchar *userlabel;
- const gchar *path;
- const gchar *pathlabel;
- const gchar *pathentry;
-
- const gchar *security_frame;
- const gchar *ssl_hbox;
- const gchar *use_ssl;
- const gchar *ssl_disabled;
-
- const gchar *needs_auth;
- const gchar *auth_frame;
-
- const gchar *authtype;
- const gchar *authtype_check;
-
- const gchar *remember_password;
-
-} emae_service_info[CAMEL_NUM_PROVIDER_TYPES] = {
-
- { E_ACCOUNT_SOURCE_URL,
- E_ACCOUNT_SOURCE_SAVE_PASSWD,
-
- "source-config-section",
- "source_type_dropdown",
-
- "vboxSourceBorder",
- "source_description",
- "source_host",
- "source_host_label",
- "source_port",
- "source_port_label",
- "source_user",
- "source_user_label",
- "source_path",
- "source_path_label",
- "source_path_entry",
-
- "source-security-section",
- "source_ssl_hbox",
- "source_use_ssl",
- "source_ssl_disabled",
-
- NULL,
- "source-auth-section",
-
- "source_auth_dropdown",
- "source_check_supported",
-
- "source_remember_password"
- },
-
- { E_ACCOUNT_TRANSPORT_URL,
- E_ACCOUNT_TRANSPORT_SAVE_PASSWD,
-
- "transport-server-section",
- "transport_type_dropdown",
-
- "vboxTransportBorder",
- "transport_description",
- "transport_host",
- "transport_host_label",
- "transport_port",
- "transport_port_label",
- "transport_user",
- "transport_user_label",
- NULL,
- NULL,
- NULL,
-
- "transport-security-section",
- "transport_ssl_hbox",
- "transport_use_ssl",
- "transport_ssl_disabled",
-
- "transport_needs_auth",
- "transport-auth-section",
-
- "transport_auth_dropdown",
- "transport_check_supported",
-
- "transport_remember_password"
- }
-};
-
-static void
-emae_file_chooser_changed (GtkFileChooser *file_chooser,
- EMAccountEditorService *service)
-{
- CamelLocalSettings *local_settings;
- const gchar *filename;
-
- local_settings = CAMEL_LOCAL_SETTINGS (service->settings);
- filename = gtk_file_chooser_get_filename (file_chooser);
- camel_local_settings_set_path (local_settings, filename);
-}
-
-static void
-emae_ensure_auth_mechanism (CamelProvider *provider,
- CamelSettings *settings)
-{
- CamelServiceAuthType *auth_type;
- const gchar *auth_mechanism;
-
- auth_mechanism =
- camel_network_settings_get_auth_mechanism (
- CAMEL_NETWORK_SETTINGS (settings));
-
- /* If a mechanism name is already set, we're fine. */
- if (auth_mechanism != NULL)
- return;
-
- /* Check that the CamelProvider defines some auth mechanisms.
- * If not, it's reasonable to leave the mechanism name unset. */
- if (provider->authtypes == NULL)
- return;
-
- /* No authentication mechanism has been chosen, so we'll choose
- * one from the CamelProvider's list of available mechanisms. */
-
- auth_type = provider->authtypes->data;
- auth_mechanism = auth_type->authproto;
-
- camel_network_settings_set_auth_mechanism (
- CAMEL_NETWORK_SETTINGS (settings), auth_mechanism);
-}
-
-static void
-emae_setup_settings (EMAccountEditorService *service)
-{
- CamelServiceClass *class;
- CamelProvider *provider;
- CamelSettings *settings = NULL;
- GType service_type;
- GType settings_type;
- CamelURL *url;
-
- provider = camel_provider_get (service->protocol, NULL);
- g_return_if_fail (provider != NULL);
-
- service_type = provider->object_types[service->type];
- g_return_if_fail (g_type_is_a (service_type, CAMEL_TYPE_SERVICE));
-
- class = g_type_class_ref (service_type);
- settings_type = class->settings_type;
- g_type_class_unref (class);
-
- url = emae_account_url (
- service->emae,
- emae_service_info[service->type].account_uri_key);
-
- /* Destroy any old CamelSettings instances.
- * Changing CamelProviders invalidates them. */
-
- if (service->settings != NULL)
- camel_settings_save_to_url (service->settings, url);
-
- if (g_type_is_a (settings_type, CAMEL_TYPE_SETTINGS)) {
- settings = g_object_new (settings_type, NULL);
- camel_settings_load_from_url (settings, url);
-
- g_signal_connect_swapped (
- settings, "notify",
- G_CALLBACK (emae_config_target_changed_cb),
- service->emae);
- }
-
- camel_url_free (url);
-
- if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) {
- emae_set_store_settings (service->emae, settings);
- emae_set_transport_settings (service->emae, settings);
-
- } else if (service->type == CAMEL_PROVIDER_STORE) {
- emae_set_store_settings (service->emae, settings);
-
- } else if (service->type == CAMEL_PROVIDER_TRANSPORT) {
- emae_set_transport_settings (service->emae, settings);
- }
-
- if (CAMEL_IS_NETWORK_SETTINGS (settings)) {
- CamelNetworkSettings *network_settings;
- guint16 port;
-
- network_settings = CAMEL_NETWORK_SETTINGS (settings);
-
- /* remember port number as set before binding properties,
- * because changes in auth-mechanism combo can reset the port,
- * thus effectively lost it, when set to other known value */
- port = camel_network_settings_get_port (network_settings);
-
- /* Even if the service does not need to authenticate, we
- * still need to initialize the auth mechanism combo box.
- * So if CamelSettings does not already have a mechanism
- * name set, choose one from the CamelProvider's list of
- * available auth mechanisms. Later in emae_commit(),
- * if need be, we'll revert the setting back to NULL. */
- emae_ensure_auth_mechanism (provider, settings);
-
- g_object_bind_property (
- settings, "auth-mechanism",
- service->authtype, "active-id",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- settings, "host",
- service->hostname, "text",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property_full (
- settings, "security-method",
- service->use_ssl, "active-id",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE,
- e_binding_transform_enum_value_to_nick,
- e_binding_transform_enum_nick_to_value,
- NULL, (GDestroyNotify) NULL);
-
- g_object_bind_property (
- settings, "port",
- service->port, "port",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- settings, "security-method",
- service->port, "security-method",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- settings, "user",
- service->username, "text",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- /* restore previously saved port, if set */
- if (port > 0)
- camel_network_settings_set_port (network_settings, port);
- }
-
- if (CAMEL_IS_LOCAL_SETTINGS (settings)) {
- const gchar *path;
-
- path = camel_local_settings_get_path (
- CAMEL_LOCAL_SETTINGS (settings));
- if (path != NULL && *path != '\0')
- gtk_file_chooser_set_filename (
- GTK_FILE_CHOOSER (service->pathentry), path);
- }
-
- g_object_unref (settings);
-}
-
-static void
-emae_service_provider_changed (EMAccountEditorService *service)
-{
- EConfig *config;
- EMConfigTargetSettings *target;
- CamelProvider *provider = NULL;
- const gchar *description;
-
- if (service->protocol != NULL)
- provider = camel_provider_get (service->protocol, NULL);
-
- description = (provider != NULL) ? provider->description : "";
- gtk_label_set_text (service->description, description);
-
- if (provider != NULL) {
- gboolean visible_auth;
- gboolean visible_host;
- gboolean visible_path;
- gboolean visible_port;
- gboolean visible_user;
- gboolean visible_ssl;
- gboolean allows;
- gboolean hidden;
-
- emae_setup_settings (service);
-
- gtk_widget_show (service->frame);
-
- allows = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_AUTH);
- hidden = CAMEL_PROVIDER_HIDDEN (provider, CAMEL_URL_PART_AUTH);
- visible_auth = (allows && !hidden);
-
- allows = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_HOST);
- hidden = CAMEL_PROVIDER_HIDDEN (provider, CAMEL_URL_PART_HOST);
- visible_host = (allows && !hidden);
-
- allows = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_PATH);
- hidden = CAMEL_PROVIDER_HIDDEN (provider, CAMEL_URL_PART_PATH);
- visible_path = (allows && !hidden);
-
- allows = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_PORT);
- hidden = CAMEL_PROVIDER_HIDDEN (provider, CAMEL_URL_PART_PORT);
- visible_port = (allows && !hidden);
-
- allows = CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_USER);
- hidden = CAMEL_PROVIDER_HIDDEN (provider, CAMEL_URL_PART_USER);
- visible_user = (allows && !hidden);
-
- switch (service->type) {
- case CAMEL_PROVIDER_STORE:
- g_object_set (
- service->emae,
- "store-visible-auth", visible_auth,
- "store-visible-host", visible_host,
- "store-visible-path", visible_path,
- "store-visible-port", visible_port,
- "store-visible-user", visible_user,
- NULL);
- break;
-
- case CAMEL_PROVIDER_TRANSPORT:
- g_object_set (
- service->emae,
- "transport-visible-auth", visible_auth,
- "transport-visible-host", visible_host,
- "transport-visible-path", visible_path,
- "transport-visible-port", visible_port,
- "transport-visible-user", visible_user,
- NULL);
- break;
-
- default:
- g_warn_if_reached ();
- }
-
- if (CAMEL_PROVIDER_ALLOWS (provider, CAMEL_URL_PART_AUTH)) {
- if (service->needs_auth && !CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_AUTH))
- gtk_widget_show ((GtkWidget *) service->needs_auth);
- } else {
- if (service->needs_auth)
- gtk_widget_hide ((GtkWidget *) service->needs_auth);
- }
-#ifdef HAVE_SSL
- visible_ssl =
- (provider->flags & CAMEL_PROVIDER_SUPPORTS_SSL);
- gtk_widget_set_visible (service->ssl_frame, visible_ssl);
- gtk_widget_set_visible (service->ssl_hbox, visible_ssl);
- gtk_widget_hide (service->no_ssl);
-#else
- gtk_widget_hide (service->ssl_hbox);
- gtk_widget_show (service->no_ssl);
-#endif
- } else {
- gtk_widget_hide (service->frame);
- gtk_widget_hide (service->auth_frame);
- gtk_widget_hide (service->ssl_frame);
- }
-
- /* Update the EConfigTarget so it has the latest CamelSettings. */
-
- config = E_CONFIG (service->emae->priv->config);
- target = (EMConfigTargetSettings *) config->target;
-
- em_config_target_update_settings (
- config, target,
- service->emae->priv->modified_account->id->address,
- service->emae->priv->source.protocol,
- service->emae->priv->source.settings,
- service->emae->priv->transport.protocol,
- service->emae->priv->transport.settings);
-}
-
-static void
-emae_provider_changed (GtkComboBox *combo_box,
- EMAccountEditorService *service)
-{
- const gchar *active_protocol;
-
- active_protocol = gtk_combo_box_get_active_id (combo_box);
-
- if (g_strcmp0 (active_protocol, service->protocol) == 0)
- return;
-
- service->protocol = active_protocol;
-
- switch (service->type) {
- case CAMEL_PROVIDER_STORE:
- g_object_notify (
- G_OBJECT (service->emae),
- "store-provider");
- break;
- case CAMEL_PROVIDER_TRANSPORT:
- g_object_notify (
- G_OBJECT (service->emae),
- "transport-provider");
- break;
- default:
- g_warn_if_reached ();
- }
-
- emae_service_provider_changed (service);
-
- e_config_target_changed (
- (EConfig *) service->emae->priv->config,
- E_CONFIG_TARGET_CHANGED_REBUILD);
-}
-
-static void
-emae_refresh_providers (EMAccountEditor *emae,
- EMAccountEditorService *service)
-{
- GtkComboBoxText *combo_box;
- GList *link;
-
- combo_box = GTK_COMBO_BOX_TEXT (service->providers);
-
- g_signal_handlers_block_by_func (
- combo_box, emae_provider_changed, service);
-
- gtk_combo_box_text_remove_all (combo_box);
-
- for (link = emae->priv->providers; link != NULL; link = link->next) {
- CamelProvider *provider = link->data;
-
- /* FIXME This expression is awesomely unreadable! */
- if (!(provider->object_types[service->type]
- && (service->type != CAMEL_PROVIDER_STORE ||
- (provider->flags & CAMEL_PROVIDER_IS_SOURCE) != 0))
- /* hardcode not showing providers who's transport is done in the store */
- || (service->type == CAMEL_PROVIDER_TRANSPORT
- && CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)))
- continue;
-
- gtk_combo_box_text_append (
- combo_box,
- provider->protocol,
- provider->name);
- }
-
- g_signal_handlers_unblock_by_func (
- combo_box, emae_provider_changed, service);
-
- gtk_combo_box_set_active_id (
- GTK_COMBO_BOX (combo_box), service->protocol);
-
- /* make sure at least something is selected;
- * this applies for cases when user changed from provider which was
- * store and transport together, to a store provider only (like from
- * exchange to imap provider), which left unselected transport type
- */
- if (gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box)) == -1)
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
-}
-
-static void
-emae_authtype_changed (GtkComboBox *combo_box,
- EMAccountEditorService *service)
-{
- CamelServiceAuthType *authtype = NULL;
- const gchar *mechanism;
- gboolean sensitive = FALSE;
-
- mechanism = gtk_combo_box_get_active_id (combo_box);
-
- if (mechanism != NULL && *mechanism != '\0') {
- authtype = camel_sasl_authtype (mechanism);
- g_warn_if_fail (authtype != NULL);
- }
-
- sensitive = (authtype == NULL) || (authtype->need_password);
- gtk_widget_set_sensitive (GTK_WIDGET (service->remember), sensitive);
-}
-
-static void emae_check_authtype (GtkWidget *w, EMAccountEditorService *service);
-
-static void
-emae_check_authtype_done (CamelService *camel_service,
- GAsyncResult *result,
- EMAccountEditorService *service)
-{
- EMailBackend *backend;
- EMailSession *session;
- GtkWidget *editor;
- GList *available_authtypes;
- GError *error = NULL;
-
- available_authtypes = camel_service_query_auth_types_finish (
- camel_service, result, &error);
-
- editor = NULL;
- if (service->emae && service->emae->config && E_IS_CONFIG (service->emae->config))
- editor = E_CONFIG (service->emae->config)->window;
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_warn_if_fail (available_authtypes == NULL);
- g_error_free (error);
-
- } else if (error != NULL) {
- g_warn_if_fail (available_authtypes == NULL);
- if (service->check_dialog)
- e_alert_run_dialog_for_args (
- GTK_WINDOW (service->check_dialog),
- "mail:checking-service-error",
- error->message, NULL);
- g_error_free (error);
-
- } else {
- e_auth_combo_box_update_available (
- E_AUTH_COMBO_BOX (service->authtype),
- available_authtypes);
- g_list_free (available_authtypes);
- }
-
- if (service->check_dialog) {
- g_object_weak_unref (G_OBJECT (service->check_dialog), (GWeakNotify) g_nullify_pointer, &service->check_dialog);
- gtk_widget_destroy (service->check_dialog);
- }
- service->check_dialog = NULL;
-
- if (editor != NULL)
- gtk_widget_set_sensitive (editor, TRUE);
-
- backend = em_account_editor_get_backend (service->emae);
- session = e_mail_backend_get_session (backend);
-
- /* drop the temporary CamelService */
- camel_session_remove_service (
- CAMEL_SESSION (session), camel_service);
-
- g_object_unref (service->emae);
-}
-
-static void
-emae_check_authtype_response (GtkDialog *dialog,
- gint button,
- GCancellable *cancellable)
-{
- g_cancellable_cancel (cancellable);
-}
-
-static void
-emae_check_authtype (GtkWidget *w,
- EMAccountEditorService *service)
-{
- CamelService *camel_service;
- EMailBackend *backend;
- EMailSession *session;
- GtkWidget *editor;
- gpointer parent;
- gchar *uid;
- GError *error = NULL;
-
- editor = E_CONFIG (service->emae->config)->window;
-
- backend = em_account_editor_get_backend (service->emae);
- session = e_mail_backend_get_session (backend);
-
- uid = g_strdup_printf ("emae-check-authtype-%p", service);
-
- /* to test on actual data, not on previously used */
- camel_service = camel_session_add_service (
- CAMEL_SESSION (session), uid,
- service->protocol, service->type, &error);
-
- g_free (uid);
-
- if (camel_service != NULL && service->settings != NULL)
- camel_service_set_settings (camel_service, service->settings);
-
- if (editor != NULL)
- parent = gtk_widget_get_toplevel (editor);
- else
- parent = gtk_widget_get_toplevel (w);
-
- if (error) {
- e_alert_run_dialog_for_args (
- parent, "mail:checking-service-error",
- error->message, NULL);
- g_clear_error (&error);
- return;
- }
-
- g_return_if_fail (CAMEL_IS_SERVICE (camel_service));
-
- if (service->checking != NULL) {
- g_cancellable_cancel (service->checking);
- g_object_unref (service->checking);
- }
-
- service->checking = g_cancellable_new ();
-
- service->check_dialog = e_alert_dialog_new_for_args (
- parent, "mail:checking-service", NULL);
- g_object_weak_ref (G_OBJECT (service->check_dialog), (GWeakNotify) g_nullify_pointer, &service->check_dialog);
-
- g_object_ref (service->emae);
-
- camel_service_query_auth_types (
- camel_service, G_PRIORITY_DEFAULT,
- service->checking, (GAsyncReadyCallback)
- emae_check_authtype_done, service);
-
- g_signal_connect (
- service->check_dialog, "response",
- G_CALLBACK (emae_check_authtype_response),
- service->checking);
-
- gtk_widget_show (service->check_dialog);
-
- if (editor != NULL)
- gtk_widget_set_sensitive (editor, FALSE);
-}
-
-static void
-emae_setup_service (EMAccountEditor *emae,
- EMAccountEditorService *service,
- GtkBuilder *builder)
-{
- struct _service_info *info = &emae_service_info[service->type];
- gboolean requires_auth;
- CamelProvider *provider = NULL;
- CamelURL *url;
-
- url = emae_account_url (emae, info->account_uri_key);
-
- if (!service->protocol) {
- /* GtkComboBox internalizes ID strings, which for the provider
- * combo box are protocol names. So we'll do the same here. */
- if (url != NULL && url->protocol != NULL)
- service->protocol = g_intern_string (url->protocol);
-
- if (!service->protocol)
- service->protocol = "none";
- }
-
- requires_auth = url && url->authmech != NULL;
-
- camel_url_free (url);
-
- if (service->protocol != NULL)
- provider = camel_provider_get (service->protocol, NULL);
-
- /* Extract all widgets we need from the builder file. */
-
- service->frame = e_builder_get_widget (builder, info->frame);
- service->container = e_builder_get_widget (builder, info->container);
- service->description = GTK_LABEL (e_builder_get_widget (builder, info->description));
- service->hostname = GTK_ENTRY (e_builder_get_widget (builder, info->hostname));
- service->hostlabel = (GtkLabel *) e_builder_get_widget (builder, info->hostlabel);
- service->port = E_PORT_ENTRY (e_builder_get_widget (builder, info->port));
- service->portlabel = (GtkLabel *) e_builder_get_widget (builder, info->portlabel);
- service->username = GTK_ENTRY (e_builder_get_widget (builder, info->username));
- service->userlabel = (GtkLabel *) e_builder_get_widget (builder, info->userlabel);
- if (info->pathentry) {
- service->pathlabel = (GtkLabel *) e_builder_get_widget (builder, info->pathlabel);
- service->pathentry = e_builder_get_widget (builder, info->pathentry);
- }
-
- service->ssl_frame = e_builder_get_widget (builder, info->security_frame);
- gtk_widget_hide (service->ssl_frame);
- service->ssl_hbox = e_builder_get_widget (builder, info->ssl_hbox);
- service->use_ssl = (GtkComboBox *) e_builder_get_widget (builder, info->use_ssl);
- service->no_ssl = e_builder_get_widget (builder, info->ssl_disabled);
-
- service->auth_frame = e_builder_get_widget (builder, info->auth_frame);
- service->check_supported = (GtkButton *) e_builder_get_widget (builder, info->authtype_check);
- service->authtype = (GtkComboBox *) e_builder_get_widget (builder, info->authtype);
- service->providers = (GtkComboBox *) e_builder_get_widget (builder, info->type_dropdown);
-
- /* XXX GtkComboBoxText, when loaded from a GtkBuilder file,
- * needs further manual configuration to be fully usable.
- * Particularly the ID column has to be set explicitly.
- * https://bugzilla.gnome.org/show_bug.cgi?id=612396#c53 */
- g_object_set (
- service->providers,
- "entry-text-column", 0,
- "id-column", 1, NULL);
-
- service->remember = emae_account_toggle (emae, info->remember_password, info->save_passwd_key, builder);
-
- if (info->needs_auth) {
- service->needs_auth = (GtkToggleButton *) e_builder_get_widget (builder, info->needs_auth);
- } else {
- service->needs_auth = NULL;
- }
-
- g_signal_connect (
- service->providers, "changed",
- G_CALLBACK (emae_provider_changed), service);
-
- if (GTK_IS_FILE_CHOOSER (service->pathentry))
- g_signal_connect (
- service->pathentry, "selection-changed",
- G_CALLBACK (emae_file_chooser_changed), service);
-
- g_signal_connect (
- service->authtype, "changed",
- G_CALLBACK (emae_authtype_changed), service);
-
- g_signal_connect (
- service->check_supported, "clicked",
- G_CALLBACK (emae_check_authtype), service);
-
- switch (service->type) {
- case CAMEL_PROVIDER_STORE:
- g_object_bind_property (
- emae, "store-provider",
- service->authtype, "provider",
- G_BINDING_SYNC_CREATE);
-
- if (service->needs_auth != NULL) {
- g_object_set (emae, "store-requires-auth", requires_auth, NULL);
- g_object_bind_property (
- emae, "store-requires-auth",
- service->needs_auth, "active",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (
- emae, "store-requires-auth",
- service->auth_frame, "sensitive",
- G_BINDING_SYNC_CREATE);
- }
-
- g_object_bind_property (
- emae, "store-visible-auth",
- service->auth_frame, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-host",
- service->hostname, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-host",
- service->hostlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-path",
- service->pathentry, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-path",
- service->pathlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-port",
- service->port, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-port",
- service->portlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-user",
- service->username, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "store-visible-user",
- service->userlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- break;
-
- case CAMEL_PROVIDER_TRANSPORT:
- g_object_bind_property (
- emae, "transport-provider",
- service->authtype, "provider",
- G_BINDING_SYNC_CREATE);
-
- if (service->needs_auth != NULL) {
- g_object_set (emae, "transport-requires-auth", requires_auth, NULL);
- g_object_bind_property (
- emae, "transport-requires-auth",
- service->needs_auth, "active",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (
- emae, "transport-requires-auth",
- service->auth_frame, "sensitive",
- G_BINDING_SYNC_CREATE);
- }
-
- g_object_bind_property (
- emae, "transport-visible-auth",
- service->auth_frame, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "transport-visible-host",
- service->hostname, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "transport-visible-host",
- service->hostlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "transport-visible-port",
- service->port, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "transport-visible-port",
- service->portlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "transport-visible-user",
- service->username, "visible",
- G_BINDING_SYNC_CREATE);
-
- g_object_bind_property (
- emae, "transport-visible-user",
- service->userlabel, "visible",
- G_BINDING_SYNC_CREATE);
-
- break;
-
- default:
- g_warn_if_reached ();
- }
-
- if (service->pathentry) {
- GtkFileChooserAction action;
- gboolean need_path_dir;
- const gchar *label;
-
- need_path_dir =
- (provider == NULL) ||
- ((provider->url_flags & CAMEL_URL_NEED_PATH_DIR) != 0);
-
- if (need_path_dir) {
- action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
- label = _("_Path:");
- } else {
- action = GTK_FILE_CHOOSER_ACTION_OPEN;
- label = _("Fil_e:");
- }
-
- if (service->pathlabel)
- gtk_label_set_text_with_mnemonic (
- GTK_LABEL (service->pathlabel), label);
-
- if (action != gtk_file_chooser_get_action (GTK_FILE_CHOOSER (service->pathentry)))
- gtk_file_chooser_set_action (GTK_FILE_CHOOSER (service->pathentry), action);
- }
-
- /* old authtype will be destroyed when we exit */
- emae_refresh_providers (emae, service);
-
- if (provider != NULL && provider->port_entries) {
- e_port_entry_set_camel_entries (
- service->port, provider->port_entries);
-
- /* update also port in settings, because it's not bind yet */
- if (service->settings && CAMEL_IS_NETWORK_SETTINGS (service->settings)) {
- camel_network_settings_set_port (
- CAMEL_NETWORK_SETTINGS (service->settings),
- e_port_entry_get_port (service->port));
- }
- }
-
- emae_service_provider_changed (service);
-}
-
-static GtkWidget *
-emae_create_basic_assistant_page (EMAccountEditor *emae,
- GtkAssistant *assistant,
- const gchar *page_id,
- gint position)
-{
- const gchar *title = NULL, *label = NULL;
- GtkAssistantPageType page_type = GTK_ASSISTANT_PAGE_CONTENT;
- GtkWidget *vbox, *lbl;
- gboolean fill_space = FALSE;
-
- g_return_val_if_fail (page_id != NULL, NULL);
-
- if (g_ascii_strcasecmp (page_id, "start_page") == 0) {
- page_type = GTK_ASSISTANT_PAGE_INTRO;
- fill_space = TRUE;
- title = _("Mail Configuration");
- label = _("Welcome to the Evolution Mail Configuration Assistant.\n\nClick \"Continue\" to begin.");
- } else if (g_ascii_strcasecmp (page_id, "identity_page") == 0) {
- title = _("Identity");
- label = _("Please enter your name and email address below. The \"optional\" fields below do not need to be filled in, unless you wish to include this information in email you send.");
- } else if (g_ascii_strcasecmp (page_id, "source_page") == 0) {
- title = _("Receiving Email");
- label = _("Please configure the following account settings.");
- } else if (g_ascii_strcasecmp (page_id, "transport_page") == 0) {
- title = _("Sending Email");
- label = _("Please enter information about the way you will send mail. If you are not sure, ask your system administrator or Internet Service Provider.");
- } else if (g_ascii_strcasecmp (page_id, "review_page") == 0) {
- title = _("Account Summary");
- label = _("This is a summary of the settings which will be used to access your mail.");
- } else if (g_ascii_strcasecmp (page_id, "finish_page") == 0) {
- page_type = GTK_ASSISTANT_PAGE_CONFIRM;
- fill_space = TRUE;
- title = _("Done");
- label = _("Congratulations, your mail configuration is complete.\n\nYou are now ready to send and receive email using Evolution.\n\nClick \"Apply\" to save your settings.");
- } else {
- g_return_val_if_reached (NULL);
- }
-
- vbox = gtk_vbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
- gtk_widget_show (vbox);
-
- lbl = gtk_label_new (label);
- gtk_label_set_line_wrap (GTK_LABEL (lbl), TRUE);
- gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (vbox), lbl, fill_space, fill_space, 0);
- gtk_widget_show (lbl);
-
- if (g_ascii_strcasecmp (page_id, "start_page") == 0)
- g_hash_table_insert (emae->priv->widgets, (gchar *)"start_page_label", lbl);
-
- gtk_assistant_insert_page (assistant, vbox, position);
- gtk_assistant_set_page_title (assistant, vbox, title);
- gtk_assistant_set_page_type (assistant, vbox, page_type);
-
- return vbox;
-}
-
-/* do not re-order these, the order is used by various code to look up emae->priv->identity_entries[] */
-static struct {
- const gchar *name;
- gint item;
-} emae_identity_entries[] = {
- { "management_name", E_ACCOUNT_NAME },
- { "identity_full_name", E_ACCOUNT_ID_NAME },
- { "identity_address", E_ACCOUNT_ID_ADDRESS },
- { "identity_reply_to", E_ACCOUNT_ID_REPLY_TO },
- { "identity_organization", E_ACCOUNT_ID_ORGANIZATION },
-};
-
-static void
-emae_queue_widgets (EMAccountEditor *emae,
- GtkBuilder *builder,
- const gchar *first,
- ...)
-{
- va_list ap;
-
- va_start (ap, first);
- while (first) {
- g_hash_table_insert (emae->priv->widgets, (gchar *) first, e_builder_get_widget (builder, first));
- first = va_arg (ap, const gchar *);
- }
- va_end (ap);
-}
-
-static GtkWidget *
-emae_identity_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EMAccountEditorPrivate *priv = emae->priv;
- EAccount *account;
- gint i;
- GtkWidget *w;
- GtkBuilder *builder;
-
- if (old && emae->type == EMAE_PAGES)
- return old;
-
- account = em_account_editor_get_modified_account (emae);
-
- /* Make sure our custom widget classes are registered with
- * GType before we load the GtkBuilder definition file. */
- E_TYPE_MAIL_JUNK_OPTIONS;
- EM_TYPE_FOLDER_SELECTION_BUTTON;
-
- builder = gtk_builder_new ();
- e_load_ui_builder_definition (builder, "mail-config.ui");
-
- /* Management & Identity fields, in the assistant the management frame is relocated to the last page later on */
- for (i = 0; i < G_N_ELEMENTS (emae_identity_entries); i++)
- priv->identity_entries[i] = emae_account_entry (emae, emae_identity_entries[i].name, emae_identity_entries[i].item, builder);
-
- priv->management_frame = e_builder_get_widget (builder, "management-section");
-
- priv->default_account = GTK_TOGGLE_BUTTON (e_builder_get_widget (builder, "management_default"));
- if (!e_get_default_account ()
- || (account == e_get_default_account ())
- || (GPOINTER_TO_INT(g_object_get_data (G_OBJECT (account), "default_flagged"))) )
- gtk_toggle_button_set_active (priv->default_account, TRUE);
-
- if (emae->do_signature) {
- emae_setup_signatures (emae, builder);
- } else {
- /* TODO: this could/should probably be neater */
- gtk_widget_hide (e_builder_get_widget (builder, "sigLabel"));
-#if 0
- gtk_widget_hide (e_builder_get_widget (builder, "sigOption"));
-#endif
- gtk_widget_hide (e_builder_get_widget (builder, "signature_dropdown"));
- gtk_widget_hide (e_builder_get_widget (builder, "sigAddNew"));
- }
-
- w = e_builder_get_widget (builder, item->label);
- if (emae->type == EMAE_PAGES) {
- GtkWidget *page = emae_create_basic_assistant_page (emae, GTK_ASSISTANT (parent), "identity_page", position);
-
- gtk_box_pack_start ((GtkBox *) emae->pages[0], w, TRUE, TRUE, 0);
- w = page;
- } else if (((EConfig *) priv->config)->type == E_CONFIG_ASSISTANT) {
- GtkWidget *page;
-
- page = emae_create_basic_assistant_page (
- emae, GTK_ASSISTANT (parent),
- "identity_page", position);
-
- gtk_box_pack_start (GTK_BOX (page), w, TRUE, TRUE, 0);
-
- w = page;
- } else {
- gtk_notebook_insert_page (
- GTK_NOTEBOOK (parent), w,
- gtk_label_new (_("Identity")),
- position);
- gtk_container_child_set (
- GTK_CONTAINER (parent), w,
- "tab-fill", FALSE, "tab-expand", FALSE, NULL);
- }
-
- emae_queue_widgets (
- emae, builder,
- "account_vbox",
- "identity-required-table",
- "identity-optional-table",
- "identity-optional-section",
- "identity_address",
- NULL);
-
- g_object_unref (builder);
-
- return w;
-}
-
-static GtkWidget *
-emae_receive_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EMAccountEditorPrivate *priv = emae->priv;
- GtkWidget *w;
- GtkBuilder *builder;
-
- /*if (old)
- return old;*/
-
- builder = gtk_builder_new ();
- e_load_ui_builder_definition (builder, "mail-config.ui");
-
- priv->source.type = CAMEL_PROVIDER_STORE;
- emae_setup_service (emae, &priv->source, builder);
-
- w = e_builder_get_widget (builder, item->label);
- if (emae->type == EMAE_PAGES) {
- GtkWidget *page = emae_create_basic_assistant_page (emae, GTK_ASSISTANT (parent), "source_page", position);
- GtkWidget *vbox, *child;
-
- child = (GtkWidget *)g_object_get_data ((GObject *)emae->pages[1], "old-child");
- if (child)
- gtk_container_remove ((GtkContainer *) emae->pages[1], child);
-
- vbox = gtk_vbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
- gtk_widget_show (vbox);
- gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0);
- g_object_set_data ((GObject *)emae->pages[1], "old-child", vbox);
- gtk_box_pack_start ((GtkBox *) emae->pages[1], vbox, TRUE, TRUE, 0);
-
- w = page;
- } else if (((EConfig *) priv->config)->type == E_CONFIG_ASSISTANT) {
- GtkWidget *page;
-
- page = emae_create_basic_assistant_page (
- emae, GTK_ASSISTANT (parent),
- "source_page", position);
-
- gtk_box_pack_start (GTK_BOX (page), w, TRUE, TRUE, 0);
-
- w = page;
- } else {
- gtk_notebook_insert_page (
- GTK_NOTEBOOK (parent), w,
- gtk_label_new (_("Receiving Email")),
- position);
- gtk_container_child_set (
- GTK_CONTAINER (parent), w,
- "tab-fill", FALSE, "tab-expand", FALSE, NULL);
- }
-
- emae_queue_widgets (
- emae, builder,
- "source-type-table",
- "source-config-table",
- "source-security-vbox",
- "source-auth-vbox",
- NULL);
-
- g_object_unref (builder);
-
- return w;
-}
-
-static void
-emae_set_option_dependency (EMAccountEditorService *service,
- CamelProviderConfEntry *conf,
- GtkWidget *widget)
-{
- if (conf->depname != NULL) {
- const gchar *depname = conf->depname;
-
- if (*depname == '!')
- depname++;
-
- g_object_bind_property (
- service->settings, depname,
- widget, "sensitive",
- G_BINDING_SYNC_CREATE |
- (depname == conf->depname ? 0 : G_BINDING_INVERT_BOOLEAN));
- gtk_widget_set_margin_left (widget, INDENT_MARGIN);
- }
-}
-
-static GtkWidget *
-emae_option_toggle (EMAccountEditorService *service,
- CamelProviderConfEntry *conf)
-{
- GtkWidget *widget;
-
- widget = gtk_check_button_new_with_mnemonic (conf->text);
-
- g_object_bind_property (
- service->settings, conf->name,
- widget, "active",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- emae_set_option_dependency (service, conf, widget);
-
- return widget;
-}
-
-static GtkWidget *
-emae_option_entry (EMAccountEditorService *service,
- CamelProviderConfEntry *conf,
- GtkLabel *label_for_mnemonic)
-{
- GtkWidget *widget;
-
- widget = gtk_entry_new ();
- gtk_label_set_mnemonic_widget (label_for_mnemonic, widget);
-
- g_object_bind_property (
- service->settings, conf->name,
- widget, "text",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- emae_set_option_dependency (service, conf, widget);
-
- g_object_bind_property (
- widget, "sensitive",
- label_for_mnemonic, "sensitive",
- G_BINDING_SYNC_CREATE);
-
- return widget;
-}
-
-static GtkWidget *
-emae_option_checkspin (EMAccountEditorService *service,
- CamelProviderConfEntry *conf)
-{
- GObjectClass *class;
- GParamSpec *pspec;
- GParamSpec *use_pspec;
- GtkAdjustment *adjustment;
- GtkWidget *hbox, *spin;
- GtkWidget *prefix;
- gchar *use_property_name;
- gchar *pre, *post;
-
- /* The conf->name property (e.g. "foo") should be numeric for the
- * spin button. If a "use" boolean property exists (e.g. "use-foo")
- * then a checkbox is also shown. */
-
- g_return_val_if_fail (conf->name != NULL, NULL);
-
- class = G_OBJECT_GET_CLASS (service->settings);
- pspec = g_object_class_find_property (class, conf->name);
- g_return_val_if_fail (pspec != NULL, NULL);
-
- use_property_name = g_strconcat ("use-", conf->name, NULL);
- use_pspec = g_object_class_find_property (class, use_property_name);
- if (use_pspec != NULL && use_pspec->value_type != G_TYPE_BOOLEAN)
- use_pspec = NULL;
- g_free (use_property_name);
-
- /* Make sure we can convert to and from doubles. */
- g_return_val_if_fail (
- g_value_type_transformable (
- pspec->value_type, G_TYPE_DOUBLE), NULL);
- g_return_val_if_fail (
- g_value_type_transformable (
- G_TYPE_DOUBLE, pspec->value_type), NULL);
-
- if (G_IS_PARAM_SPEC_CHAR (pspec)) {
- GParamSpecChar *pspec_char;
- pspec_char = G_PARAM_SPEC_CHAR (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_char->default_value,
- (gdouble) pspec_char->minimum,
- (gdouble) pspec_char->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_UCHAR (pspec)) {
- GParamSpecUChar *pspec_uchar;
- pspec_uchar = G_PARAM_SPEC_UCHAR (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_uchar->default_value,
- (gdouble) pspec_uchar->minimum,
- (gdouble) pspec_uchar->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_INT (pspec)) {
- GParamSpecInt *pspec_int;
- pspec_int = G_PARAM_SPEC_INT (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_int->default_value,
- (gdouble) pspec_int->minimum,
- (gdouble) pspec_int->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_UINT (pspec)) {
- GParamSpecUInt *pspec_uint;
- pspec_uint = G_PARAM_SPEC_UINT (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_uint->default_value,
- (gdouble) pspec_uint->minimum,
- (gdouble) pspec_uint->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_LONG (pspec)) {
- GParamSpecLong *pspec_long;
- pspec_long = G_PARAM_SPEC_LONG (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_long->default_value,
- (gdouble) pspec_long->minimum,
- (gdouble) pspec_long->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_ULONG (pspec)) {
- GParamSpecULong *pspec_ulong;
- pspec_ulong = G_PARAM_SPEC_ULONG (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_ulong->default_value,
- (gdouble) pspec_ulong->minimum,
- (gdouble) pspec_ulong->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_FLOAT (pspec)) {
- GParamSpecFloat *pspec_float;
- pspec_float = G_PARAM_SPEC_FLOAT (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_float->default_value,
- (gdouble) pspec_float->minimum,
- (gdouble) pspec_float->maximum,
- 1.0, 1.0, 0.0);
-
- } else if (G_IS_PARAM_SPEC_DOUBLE (pspec)) {
- GParamSpecDouble *pspec_double;
- pspec_double = G_PARAM_SPEC_DOUBLE (pspec);
- adjustment = gtk_adjustment_new (
- (gdouble) pspec_double->default_value,
- (gdouble) pspec_double->minimum,
- (gdouble) pspec_double->maximum,
- 1.0, 1.0, 0.0);
-
- } else
- g_return_val_if_reached (NULL);
-
- pre = g_alloca (strlen (conf->text) + 1);
- strcpy (pre, conf->text);
- post = strstr (pre, "%s");
- if (post != NULL) {
- *post = '\0';
- post += 2;
- }
-
- hbox = gtk_hbox_new (FALSE, 3);
-
- if (use_pspec != NULL) {
- prefix = gtk_check_button_new_with_mnemonic (pre);
-
- g_object_bind_property (
- service->settings, use_pspec->name,
- prefix, "active",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
- } else {
- prefix = gtk_label_new_with_mnemonic (pre);
- }
- gtk_box_pack_start (GTK_BOX (hbox), prefix, FALSE, TRUE, 0);
- gtk_widget_show (prefix);
-
- spin = gtk_spin_button_new (adjustment, 1.0, 0);
- gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, TRUE, 0);
- gtk_widget_show (spin);
-
- g_object_bind_property (
- service->settings, conf->name,
- spin, "value",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- if (use_pspec != NULL)
- g_object_bind_property (
- prefix, "active",
- spin, "sensitive",
- G_BINDING_SYNC_CREATE);
-
- if (post != NULL) {
- GtkWidget *label = gtk_label_new_with_mnemonic (post);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), prefix);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
- gtk_widget_show (label);
- }
-
- emae_set_option_dependency (service, conf, hbox);
-
- return hbox;
-}
-
-/* 'values' is in format "nick0:caption0:nick1:caption1:...nickN:captionN"
- * where 'nick' is the nickname of a GEnumValue belonging to a GEnumClass
- * determined by the type of the GObject property named "name". */
-static GtkWidget *
-emae_option_options (EMAccountEditorService *service,
- CamelProviderConfEntry *conf,
- GtkLabel *label)
-{
- CamelProvider *provider;
- GtkWidget *widget;
- GtkListStore *store;
- GtkTreeIter iter;
- const gchar *p;
- GtkCellRenderer *renderer;
-
- provider = camel_provider_get (service->protocol, NULL);
- g_return_val_if_fail (provider != NULL, NULL);
-
- /* nick and caption */
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
-
- p = conf->value;
- while (p != NULL) {
- const gchar *nick;
- const gchar *caption;
- gchar *vl, *cp;
-
- nick = p;
- caption = strchr (p, ':');
- if (caption) {
- caption++;
- } else {
- g_warning (G_STRLOC ": expected ':' not found at '%s'", p);
- break;
- }
- p = strchr (caption, ':');
-
- vl = g_strndup (nick, caption - nick - 1);
- if (p) {
- p++;
- cp = g_strndup (caption, p - caption - 1);
- } else
- cp = g_strdup (caption);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (
- store, &iter, 0, vl, 1, dgettext (
- provider->translation_domain, cp), -1);
-
- g_free (vl);
- g_free (cp);
- }
-
- widget = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
- gtk_combo_box_set_id_column (GTK_COMBO_BOX (widget), 0);
- gtk_widget_show (widget);
-
- g_object_bind_property_full (
- service->settings, conf->name,
- widget, "active-id",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE,
- e_binding_transform_enum_value_to_nick,
- e_binding_transform_enum_nick_to_value,
- NULL, (GDestroyNotify) NULL);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
- gtk_cell_layout_set_attributes (
- GTK_CELL_LAYOUT (widget), renderer, "text", 1, NULL);
-
- gtk_label_set_mnemonic_widget (label, widget);
-
- return widget;
-}
-
-static GtkWidget *
-emae_receive_options_item (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- CamelProvider *provider;
- GtkWidget *w, *box, *spin;
- guint row;
-
- provider = emae_get_store_provider (emae);
-
- if (provider == NULL || provider->extra_conf == NULL)
- return NULL;
-
- if (old) {
- if (emae->type == EMAE_PAGES) {
- GtkWidget *box = gtk_hbox_new (FALSE, 12);
- gtk_widget_reparent (old, box);
- gtk_widget_show (box);
- gtk_box_set_child_packing ((GtkBox *) box, old, TRUE, TRUE, 12, GTK_PACK_START);
- gtk_box_pack_end ((GtkBox *) emae->pages[2], box, FALSE, FALSE, 0);
- }
- return old;
- }
-
- if (emae->type == EMAE_PAGES) {
- GtkWidget *box = gtk_hbox_new (FALSE, 12);
- gtk_widget_reparent (parent, box);
- gtk_widget_show (box);
- gtk_box_set_child_packing ((GtkBox *) box, parent, TRUE, TRUE, 12, GTK_PACK_START);
- gtk_box_pack_start ((GtkBox *) emae->pages[2], box, FALSE, FALSE, 0);
- }
-
- /* We have to add the automatic mail check item with the rest of the receive options */
- g_object_get (parent, "n-rows", &row, NULL);
-
- box = gtk_hbox_new (FALSE, 4);
- w = gtk_check_button_new_with_mnemonic (_("Check for _new messages every"));
- emae_account_toggle_widget (emae, (GtkToggleButton *) w, E_ACCOUNT_SOURCE_AUTO_CHECK);
- gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0);
-
- spin = gtk_spin_button_new_with_range (1.0, 1440.0, 1.0);
- emae_account_spinint_widget (emae, (GtkSpinButton *) spin, E_ACCOUNT_SOURCE_AUTO_CHECK_TIME);
- gtk_box_pack_start ((GtkBox *) box, spin, FALSE, TRUE, 0);
-
- w = gtk_label_new_with_mnemonic (_("minu_tes"));
- gtk_label_set_mnemonic_widget (GTK_LABEL (w), spin);
- gtk_box_pack_start ((GtkBox *) box, w, FALSE, FALSE, 0);
-
- gtk_widget_show_all (box);
-
- gtk_table_attach ((GtkTable *) parent, box, 0, 2, row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
-
- return box;
-}
-
-static GtkWidget *
-emae_receive_options_extra_item (EConfig *ec,
- EConfigItem *eitem,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EMAccountEditorService *service;
- struct _receive_options_item *item = (struct _receive_options_item *) eitem;
- GtkWidget *box;
- GtkWidget *widget;
- GtkLabel *label;
- GtkTable *table;
- CamelProvider *provider;
- CamelProviderConfEntry *entries;
- guint row;
- GHashTable *extra;
- const gchar *section_name;
- gint ii;
-
- service = &emae->priv->source;
- section_name = eitem->user_data;
-
- provider = emae_get_store_provider (emae);
-
- if (provider == NULL || provider->extra_conf == NULL)
- return NULL;
-
- entries = provider->extra_conf;
-
- if (emae->type == EMAE_PAGES) {
- GtkWidget *box;
-
- box = gtk_hbox_new (FALSE, 12);
- gtk_widget_reparent (parent, box);
- gtk_widget_show (box);
- gtk_box_set_child_packing (
- GTK_BOX (box), parent,
- TRUE, TRUE, 12, GTK_PACK_START);
- gtk_box_pack_start (
- GTK_BOX (emae->pages[2]), box, FALSE, FALSE, 0);
- }
-
- for (ii = 0; entries && entries[ii].type != CAMEL_PROVIDER_CONF_END; ii++)
- if (entries[ii].type == CAMEL_PROVIDER_CONF_SECTION_START
- && g_strcmp0 (entries[ii].name, section_name) == 0)
- goto section;
-
- return NULL;
-
-section:
- d (printf ("Building extra section '%s'\n", eitem->path));
- widget = NULL;
- item->extra_table = g_hash_table_new (g_str_hash, g_str_equal);
- extra = g_hash_table_new (g_str_hash, g_str_equal);
-
- table = GTK_TABLE (parent);
- g_object_get (table, "n-rows", &row, NULL);
-
- for (; entries[ii].type != CAMEL_PROVIDER_CONF_END && entries[ii].type != CAMEL_PROVIDER_CONF_SECTION_END; ii++) {
- switch (entries[ii].type) {
- case CAMEL_PROVIDER_CONF_SECTION_START:
- case CAMEL_PROVIDER_CONF_SECTION_END:
- break;
-
- case CAMEL_PROVIDER_CONF_LABEL:
- /* FIXME This is a hack for exchange connector,
- * labels should be removed from confentry. */
- if (!strcmp (entries[ii].name, "hostname"))
- label = emae->priv->source.hostlabel;
- else if (!strcmp (entries[ii].name, "username"))
- label = emae->priv->source.userlabel;
- else
- label = NULL;
-
- if (label != NULL)
- gtk_label_set_text_with_mnemonic (
- label, entries[ii].text);
- break;
-
- case CAMEL_PROVIDER_CONF_CHECKBOX:
- widget = emae_option_toggle (service, &entries[ii]);
- gtk_table_attach (
- table, widget, 0, 2,
- row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- gtk_widget_show (widget);
-
- g_hash_table_insert (
- extra, (gpointer) entries[ii].name, widget);
-
- row++;
-
- /* HACK: keep_on_server is stored in the e-account,
- * but is displayed as a properly on the uri, make
- * sure they track/match here. */
- if (strcmp (entries[ii].name, "keep-on-server") == 0)
- emae_account_toggle_widget (
- emae, (GtkToggleButton *) widget,
- E_ACCOUNT_SOURCE_KEEP_ON_SERVER);
- break;
-
- case CAMEL_PROVIDER_CONF_ENTRY:
- widget = gtk_label_new_with_mnemonic (entries[ii].text);
- gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
- gtk_table_attach (
- table, widget, 0, 1,
- row, row + 1, GTK_FILL, 0, 0, 0);
- gtk_widget_show (widget);
-
- label = GTK_LABEL (widget);
-
- widget = emae_option_entry (
- service, &entries[ii], label);
- gtk_table_attach (
- table, widget, 1, 2,
- row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- gtk_widget_show (widget);
-
- row++;
-
- /* FIXME This is another hack for
- * exchange/groupwise connector. */
- g_hash_table_insert (
- item->extra_table,
- (gpointer) entries[ii].name, widget);
- break;
-
- case CAMEL_PROVIDER_CONF_CHECKSPIN:
- widget = emae_option_checkspin (service, &entries[ii]);
- gtk_table_attach (
- table, widget, 0, 2,
- row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- gtk_widget_show (widget);
- row++;
- break;
-
- case CAMEL_PROVIDER_CONF_OPTIONS:
- box = gtk_hbox_new (FALSE, 4);
- gtk_table_attach (
- table, box, 0, 2,
- row, row + 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- gtk_widget_show (box);
-
- widget = gtk_label_new_with_mnemonic (entries[ii].text);
- gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
- gtk_box_pack_start (
- GTK_BOX (box), widget, FALSE, FALSE, 0);
- gtk_widget_show (widget);
-
- label = GTK_LABEL (widget);
-
- widget = emae_option_options (
- service, &entries[ii], label);
- gtk_box_pack_start (
- GTK_BOX (box), widget, FALSE, FALSE, 0);
- gtk_widget_show (widget);
-
- row++;
- break;
-
- default:
- break;
- }
- }
-
- if (widget != NULL)
- gtk_widget_show (widget);
-
- return widget;
-}
-
-static GtkWidget *
-emae_send_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EMAccountEditorPrivate *priv = emae->priv;
- CamelProvider *provider;
- GtkWidget *w;
- GtkBuilder *builder;
-
- provider = emae_get_store_provider (emae);
-
- /* no transport options page at all for these types of providers */
- if (provider && CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) {
- memset (&priv->transport.frame, 0, ((gchar *) &priv->transport.check_dialog) - ((gchar *) &priv->transport.frame));
- priv->transport.protocol = provider->protocol;
- return NULL;
- }
-
- builder = gtk_builder_new ();
- e_load_ui_builder_definition (builder, "mail-config.ui");
-
- /* Transport */
- priv->transport.type = CAMEL_PROVIDER_TRANSPORT;
- emae_setup_service (emae, &priv->transport, builder);
-
- w = e_builder_get_widget (builder, item->label);
- if (emae->type == EMAE_PAGES) {
- GtkWidget *page = emae_create_basic_assistant_page (emae, GTK_ASSISTANT (parent), "transport_page", position);
- GtkWidget *vbox, *child;
-
- child = (GtkWidget *)g_object_get_data ((GObject *)emae->pages[3], "old-child");
- if (child)
- gtk_container_remove ((GtkContainer *) emae->pages[3], child);
-
- vbox = gtk_vbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
- gtk_widget_show (vbox);
- gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0);
- g_object_set_data ((GObject *)emae->pages[3], "old-child", vbox);
-
- gtk_box_pack_start ((GtkBox *) emae->pages[3], vbox, TRUE, TRUE, 0);
-
- w = page;
- } else if (((EConfig *) priv->config)->type == E_CONFIG_ASSISTANT) {
- GtkWidget *page;
-
- page = emae_create_basic_assistant_page (
- emae, GTK_ASSISTANT (parent),
- "transport_page", position);
-
- gtk_box_pack_start (GTK_BOX (page), w, TRUE, TRUE, 0);
-
- w = page;
- } else {
- gtk_notebook_insert_page (
- GTK_NOTEBOOK (parent), w,
- gtk_label_new (_("Sending Email")),
- position);
- gtk_container_child_set (
- GTK_CONTAINER (parent), w,
- "tab-fill", FALSE, "tab-expand", FALSE, NULL);
- }
-
- emae_queue_widgets (
- emae, builder,
- "transport-type-table",
- "transport-server-table",
- "transport-security-table",
- "transport-auth-table",
- NULL);
-
- g_object_unref (builder);
-
- return w;
-}
-
-static void
-emae_real_url_toggled (GtkToggleButton *check,
- EMFolderSelectionButton *button)
-{
- if (!gtk_toggle_button_get_active (check))
- em_folder_selection_button_set_folder_uri (button, "");
-}
-
-static void
-set_real_folder_path (GtkButton *folder_button,
- CamelSettings *settings,
- const gchar *settings_prop,
- EAccount *account)
-{
- gchar *path = NULL, *uri;
- gchar *encoded_name;
- gchar *encoded_uid;
- const gchar *folder_name;
-
- g_return_if_fail (folder_button != NULL);
- g_return_if_fail (settings != NULL);
- g_return_if_fail (settings_prop != NULL);
- g_return_if_fail (account != NULL);
-
- g_object_get (G_OBJECT (settings), settings_prop, &path, NULL);
-
- if (!path || !*path) {
- g_free (path);
- return;
- }
-
- folder_name = path;
-
- /* Skip the leading slash, if present. */
- if (*folder_name == '/')
- folder_name++;
-
- encoded_uid = camel_url_encode (account->uid, ":;@/");
- encoded_name = camel_url_encode (folder_name, "#");
-
- uri = g_strdup_printf ("folder://%s/%s", encoded_uid, encoded_name);
-
- g_free (encoded_uid);
- g_free (encoded_name);
- g_free (path);
-
- em_folder_selection_button_set_folder_uri (EM_FOLDER_SELECTION_BUTTON (folder_button), uri);
-
- g_free (uri);
-}
-
-static void
-update_real_folder_cb (GtkButton *folder_button,
- GParamSpec *par_spec,
- EMAccountEditor *emae)
-{
- EMFolderSelectionButton *sel_button;
- CamelSettings *settings;
- const gchar *prop_name = NULL;
- const gchar *folder_uri;
- gchar *path = NULL;
-
- g_return_if_fail (folder_button != NULL);
- g_return_if_fail (emae != NULL);
- g_return_if_fail (emae->priv != NULL);
-
- settings = emae->priv->source.settings;
- if (folder_button == emae->priv->trash_folder_button)
- prop_name = "real-trash-path";
- else if (folder_button == emae->priv->junk_folder_button)
- prop_name = "real-junk-path";
-
- g_return_if_fail (prop_name != NULL);
-
- sel_button = EM_FOLDER_SELECTION_BUTTON (folder_button);
- g_return_if_fail (sel_button != NULL);
-
- folder_uri = em_folder_selection_button_get_folder_uri (sel_button);
- if (folder_uri && *folder_uri) {
- EMailSession *session;
-
- session = em_folder_selection_button_get_session (sel_button);
- if (!e_mail_folder_uri_parse (CAMEL_SESSION (session), folder_uri, NULL, &path, NULL))
- path = NULL;
- }
-
- g_object_set (G_OBJECT (settings), prop_name, path, NULL);
- g_free (path);
-}
-
-static GtkWidget *
-emae_defaults_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EMAccountEditorPrivate *priv = emae->priv;
- EMFolderSelectionButton *button;
- CamelProviderFlags flags;
- CamelProvider *provider;
- CamelSettings *settings;
- CamelStore *store = NULL;
- EMailBackend *backend;
- EMailSession *session;
- EAccount *account;
- GtkWidget *widget;
- GtkBuilder *builder;
- GParamSpec *pspec;
- gboolean visible;
-
- /*if (old)
- return old;*/
- if (((EConfig *) priv->config)->type == E_CONFIG_ASSISTANT && emae->type != EMAE_PAGES)
- return NULL;
-
- account = em_account_editor_get_modified_account (emae);
- backend = em_account_editor_get_backend (emae);
-
- session = e_mail_backend_get_session (backend);
-
- if (account != NULL) {
- CamelService *service;
-
- service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
-
- if (CAMEL_IS_STORE (service))
- store = CAMEL_STORE (service);
- }
-
- provider = emae_get_store_provider (emae);
- settings = emae->priv->source.settings;
-
- /* Make sure we have a valid EMailBackend. */
- g_return_val_if_fail (E_IS_MAIL_BACKEND (backend), NULL);
-
- builder = gtk_builder_new ();
- e_load_ui_builder_definition (builder, "mail-config.ui");
-
- /* Special folders */
- button = emae_account_folder (
- emae, "drafts_button",
- E_ACCOUNT_DRAFTS_FOLDER_URI,
- E_MAIL_LOCAL_FOLDER_DRAFTS, builder);
- priv->drafts_folder_button = GTK_BUTTON (button);
-
- button = emae_account_folder (
- emae, "sent_button",
- E_ACCOUNT_SENT_FOLDER_URI,
- E_MAIL_LOCAL_FOLDER_SENT, builder);
- priv->sent_folder_button = GTK_BUTTON (button);
-
- widget = e_builder_get_widget (builder, "trash_folder_check");
- priv->trash_folder_check = GTK_TOGGLE_BUTTON (widget);
-
- widget = e_builder_get_widget (builder, "trash_folder_butt");
- button = EM_FOLDER_SELECTION_BUTTON (widget);
- em_folder_selection_button_set_session (button, session);
- em_folder_selection_button_set_store (button, store);
- priv->trash_folder_button = GTK_BUTTON (button);
-
- g_signal_connect (
- priv->trash_folder_check, "toggled",
- G_CALLBACK (emae_real_url_toggled),
- priv->trash_folder_button);
-
- g_object_bind_property (
- priv->trash_folder_check, "active",
- priv->trash_folder_button, "sensitive",
- G_BINDING_SYNC_CREATE);
-
- if (settings != NULL)
- pspec = g_object_class_find_property (
- G_OBJECT_GET_CLASS (settings),
- "use-real-trash-path");
- else
- pspec = NULL;
-
- if (pspec != NULL)
- g_object_bind_property (
- settings, "use-real-trash-path",
- priv->trash_folder_check, "active",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- if (settings != NULL)
- pspec = g_object_class_find_property (
- G_OBJECT_GET_CLASS (settings),
- "real-trash-path");
- else
- pspec = NULL;
-
- if (pspec != NULL) {
- set_real_folder_path (
- priv->trash_folder_button,
- settings, "real-trash-path", account);
- g_signal_connect (
- priv->trash_folder_button, "notify::folder-uri",
- G_CALLBACK (update_real_folder_cb), emae);
- }
-
- flags = CAMEL_PROVIDER_ALLOW_REAL_TRASH_FOLDER;
- visible =
- (provider != NULL) &&
- ((provider->flags & flags) != 0);
- widget = GTK_WIDGET (priv->trash_folder_check);
- gtk_widget_set_visible (widget, visible);
- widget = GTK_WIDGET (priv->trash_folder_button);
- gtk_widget_set_visible (widget, visible);
-
- widget = e_builder_get_widget (builder, "junk_folder_check");
- priv->junk_folder_check = GTK_TOGGLE_BUTTON (widget);
-
- widget = e_builder_get_widget (builder, "junk_folder_butt");
- button = EM_FOLDER_SELECTION_BUTTON (widget);
- em_folder_selection_button_set_session (button, session);
- em_folder_selection_button_set_store (button, store);
- priv->junk_folder_button = GTK_BUTTON (button);
-
- g_signal_connect (
- priv->junk_folder_check, "toggled",
- G_CALLBACK (emae_real_url_toggled),
- priv->junk_folder_button);
-
- g_object_bind_property (
- priv->junk_folder_check, "active",
- priv->junk_folder_button, "sensitive",
- G_BINDING_SYNC_CREATE);
-
- if (settings != NULL)
- pspec = g_object_class_find_property (
- G_OBJECT_GET_CLASS (settings),
- "use-real-junk-path");
- else
- pspec = NULL;
-
- if (pspec != NULL)
- g_object_bind_property (
- settings, "use-real-junk-path",
- priv->junk_folder_check, "active",
- G_BINDING_BIDIRECTIONAL |
- G_BINDING_SYNC_CREATE);
-
- if (settings != NULL)
- pspec = g_object_class_find_property (
- G_OBJECT_GET_CLASS (settings),
- "real-junk-path");
- else
- pspec = NULL;
-
- if (pspec != NULL) {
- set_real_folder_path (
- priv->junk_folder_button,
- settings, "real-junk-path", account);
- g_signal_connect (
- priv->junk_folder_button, "notify::folder-uri",
- G_CALLBACK (update_real_folder_cb), emae);
- }
-
- flags = CAMEL_PROVIDER_ALLOW_REAL_JUNK_FOLDER;
- visible =
- (provider != NULL) &&
- ((provider->flags & flags) != 0);
- widget = GTK_WIDGET (priv->junk_folder_check);
- gtk_widget_set_visible (widget, visible);
- widget = GTK_WIDGET (priv->junk_folder_button);
- gtk_widget_set_visible (widget, visible);
-
- /* Special Folders "Reset Defaults" button */
- priv->restore_folders_button = (GtkButton *)e_builder_get_widget (builder, "default_folders_button");
- g_signal_connect (
- priv->restore_folders_button, "clicked",
- G_CALLBACK (default_folders_clicked), emae);
-
- /* Always Cc/Bcc */
- emae_account_toggle (emae, "always_cc", E_ACCOUNT_CC_ALWAYS, builder);
- emae_account_entry (emae, "cc_addrs", E_ACCOUNT_CC_ADDRS, builder);
- emae_account_toggle (emae, "always_bcc", E_ACCOUNT_BCC_ALWAYS, builder);
- emae_account_entry (emae, "bcc_addrs", E_ACCOUNT_BCC_ADDRS, builder);
-
- gtk_widget_set_sensitive (
- GTK_WIDGET (priv->sent_folder_button),
- (provider ? !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER) : TRUE));
-
- gtk_widget_set_sensitive (
- GTK_WIDGET (priv->restore_folders_button),
- (provider && !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)));
-
- /* Receipt policy */
- emae_setup_receipt_policy (emae, builder);
-
- widget = e_builder_get_widget (builder, item->label);
- if (emae->type == EMAE_PAGES) {
- gtk_box_pack_start ((GtkBox *) emae->pages[4], widget, TRUE, TRUE, 0);
- gtk_widget_show (widget);
- } else {
- gtk_notebook_insert_page (
- GTK_NOTEBOOK (parent), widget,
- gtk_label_new (_("Defaults")),
- position);
- gtk_container_child_set (
- GTK_CONTAINER (parent), widget,
- "tab-fill", FALSE, "tab-expand", FALSE, NULL);
- }
-
- emae_queue_widgets (
- emae, builder,
- "special-folders-table",
- "composing-messages-table",
- NULL);
-
- g_object_unref (builder);
-
- return widget;
-}
-
-static void
-emae_account_hash_algo_combo_changed_cb (GtkComboBox *combobox,
- EMAccountEditor *emae)
-{
- EAccount *account;
- gpointer data;
- const gchar *text = NULL;
-
- account = em_account_editor_get_modified_account (emae);
- data = g_object_get_data (G_OBJECT (combobox), "account-item");
-
- switch (gtk_combo_box_get_active (combobox)) {
- case 1: text = "sha1";
- break;
- case 2: text = "sha256";
- break;
- case 3:
- text = "sha384";
- break;
- case 4:
- text = "sha512";
- break;
- }
-
- e_account_set_string (account, GPOINTER_TO_INT (data), text);
-}
-
-static GtkComboBox *
-emae_account_hash_algo_combo (EMAccountEditor *emae,
- const gchar *name,
- gint item,
- GtkBuilder *builder)
-{
- EAccount *account;
- GtkComboBox *combobox;
- const gchar *text;
- gint index = 0;
-
- account = em_account_editor_get_modified_account (emae);
- combobox = GTK_COMBO_BOX (e_builder_get_widget (builder, name));
- g_return_val_if_fail (combobox != NULL, NULL);
-
- text = e_account_get_string (account, item);
- if (text) {
- if (g_ascii_strcasecmp (text, "sha1") == 0)
- index = 1;
- else if (g_ascii_strcasecmp (text, "sha256") == 0)
- index = 2;
- else if (g_ascii_strcasecmp (text, "sha384") == 0)
- index = 3;
- else if (g_ascii_strcasecmp (text, "sha512") == 0)
- index = 4;
- }
-
- gtk_combo_box_set_active (combobox, index);
-
- g_object_set_data (G_OBJECT (combobox), "account-item", GINT_TO_POINTER (item));
- g_signal_connect (
- combobox, "changed",
- G_CALLBACK (emae_account_hash_algo_combo_changed_cb), emae);
-
- return combobox;
-}
-
-static GtkWidget *
-emae_security_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
-#if defined (HAVE_NSS) && defined (ENABLE_SMIME)
- EMAccountEditorPrivate *priv = emae->priv;
-#endif
- GtkWidget *w;
- GtkBuilder *builder;
-
- /*if (old)
- return old;*/
-
- builder = gtk_builder_new ();
- e_load_ui_builder_definition (builder, "mail-config.ui");
-
- /* Security */
- emae_account_entry (emae, "pgp_key", E_ACCOUNT_PGP_KEY, builder);
- emae_account_hash_algo_combo (emae, "pgp_hash_algo", E_ACCOUNT_PGP_HASH_ALGORITHM, builder);
- emae_account_toggle (emae, "pgp_encrypt_to_self", E_ACCOUNT_PGP_ENCRYPT_TO_SELF, builder);
- emae_account_toggle (emae, "pgp_always_sign", E_ACCOUNT_PGP_ALWAYS_SIGN, builder);
- emae_account_toggle (emae, "pgp_no_imip_sign", E_ACCOUNT_PGP_NO_IMIP_SIGN, builder);
- emae_account_toggle (emae, "pgp_always_trust", E_ACCOUNT_PGP_ALWAYS_TRUST, builder);
-
-#if defined (HAVE_NSS) && defined (ENABLE_SMIME)
- /* TODO: this should handle its entry separately? */
- priv->smime_sign_key = emae_account_entry (emae, "smime_sign_key", E_ACCOUNT_SMIME_SIGN_KEY, builder);
- priv->smime_sign_key_select = (GtkButton *)e_builder_get_widget (builder, "smime_sign_key_select");
- priv->smime_sign_key_clear = (GtkButton *)e_builder_get_widget (builder, "smime_sign_key_clear");
- g_signal_connect (
- priv->smime_sign_key_select, "clicked",
- G_CALLBACK (smime_sign_key_select), emae);
- g_signal_connect (
- priv->smime_sign_key_clear, "clicked",
- G_CALLBACK (smime_sign_key_clear), emae);
-
- emae_account_hash_algo_combo (emae, "smime_hash_algo", E_ACCOUNT_SMIME_HASH_ALGORITHM, builder);
- priv->smime_sign_default = emae_account_toggle (emae, "smime_sign_default", E_ACCOUNT_SMIME_SIGN_DEFAULT, builder);
-
- priv->smime_encrypt_key = emae_account_entry (emae, "smime_encrypt_key", E_ACCOUNT_SMIME_ENCRYPT_KEY, builder);
- priv->smime_encrypt_key_select = (GtkButton *)e_builder_get_widget (builder, "smime_encrypt_key_select");
- priv->smime_encrypt_key_clear = (GtkButton *)e_builder_get_widget (builder, "smime_encrypt_key_clear");
- g_signal_connect (
- priv->smime_encrypt_key_select, "clicked",
- G_CALLBACK (smime_encrypt_key_select), emae);
- g_signal_connect (
- priv->smime_encrypt_key_clear, "clicked",
- G_CALLBACK (smime_encrypt_key_clear), emae);
-
- priv->smime_encrypt_default = emae_account_toggle (emae, "smime_encrypt_default", E_ACCOUNT_SMIME_ENCRYPT_DEFAULT, builder);
- priv->smime_encrypt_to_self = emae_account_toggle (emae, "smime_encrypt_to_self", E_ACCOUNT_SMIME_ENCRYPT_TO_SELF, builder);
- smime_changed (emae);
-#else
- {
- /* Since we don't have NSS, hide the S/MIME config options */
- GtkWidget *frame;
-
- frame = e_builder_get_widget (builder, "smime_vbox");
- gtk_widget_destroy (frame);
- }
-#endif /* HAVE_NSS */
-
- w = e_builder_get_widget (builder, item->label);
- gtk_notebook_insert_page (
- GTK_NOTEBOOK (parent), w,
- gtk_label_new (_("Security")),
- position);
- gtk_container_child_set (
- GTK_CONTAINER (parent), w,
- "tab-fill", FALSE, "tab-expand", FALSE, NULL);
-
- g_object_unref (builder);
-
- return w;
-}
-
-/*
- * Allow some level of post creation customisation in plugins.
- */
-GtkWidget *
-em_account_editor_get_widget (EMAccountEditor *emae,
- const gchar *name)
-{
- GtkWidget *wid;
-
- wid = g_hash_table_lookup (emae->priv->widgets, name);
- if (wid)
- return wid;
-
- g_warning ("Mail account widget '%s' not found", name);
-
- return NULL;
-}
-
-static GtkWidget *
-emae_widget_glade (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- return em_account_editor_get_widget (data, item->label);
-}
-
-/* plugin meta-data for "org.gnome.evolution.mail.config.accountEditor" */
-static EMConfigItem emae_editor_items[] = {
- { E_CONFIG_BOOK, (gchar *) "" },
- { E_CONFIG_PAGE, (gchar *) "00.identity", (gchar *) "vboxIdentityBorder", emae_identity_page },
- { E_CONFIG_SECTION, (gchar *) "00.identity/00.name", (gchar *) "account_vbox", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "00.identity/10.required", (gchar *) "identity-required-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "00.identity/20.info", (gchar *) "identity-optional-table", emae_widget_glade },
-
- { E_CONFIG_PAGE, (gchar *) "10.receive", (gchar *) "vboxSourceBorder", emae_receive_page },
- { E_CONFIG_SECTION_TABLE, (gchar *) "10.receive/00.type", (gchar *) "source-type-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "10.receive/10.config", (gchar *) "source-config-table", emae_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "10.receive/20.security", (gchar *) "source-security-vbox", emae_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "10.receive/30.auth", (gchar *) "source-auth-vbox", emae_widget_glade },
-
- /* Most sections for this is auto-generated from the camel config */
- { E_CONFIG_PAGE, (gchar *) "20.receive_options", (gchar *) N_("Receiving Options"), },
- { E_CONFIG_SECTION_TABLE, (gchar *) "20.receive_options/10.mailcheck", (gchar *) N_("Checking for New Messages"), },
- { E_CONFIG_ITEM_TABLE, (gchar *) "20.receive_options/10.mailcheck/00.autocheck", NULL, emae_receive_options_item, },
-
- { E_CONFIG_PAGE, (gchar *) "30.send", (gchar *) "vboxTransportBorder", emae_send_page },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/00.type", (gchar *) "transport-type-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/10.config", (gchar *) "transport-server-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/20.security", (gchar *) "transport-security-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/30.auth", (gchar *) "transport-auth-table", emae_widget_glade },
-
- { E_CONFIG_PAGE, (gchar *) "40.defaults", (gchar *) "vboxFoldersBorder", emae_defaults_page },
- { E_CONFIG_SECTION_TABLE, (gchar *) "40.defaults/00.folders", (gchar *) "special-folders-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "40.defaults/10.composing", (gchar *) "composing-messages-table", emae_widget_glade },
-
- { E_CONFIG_PAGE, (gchar *) "50.security", (gchar *) "vboxSecurityBorder", emae_security_page },
- /* 1x1 table (!) not vbox: { E_CONFIG_SECTION, "50.security/00.gpg", "table19", emae_widget_glade }, */
- /* table not vbox: { E_CONFIG_SECTION, "50.security/10.smime", "smime_table", emae_widget_glade }, */
- { 0 },
-};
-static gboolean emae_editor_items_translated = FALSE;
-
-static GtkWidget *
-emae_review_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EMAccountEditorPrivate *priv = emae->priv;
- GtkWidget *w;
- GtkBuilder *builder;
-
- builder = gtk_builder_new ();
- e_load_ui_builder_definition (builder, "mail-config.ui");
-
- priv->review_name = (GtkLabel*) e_builder_get_widget (builder, "personal-name-entry");
- priv->review_email = (GtkLabel*) e_builder_get_widget (builder, "personal-email-entry");
- priv->receive_stype = (GtkLabel*) e_builder_get_widget (builder, "receive_server_type");
- priv->send_stype = (GtkLabel*) e_builder_get_widget (builder, "send_server_type");
- priv->receive_saddress = (GtkLabel*) e_builder_get_widget (builder, "receive_server_address");
- priv->send_saddress = (GtkLabel*) e_builder_get_widget (builder, "send_server_address");
- priv->receive_name = (GtkLabel*) e_builder_get_widget (builder, "receive_username");
- priv->send_name = (GtkLabel*) e_builder_get_widget (builder, "send_username");
- priv->receive_encryption = (GtkLabel*) e_builder_get_widget (builder, "receive_encryption");
- priv->send_encryption = (GtkLabel*) e_builder_get_widget (builder, "send_encryption");
-
- w = e_builder_get_widget (builder, item->label);
- priv->review_box = gtk_vbox_new (FALSE, 2);
- gtk_widget_show (priv->review_box);
- if (((EConfig *) priv->config)->type == E_CONFIG_ASSISTANT) {
- GtkWidget *page;
-
- page = emae_create_basic_assistant_page (
- emae, GTK_ASSISTANT (parent),
- "review_page", position);
-
- gtk_box_pack_start (GTK_BOX (page), w, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (page), priv->review_box, FALSE, FALSE, 0);
- gtk_widget_reparent (priv->management_frame, page);
-
- w = page;
- }
-
- return w;
-}
-
-static GtkWidget *
-emae_widget_assistant_page (EConfig *ec,
- EConfigItem *item,
- GtkWidget *parent,
- GtkWidget *old,
- gint position,
- gpointer data)
-{
- EMAccountEditor *emae = (EMAccountEditor *) data;
-
- if (emae->type == EMAE_PAGES)
- return NULL;
-
- return emae_create_basic_assistant_page (
- emae, GTK_ASSISTANT (parent), item->label, position);
-}
-
-/* plugin meta-data for "org.gnome.evolution.mail.config.accountAssistant" */
-static EMConfigItem emae_assistant_items[] = {
- { E_CONFIG_ASSISTANT, (gchar *) "" },
- { E_CONFIG_PAGE_START, (gchar *) "0.start", (gchar *) "start_page", emae_widget_assistant_page },
-
- { E_CONFIG_PAGE, (gchar *) "00.identity", (gchar *) "vboxIdentityBorder", emae_identity_page },
- { E_CONFIG_SECTION, (gchar *) "00.identity/00.name", (gchar *) "account_vbox", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "00.identity/10.required", (gchar *) "identity-required-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "00.identity/20.info", (gchar *) "identity-optional-table", emae_widget_glade },
-
- { E_CONFIG_PAGE, (gchar *) "10.receive", (gchar *) "vboxSourceBorder", emae_receive_page },
- { E_CONFIG_SECTION_TABLE, (gchar *) "10.receive/00.type", (gchar *) "source-type-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "10.receive/10.config", (gchar *) "source-config-table", emae_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "10.receive/20.security", (gchar *) "source-security-vbox", emae_widget_glade },
- { E_CONFIG_SECTION, (gchar *) "10.receive/30.auth", (gchar *) "source-auth-vbox", emae_widget_glade },
-
- /* Most sections for this is auto-generated fromt the camel config */
- { E_CONFIG_PAGE, (gchar *) "20.receive_options", (gchar *) N_("Receiving Options"), },
- { E_CONFIG_SECTION_TABLE, (gchar *) "20.receive_options/10.mailcheck", (gchar *) N_("Checking for New Messages"), },
- { E_CONFIG_ITEM_TABLE, (gchar *) "20.receive_options/10.mailcheck/00.autocheck", NULL, emae_receive_options_item, },
-
- { E_CONFIG_PAGE, (gchar *) "30.send", (gchar *) "vboxTransportBorder", emae_send_page },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/00.type", (gchar *) "transport-type-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/10.config", (gchar *) "transport-server-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/20.security", (gchar *) "transport-security-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "30.send/30.auth", (gchar *) "transport-auth-table", emae_widget_glade },
-
- { E_CONFIG_PAGE, (gchar *) "40.defaults", (gchar *) "vboxFoldersBorder", emae_defaults_page },
- { E_CONFIG_SECTION_TABLE, (gchar *) "40.defaults/00.folders", (gchar *) "special-folders-table", emae_widget_glade },
- { E_CONFIG_SECTION_TABLE, (gchar *) "40.defaults/10.composing", (gchar *) "composing-messages-table", emae_widget_glade },
-
- { E_CONFIG_PAGE, (gchar *) "50.review", (gchar *) "vboxReviewBorder", emae_review_page },
-
- { E_CONFIG_PAGE_FINISH, (gchar *) "999.end", (gchar *) "finish_page", emae_widget_assistant_page },
- { 0 },
-};
-static gboolean emae_assistant_items_translated = FALSE;
-
-static void
-emae_free (EConfig *ec,
- GSList *items,
- gpointer data)
-{
- g_slist_free (items);
-}
-
-static void
-emae_free_auto (EConfig *ec,
- GSList *items,
- gpointer data)
-{
- GSList *l, *n;
-
- for (l = items; l;) {
- struct _receive_options_item *item = l->data;
-
- n = g_slist_next (l);
- g_free (item->item.path);
- if (item->extra_table)
- g_hash_table_destroy (item->extra_table);
- g_free (item);
- g_slist_free_1 (l);
- l = n;
- }
-}
-
-static gboolean
-emae_check_service_complete (EMAccountEditor *emae,
- EMAccountEditorService *service)
-{
- CamelProvider *provider = NULL;
- const gchar *host = NULL;
- const gchar *path = NULL;
- const gchar *user = NULL;
- gboolean have_host;
- gboolean have_path;
- gboolean have_user;
- gboolean need_auth;
- gboolean need_host;
- gboolean need_path;
- gboolean need_port;
- gboolean need_user;
-
- if (service->protocol != NULL)
- provider = camel_provider_get (service->protocol, NULL);
-
- if (provider == NULL)
- return TRUE;
-
- if (CAMEL_IS_NETWORK_SETTINGS (service->settings)) {
- CamelNetworkSettings *network_settings;
-
- network_settings = CAMEL_NETWORK_SETTINGS (service->settings);
- host = camel_network_settings_get_host (network_settings);
- user = camel_network_settings_get_user (network_settings);
- }
-
- if (CAMEL_IS_LOCAL_SETTINGS (service->settings)) {
- CamelLocalSettings *local_settings;
-
- local_settings = CAMEL_LOCAL_SETTINGS (service->settings);
- path = camel_local_settings_get_path (local_settings);
- }
-
- need_auth = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_AUTH);
- need_host = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_HOST);
- need_path = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_PATH);
- need_port = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_PORT);
- need_user = CAMEL_PROVIDER_NEEDS (provider, CAMEL_URL_PART_USER);
-
- have_host = (host != NULL && *host != '\0');
- have_path = (path != NULL && *path != '\0');
- have_user = (user != NULL && *user != '\0');
-
- if (need_host && !have_host)
- return FALSE;
-
- if (need_port && !e_port_entry_is_valid (service->port))
- return FALSE;
-
- /* We only need the user if the service needs auth as well, i think */
- if (need_auth || service->requires_auth)
- if (need_user && !have_user)
- return FALSE;
-
- if (need_path && !have_path)
- return FALSE;
-
- return TRUE;
-}
-
-static ServerData *
-emae_check_servers (const gchar *email)
-{
- ServerData *sdata = g_new0 (ServerData, 1);
- EmailProvider *provider = g_new0 (EmailProvider, 1);
- gchar *dupe = g_strdup (email);
- gchar *tmp;
-
- /* FIXME: Find a way to free the provider once given to account settings. */
- provider->email = (gchar *) email;
- tmp = strchr (email, '@');
- tmp++;
- provider->domain = tmp;
- tmp = strchr (dupe, '@');
- *tmp = 0;
- provider->username = (gchar *) g_quark_to_string (g_quark_from_string (dupe));
- g_free (dupe);
-
- if (!mail_guess_servers (provider)) {
- g_free (provider);
- g_free (sdata);
- return NULL;
- }
- /*printf("Recv: %s\n%s(%s), %s by %s \n Send: %s\n%s(%s), %s by %s\n via %s to %s\n",
- provider->recv_type, provider->recv_hostname, provider->recv_port, provider->recv_username, provider->recv_auth,
- provider->send_type, provider->send_hostname, provider->send_port, provider->send_username, provider->send_auth,
- provider->recv_socket_type, provider->send_socket_type); */
-
- sdata->recv = provider->recv_hostname;
- sdata->recv_port = provider->recv_port;
- sdata->send = provider->send_hostname;
- sdata->send_port = provider->send_port;
- if (strcmp (provider->recv_type, "pop3") == 0)
- sdata->proto = g_strdup ("pop");
- else if (strcmp (provider->recv_type, "imap") == 0)
- sdata->proto = g_strdup ("imapx");
- else
- sdata->proto = provider->recv_type;
- if (provider->recv_socket_type) {
- CamelNetworkSecurityMethod method;
-
- if (g_ascii_strcasecmp (provider->recv_socket_type, "SSL") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
- else if (g_ascii_strcasecmp (provider->recv_socket_type, "secure") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
- else if (g_ascii_strcasecmp (provider->recv_socket_type, "STARTTLS") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
- else if (g_ascii_strcasecmp (provider->recv_socket_type, "TLS") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
- else
- method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
-
- sdata->security_method = method;
- sdata->recv_security_method = method;
- }
-
- if (provider->send_socket_type) {
- CamelNetworkSecurityMethod method;
-
- if (g_ascii_strcasecmp (provider->send_socket_type, "SSL") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
- else if (g_ascii_strcasecmp (provider->send_socket_type, "secure") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
- else if (g_ascii_strcasecmp (provider->send_socket_type, "STARTTLS") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
- else if (g_ascii_strcasecmp (provider->send_socket_type, "TLS") == 0)
- method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
- else
- method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
-
- sdata->send_security_method = method;
- }
-
- sdata->send_auth = g_ascii_strup (provider->send_auth, -1);
- sdata->recv_auth = g_ascii_strup (provider->recv_auth, -1);
- sdata->send_user = provider->send_username;
- sdata->recv_user = provider->recv_username;
-
- g_free (provider);
-
- return sdata;
-}
-
-static void
-emae_destroy_widget (GtkWidget *widget)
-{
- if (widget && GTK_IS_WIDGET (widget)) {
- gtk_widget_destroy (widget);
- widget = NULL;
- }
-}
-
-static gboolean
-emae_display_name_in_use (EMAccountEditor *emae,
- const gchar *display_name)
-{
- EAccount *account;
- EAccount *original_account;
-
- /* XXX Trivial for now, less so when we dump EAccount. */
-
- account = e_get_account_by_name (display_name);
- original_account = em_account_editor_get_original_account (emae);
-
- return (account != NULL && account != original_account);
-}
-
-static void
-emae_init_receive_page_for_new_account (EMAccountEditor *emae)
-{
- EAccount *account;
- const gchar *address;
- gchar *user;
-
- account = em_account_editor_get_modified_account (emae);
- address = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
-
- /* Extract an initial username from the email address. */
- user = g_strdup (address);
- if (user != NULL) {
- gchar *cp = strchr (user, '@');
- if (cp != NULL)
- *cp = '\0';
- }
-
- gtk_entry_set_text (emae->priv->source.username, user);
-
- g_free (user);
-}
-
-static void
-emae_init_receive_page_for_server_data (EMAccountEditor *emae)
-{
- ServerData *sdata;
- CamelNetworkSecurityMethod method;
- gint port = 0;
-
- sdata = emae->priv->selected_server;
- g_return_if_fail (sdata != NULL);
-
- if (sdata->recv_user == NULL) {
- ; /* do nothing */
- } else if (*sdata->recv_user == '\0') {
- ; /* do nothing */
- } else if (strcmp (sdata->recv_user, "@") == 0) {
- ; /* do nothing */
- } else {
- gtk_entry_set_text (
- emae->priv->source.username,
- sdata->recv_user);
- }
-
- if (sdata->recv_security_method != CAMEL_NETWORK_SECURITY_METHOD_NONE)
- method = sdata->recv_security_method;
- else
- method = sdata->security_method;
-
- g_object_set (
- emae->priv->source.settings,
- "security-method", method, NULL);
-
- emae->priv->source.protocol = sdata->proto;
-
- if (sdata->recv_port != NULL && *sdata->recv_port != '\0')
- port = (gint) strtol (sdata->recv_port, NULL, 10);
-
- if (port > 0)
- e_port_entry_set_port (emae->priv->source.port, port);
-
- gtk_toggle_button_set_active (emae->priv->source.remember, TRUE);
- gtk_entry_set_text (emae->priv->source.hostname, sdata->recv);
-
- if (sdata->recv_auth != NULL && *sdata->recv_auth != '\0')
- gtk_combo_box_set_active_id (
- emae->priv->source.authtype,
- sdata->recv_auth);
-}
-
-static void
-emae_init_send_page_for_new_account (EMAccountEditor *emae)
-{
- EAccount *account;
- const gchar *address;
- gchar *user;
-
- account = em_account_editor_get_modified_account (emae);
- address = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
-
- /* Extract an initial username from the email address. */
- user = g_strdup (address);
- if (user != NULL) {
- gchar *cp = strchr (user, '@');
- if (cp != NULL)
- *cp = '\0';
- }
-
- gtk_entry_set_text (emae->priv->transport.username, user);
-
- g_free (user);
-}
-
-static void
-emae_init_send_page_for_server_data (EMAccountEditor *emae)
-{
- ServerData *sdata;
- CamelNetworkSecurityMethod method;
- gint port = 0;
-
- sdata = emae->priv->selected_server;
- g_return_if_fail (sdata != NULL);
-
- if (sdata->recv_user == NULL) {
- ; /* do nothing */
- } else if (*sdata->recv_user == '\0') {
- ; /* do nothing */
- } else if (strcmp (sdata->recv_user, "@") == 0) {
- ; /* do nothing */
- } else {
- gtk_entry_set_text (
- emae->priv->transport.username,
- sdata->send_user);
- }
-
- if (sdata->recv_security_method != CAMEL_NETWORK_SECURITY_METHOD_NONE)
- method = sdata->recv_security_method;
- else
- method = sdata->security_method;
-
- g_object_set (
- emae->priv->transport.settings,
- "security-method", method, NULL);
-
- emae->priv->transport.protocol = "smtp";
-
- if (sdata->recv_port != NULL && *sdata->recv_port != '\0')
- port = (gint) strtol (sdata->recv_port, NULL, 10);
-
- if (port > 0)
- e_port_entry_set_port (emae->priv->source.port, port);
-
- gtk_toggle_button_set_active (emae->priv->transport.remember, TRUE);
- gtk_toggle_button_set_active (emae->priv->transport.needs_auth, TRUE);
- gtk_entry_set_text (emae->priv->transport.hostname, sdata->send);
-
- if (sdata->send_auth != NULL && *sdata->send_auth != '\0')
- gtk_combo_box_set_active_id (
- emae->priv->source.authtype,
- sdata->send_auth);
- else
- emae_authtype_changed (
- emae->priv->transport.authtype,
- &emae->priv->transport);
-}
-
-static void
-emae_init_review_page (EMAccountEditor *emae)
-{
- EAccount *account;
- const gchar *address;
- gchar *display_name;
- gint ii = 1;
-
- account = em_account_editor_get_modified_account (emae);
- address = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
-
- display_name = g_strdup (address);
-
- /* Use the email address as the initial display name for the
- * mail account. If necessary, append a number to the display
- * name to make it unique among other mail accounts. */
- while (emae_display_name_in_use (emae, display_name)) {
- g_free (display_name);
- display_name = g_strdup_printf ("%s (%d)", address, ii++);
- }
-
- gtk_entry_set_text (emae->priv->identity_entries[0], display_name);
-
- g_free (display_name);
-}
-
-static void
-emae_update_review_page (EMAccountEditor *emae)
-{
- EAccount *account;
- const gchar *name;
- const gchar *address;
-
- account = em_account_editor_get_modified_account (emae);
- name = e_account_get_string (account, E_ACCOUNT_ID_NAME);
- address = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
-
- gtk_label_set_text (emae->priv->review_name, name);
- gtk_label_set_text (emae->priv->review_email, address);
-
- if (CAMEL_IS_NETWORK_SETTINGS (emae->priv->source.settings)) {
- CamelNetworkSecurityMethod method;
- const gchar *encryption;
- const gchar *protocol;
- gchar *host = NULL;
- gchar *user = NULL;
-
- protocol = emae->priv->source.protocol;
-
- g_object_get (
- emae->priv->source.settings,
- "host", &host, "user", &user,
- "security-method", &method, NULL);
-
- switch (method) {
- case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT:
- encryption = _("Always (SSL)");
- break;
- case CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT:
- encryption = _("When possible (TLS)");
- break;
- default:
- encryption = _("Never");
- break;
- }
-
- gtk_label_set_text (emae->priv->receive_stype, protocol);
- gtk_label_set_text (emae->priv->receive_saddress, host);
- gtk_label_set_text (emae->priv->receive_name, user);
- gtk_label_set_text (emae->priv->receive_encryption, encryption);
-
- g_free (host);
- g_free (user);
- }
-
- if (CAMEL_IS_NETWORK_SETTINGS (emae->priv->transport.settings)) {
- CamelNetworkSecurityMethod method;
- const gchar *encryption;
- const gchar *protocol;
- gchar *host = NULL;
- gchar *user = NULL;
-
- protocol = emae->priv->transport.protocol;
-
- g_object_get (
- emae->priv->transport.settings,
- "host", &host, "user", &user,
- "security-method", &method, NULL);
-
- switch (method) {
- case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT:
- encryption = _("Always (SSL)");
- break;
- case CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT:
- encryption = _("When possible (TLS)");
- break;
- default:
- encryption = _("Never");
- break;
- }
-
- gtk_label_set_text (emae->priv->send_stype, protocol);
- gtk_label_set_text (emae->priv->send_saddress, host);
- gtk_label_set_text (emae->priv->send_name, user);
- gtk_label_set_text (emae->priv->send_encryption, encryption);
-
- g_free (host);
- g_free (user);
- }
-}
-
-static void
-emae_update_review_page_for_google (EMAccountEditor *emae)
-{
- GtkWidget *container;
- GtkWidget *widget;
- gchar *markup;
- gboolean can_contacts, can_calendar;
-
- can_contacts = !emae->priv->gcontacts ||
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (emae->priv->gcontacts));
- can_calendar = !emae->priv->calendar ||
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (emae->priv->calendar));
-
- emae_destroy_widget (emae->priv->gcontacts);
- emae_destroy_widget (emae->priv->calendar);
- emae_destroy_widget (emae->priv->account_label);
- emae_destroy_widget (emae->priv->gmail_link);
-
- container = emae->priv->review_box;
-
- widget = gtk_label_new (NULL);
- markup = g_markup_printf_escaped (
- "<span size=\"large\" weight=\"bold\">%s</span>",
- _("Google account settings:"));
- gtk_label_set_markup (GTK_LABEL (widget), markup);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->account_label = widget;
- gtk_widget_show (widget);
- g_free (markup);
-
- widget = gtk_check_button_new_with_mnemonic (
- _("Setup Google con_tacts with Evolution"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), can_contacts);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->gcontacts = widget;
- gtk_widget_show (widget);
-
- widget = gtk_check_button_new_with_mnemonic (
- _("Setup Google ca_lendar with Evolution"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), can_calendar);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->calendar = widget;
- gtk_widget_show (widget);
-
- widget = gtk_link_button_new_with_label (
- "https://mail.google.com/mail/?ui=2&amp;shva=1#settings/fwdandpop",
- _("You may need to enable IMAP access."));
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->gmail_link = widget;
- gtk_widget_show (widget);
-}
-
-static void
-emae_update_review_page_for_yahoo (EMAccountEditor *emae)
-{
- EAccount *account;
- GtkWidget *container;
- GtkWidget *widget;
- GtkWidget *label;
- gchar *markup;
- gchar *name = NULL;
- gboolean can_calendar, can_tasks;
-
- if (emae->priv->yahoo_cal_entry) {
- name = g_strdup (gtk_entry_get_text (GTK_ENTRY (emae->priv->yahoo_cal_entry)));
- } else {
- account = em_account_editor_get_modified_account (emae);
- name = g_strdup (e_account_get_string (account, E_ACCOUNT_ID_NAME));
-
- g_strdelimit (name, " ", '_');
- }
-
- can_calendar = !emae->priv->calendar ||
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (emae->priv->calendar));
- can_tasks = !emae->priv->tasks ||
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (emae->priv->tasks));
-
- emae_destroy_widget (emae->priv->calendar);
- emae_destroy_widget (emae->priv->tasks);
- emae_destroy_widget (emae->priv->info_label);
- emae_destroy_widget (emae->priv->yahoo_cal_entry);
- emae_destroy_widget (emae->priv->account_label);
- emae_destroy_widget (emae->priv->yahoo_cal_box);
-
- container = emae->priv->review_box;
-
- widget = gtk_label_new (NULL);
- markup = g_markup_printf_escaped (
- "<span size=\"large\" weight=\"bold\">%s</span>",
- _("Yahoo! account settings:"));
- gtk_label_set_markup (GTK_LABEL (widget), markup);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->account_label = widget;
- gtk_widget_show (widget);
- g_free (markup);
-
- widget = gtk_check_button_new_with_mnemonic (
- _("Setup _Yahoo! calendar with Evolution"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), can_calendar);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->calendar = widget;
- gtk_widget_show (widget);
-
- widget = gtk_check_button_new_with_mnemonic (
- _("Setup Yahoo! _tasks with Evolution"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), can_tasks);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->tasks = widget;
- gtk_widget_show (widget);
-
- widget = gtk_label_new (
- _("Yahoo! calendars are named as firstname_lastname. We have "
- "tried to form the calendar name. Please confirm and "
- "re-enter the calendar name, if it is not correct, or "
- "change it later in calendar Properties."));
- gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
- gtk_label_set_line_wrap_mode (GTK_LABEL (widget), PANGO_WRAP_WORD);
- gtk_label_set_selectable (GTK_LABEL (widget), TRUE);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->info_label = widget;
- gtk_widget_show (widget);
-
- widget = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->yahoo_cal_box = widget;
- gtk_widget_show (widget);
-
- container = widget;
-
- widget = gtk_label_new_with_mnemonic (
- _("Yahoo! Calen_dar name:"));
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- gtk_widget_show (widget);
-
- label = widget;
-
- widget = gtk_entry_new ();
- gtk_entry_set_text (GTK_ENTRY (widget), name);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
- gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- emae->priv->yahoo_cal_entry = widget;
- gtk_widget_show (widget);
-
- g_free (name);
-}
-
-static gboolean
-emae_check_identity_complete (EMAccountEditor *emae)
-{
- EAccount *account;
- const gchar *name;
- const gchar *address;
- const gchar *reply_to;
-
- account = em_account_editor_get_modified_account (emae);
-
- name = e_account_get_string (account, E_ACCOUNT_ID_NAME);
- address = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
- reply_to = e_account_get_string (account, E_ACCOUNT_ID_REPLY_TO);
-
- if (name == NULL || *name == '\0')
- return FALSE;
-
- if (address == NULL || !is_email (address))
- return FALSE;
-
- /* An empty reply_to string is allowed. */
- if (reply_to != NULL && *reply_to != '\0' && !is_email (reply_to))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-emae_check_review_complete (EMAccountEditor *emae)
-{
- EAccount *account;
- const gchar *display_name;
-
- account = em_account_editor_get_modified_account (emae);
- display_name = e_account_get_string (account, E_ACCOUNT_NAME);
-
- if (display_name == NULL || *display_name == '\0')
- return FALSE;
-
- if (emae_display_name_in_use (emae, display_name))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-emae_check_complete (EConfig *ec,
- const gchar *pageid,
- gpointer data)
-{
- EMAccountEditor *emae = data;
- EAccount *account;
- enum _e_config_t config_type;
- gboolean refresh = FALSE;
- gboolean new_account;
- const gchar *address;
- gchar *host = NULL;
- gboolean ok = TRUE;
-
- config_type = ((EConfig *) emae->priv->config)->type;
- new_account = (em_account_editor_get_original_account (emae) == NULL);
-
- account = em_account_editor_get_modified_account (emae);
- address = e_account_get_string (account, E_ACCOUNT_ID_ADDRESS);
-
- if (CAMEL_IS_NETWORK_SETTINGS (emae->priv->source.settings))
- host = camel_network_settings_dup_host (
- CAMEL_NETWORK_SETTINGS (emae->priv->source.settings));
-
- /* We use the page-check of various pages to 'prepare' or
- * pre-load their values, only in the assistant. */
-
- if (pageid == NULL || config_type != E_CONFIG_ASSISTANT)
- goto skip_prepare;
-
- if (strcmp (pageid, "10.receive") == 0) {
- if (!emae->priv->receive_set) {
-
- /* FIXME Do this asynchronously! */
- emae->priv->selected_server =
- emae_check_servers (address);
-
- if (new_account) {
- emae_init_receive_page_for_new_account (emae);
- refresh = TRUE;
- }
- if (emae->priv->selected_server != NULL)
- emae_init_receive_page_for_server_data (emae);
-
- emae->priv->receive_set = TRUE;
- }
-
- } else if (strcmp (pageid, "30.send") == 0) {
- if (!emae->priv->send_set) {
- if (new_account)
- emae_init_send_page_for_new_account (emae);
- if (emae->priv->selected_server != NULL) {
- emae_init_send_page_for_server_data (emae);
- refresh = TRUE;
- }
-
- emae->priv->send_set = TRUE;
- }
-
- } else if (strcmp (pageid, "20.receive_options") == 0) {
- if (!emae->priv->receive_opt_set) {
- CamelProvider *provider;
-
- provider = emae_get_store_provider (emae);
-
- if (provider != NULL
- && emae->priv->extra_provider != provider) {
- emae->priv->extra_provider = provider;
- emae_auto_detect (emae);
- }
-
- emae->priv->receive_opt_set = TRUE;
- }
-
- /* Review page is only shown in the assistant. */
- } else if (strcmp (pageid, "50.review") == 0) {
- if (!emae->priv->review_set) {
- emae_init_review_page (emae);
- emae->priv->review_set = TRUE;
- }
-
- emae_update_review_page (emae);
-
- /* Google and Yahoo get special treatment. */
-
- emae->priv->is_gmail = FALSE;
- emae->priv->is_yahoo = FALSE;
-
- if (e_util_utf8_strstrcase (host, "gmail")) {
- emae->priv->is_gmail = TRUE;
- emae_update_review_page_for_google (emae);
-
- } else if (e_util_utf8_strstrcase (host, "googlemail")) {
- emae->priv->is_gmail = TRUE;
- emae_update_review_page_for_google (emae);
-
- } else if (e_util_utf8_strstrcase (host, "yahoo.")) {
- emae->priv->is_yahoo = TRUE;
- emae_update_review_page_for_yahoo (emae);
-
- } else if (e_util_utf8_strstrcase (host, "ymail.")) {
- emae->priv->is_yahoo = TRUE;
- emae_update_review_page_for_yahoo (emae);
-
- } else if (e_util_utf8_strstrcase (host, "rocketmail.")) {
- emae->priv->is_yahoo = TRUE;
- emae_update_review_page_for_yahoo (emae);
- }
- }
-
-skip_prepare:
- /*
- * Setting a flag on the Account if it is marked as default. It is
- * done in this way instead of using a temporary variable so as to
- * keep track of which account is marked as default in case of
- * editing multiple accounts at a time.
- */
- if (gtk_toggle_button_get_active (emae->priv->default_account))
- g_object_set_data (G_OBJECT (account), "default_flagged", GINT_TO_POINTER(1));
-
- if (ok && (pageid == NULL || strcmp (pageid, "00.identity") == 0))
- ok = emae_check_identity_complete (emae);
-
- if (ok && (pageid == NULL || strcmp (pageid, "10.receive") == 0)) {
- if (emae->type != EMAE_NOTEBOOK && refresh) {
- emae_refresh_providers (
- emae, &emae->priv->source);
- emae_provider_changed (
- emae->priv->source.providers,
- &emae->priv->source);
- }
- ok = emae_check_service_complete (emae, &emae->priv->source);
- }
-
- if (ok && (pageid == NULL || strcmp (pageid, "30.send") == 0)) {
- CamelProvider *provider;
-
- provider = emae_get_store_provider (emae);
- if (!provider || !CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) {
- if (emae->type != EMAE_NOTEBOOK && refresh) {
- emae_refresh_providers (
- emae, &emae->priv->transport);
- emae_provider_changed (
- emae->priv->transport.providers,
- &emae->priv->transport);
- }
- ok = emae_check_service_complete (
- emae, &emae->priv->transport);
- }
- }
-
- if (ok && (pageid == NULL || strcmp (pageid, "50.review") == 0))
- ok = emae_check_review_complete (emae);
-
- g_free (host);
-
- return ok;
-}
-
-gboolean
-em_account_editor_check (EMAccountEditor *emae,
- const gchar *page)
-{
- return emae_check_complete ((EConfig *) emae->config, page, emae);
-}
-
-static void
-forget_password_if_needed (EAccount *original_account,
- EAccount *modified_account,
- e_account_item_t save_pass_itm,
- e_account_item_t url_itm)
-{
- const gchar *orig_url, *modif_url;
-
- g_return_if_fail (original_account != NULL);
- g_return_if_fail (modified_account != NULL);
-
- orig_url = e_account_get_string (original_account, url_itm);
- modif_url = e_account_get_string (modified_account, url_itm);
-
- if (orig_url && !*orig_url)
- orig_url = NULL;
-
- if (modif_url && !*modif_url)
- modif_url = NULL;
-
- if ((e_account_get_bool (original_account, save_pass_itm) != e_account_get_bool (modified_account, save_pass_itm)
- && !e_account_get_bool (modified_account, save_pass_itm) && orig_url) ||
- (orig_url && !modif_url)) {
- CamelURL *url;
- gchar *url_str;
-
- url = camel_url_new (orig_url, NULL);
- if (!url)
- return;
-
- url_str = camel_url_to_string (url, CAMEL_URL_HIDE_PARAMS);
- if (url_str)
- e_passwords_forget_password (NULL, url_str);
-
- g_free (url_str);
- camel_url_free (url);
- }
-}
-
-#define CALENDAR_CALDAV_URI "caldav://%s@www.google.com/calendar/dav/%s/events"
-#define GMAIL_CALENDAR_LOCATION "://www.google.com/calendar/feeds/"
-#define CALENDAR_DEFAULT_PATH "/private/full"
-#define SELECTED_CALENDARS "selected-calendars"
-#define YAHOO_CALENDAR_LOCATION "%s@caldav.calendar.yahoo.com/dav/%s/Calendar/%s"
-
-static gchar *
-sanitize_user_mail (const gchar *user)
-{
- if (!user)
- return NULL;
-
- if (strstr (user, "%40") != NULL) {
- return g_strdup (user);
- } else if (!is_email (user)) {
- return g_strconcat (user, "%40gmail.com", NULL);
- } else {
- gchar *tmp = g_malloc0 (sizeof (gchar) * (1 + strlen (user) + 2));
- gchar *at = strchr (user, '@');
-
- strncpy (tmp, user, at - user);
- strcat (tmp, "%40");
- strcat (tmp, at + 1);
-
- return tmp;
- }
-}
-
-static void
-setup_google_addressbook (EMAccountEditor *emae)
-{
- ESourceList *slist = NULL;
- ESourceGroup *sgrp;
- GSList *sources;
- gboolean source_already_exists = FALSE;
- CamelURL *url;
- gchar * username;
- EAccount *modified_account;
- GError *error = NULL;
-
- if (!e_client_utils_get_sources (&slist, E_CLIENT_SOURCE_TYPE_CONTACTS, &error) || !slist) {
- g_debug ("%s: Failed to get list of sources: %s", G_STRFUNC, error ? error->message : "Unknown error");
- g_clear_error (&error);
- return;
- }
-
- modified_account = em_account_editor_get_modified_account (emae);
- sgrp = e_source_list_ensure_group (slist, _("Google"), "google://", TRUE);
- url = emae_account_url (emae, E_ACCOUNT_SOURCE_URL);
- username = g_strdup (url->user);
-
- sources = e_source_group_peek_sources (sgrp);
- for (; sources; sources = sources->next) {
- ESource *existing = (ESource *) sources->data;
- if (!g_strcmp0 (e_source_peek_relative_uri (existing), username)) {
- source_already_exists = TRUE;
- break;
- }
- }
-
- if (!source_already_exists) {
- ESource *abook;
-
- abook = e_source_new (e_account_get_string (modified_account, E_ACCOUNT_NAME), "");
- e_source_set_property (abook, "default", "true");
- e_source_set_property (abook, "offline_sync", "1");
- e_source_set_property (abook, "auth", "plain/password");
- e_source_set_property (abook, "use-ssl", "true");
- e_source_set_property (abook, "remember_password", "true");
- e_source_set_property (abook, "refresh-interval", "86400");
- e_source_set_property (abook, "completion", "true");
- e_source_set_property (abook, "username", username);
-
- e_source_group_add_source (sgrp, abook, -1);
- e_source_set_relative_uri (abook, username);
- e_source_list_sync (slist, NULL);
-
- g_object_unref (abook);
- }
-
- g_free (username);
- g_object_unref (sgrp);
- g_object_unref (slist);
-}
-
-static void
-setup_google_calendar (EMAccountEditor *emae,
- EClientSourceType source_type)
-{
- ESourceList *slist = NULL;
- ESourceGroup *sgrp;
- ESource *calendar;
- gchar *sanitize_uname, *username;
- gchar *abs_uri, *rel_uri;
- gchar **ids;
- gint i;
- GPtrArray *array;
- CamelURL *url;
- GSettings *settings;
- EAccount *modified_account;
- GError *error = NULL;
-
- if (!e_client_utils_get_sources (&slist, source_type, &error) || !slist) {
- g_debug ("%s: Failed to get list of sources: %s", G_STRFUNC, error ? error->message : "Unknown error");
- g_clear_error (&error);
- return;
- }
-
- modified_account = em_account_editor_get_modified_account (emae);
- sgrp = e_source_list_ensure_group (slist, _("Google"), "google://", TRUE);
- url = emae_account_url (emae, E_ACCOUNT_SOURCE_URL);
- username = g_strdup (url->user);
-
- calendar = e_source_new (e_account_get_string (modified_account, E_ACCOUNT_NAME), "");
- e_source_set_property (calendar, "ssl", "1");
- e_source_set_property (calendar, "refresh", "30");
- e_source_set_property (calendar, "auth", "1");
- e_source_set_property (calendar, "offline_sync", "1");
- e_source_set_property (calendar, "username", username);
- e_source_set_property (calendar, "setup-username", username);
- e_source_set_property (calendar, "default", "true");
- e_source_set_property (calendar, "alarm", "true");
- e_source_set_readonly (calendar, FALSE);
-
- if (source_type != E_CLIENT_SOURCE_TYPE_CONTACTS)
- e_source_set_color_spec (calendar, "#CE9687");
-
- e_source_group_add_source (sgrp, calendar, -1);
-
- sanitize_uname = sanitize_user_mail (username);
-
- abs_uri = g_strdup_printf (CALENDAR_CALDAV_URI, sanitize_uname, username);
- e_source_set_absolute_uri (calendar, abs_uri);
-
- rel_uri = g_strconcat ("https", GMAIL_CALENDAR_LOCATION, sanitize_uname, CALENDAR_DEFAULT_PATH, NULL);
- e_source_set_relative_uri (calendar, rel_uri);
-
- e_source_list_sync (slist, NULL);
-
- settings = g_settings_new ("org.gnome.evolution.calendar");
- ids = g_settings_get_strv (settings, SELECTED_CALENDARS);
- array = g_ptr_array_new ();
- for (i = 0; ids[i] != NULL; i++)
- g_ptr_array_add (array, ids[i]);
- g_ptr_array_add (array, (gpointer) e_source_get_uid (calendar));
- g_ptr_array_add (array, NULL);
- g_settings_set_strv (
- settings, SELECTED_CALENDARS,
- (const gchar * const *) array->pdata);
-
- g_strfreev (ids);
- g_ptr_array_free (array, TRUE);
- g_object_unref (settings);
- g_free (username);
- g_free (abs_uri);
- g_free (rel_uri);
- g_free (sanitize_uname);
- g_object_unref (calendar);
- g_object_unref (sgrp);
- g_object_unref (slist);
-}
-
-static void
-setup_yahoo_calendar (EMAccountEditor *emae,
- EClientSourceType source_type)
-{
- ESourceList *slist = NULL;
- ESourceGroup *sgrp;
- ESource *calendar;
- gchar *sanitize_uname;
- gchar *abs_uri, *rel_uri;
- const gchar *email;
- GSettings *settings;
- gchar **ids;
- gint i;
- GPtrArray *array;
- EAccount *modified_account;
- GError *error = NULL;
-
- if (!e_client_utils_get_sources (&slist, source_type, &error) || !slist) {
- g_debug ("%s: Failed to get list of sources: %s", G_STRFUNC, error ? error->message : "Unknown error");
- g_clear_error (&error);
- return;
- }
-
- modified_account = em_account_editor_get_modified_account (emae);
- email = e_account_get_string (modified_account, E_ACCOUNT_ID_ADDRESS);
- sgrp = e_source_list_ensure_group (slist, _("CalDAV"), "caldav://", TRUE);
-
- calendar = e_source_new (e_account_get_string (modified_account, E_ACCOUNT_NAME), "");
- e_source_set_property (calendar, "ssl", "1");
- e_source_set_property (calendar, "refresh", "30");
- e_source_set_property (calendar, "refresh-type", "0");
- e_source_set_property (calendar, "auth", "1");
- e_source_set_property (calendar, "offline_sync", "1");
- e_source_set_property (calendar, "username", email);
- e_source_set_property (calendar, "default", "true");
- e_source_set_property (calendar, "alarm", "true");
- e_source_set_readonly (calendar, FALSE);
-
- if (source_type != E_CLIENT_SOURCE_TYPE_CONTACTS)
- e_source_set_color_spec (calendar, "#87CE8C");
-
- sanitize_uname = sanitize_user_mail (email);
-
- abs_uri = g_strdup_printf ("caldav://%s@caldav.calendar.yahoo.com/dav/%s/Calendar/%s",
- sanitize_uname, email, gtk_entry_get_text ((GtkEntry *) emae->priv->yahoo_cal_entry));
- rel_uri = g_strdup_printf (YAHOO_CALENDAR_LOCATION, sanitize_uname, email, gtk_entry_get_text ((GtkEntry *) emae->priv->yahoo_cal_entry));
- e_source_set_relative_uri (calendar, rel_uri);
-
- e_source_group_add_source (sgrp, calendar, -1);
- e_source_list_sync (slist, NULL);
-
- settings = g_settings_new ("org.gnome.evolution.calendar");
- ids = g_settings_get_strv (settings, SELECTED_CALENDARS);
- array = g_ptr_array_new ();
- for (i = 0; ids[i] != NULL; i++)
- g_ptr_array_add (array, ids[i]);
- g_ptr_array_add (array, (gpointer) e_source_get_uid (calendar));
- g_ptr_array_add (array, NULL);
- g_settings_set_strv (
- settings, SELECTED_CALENDARS,
- (const gchar * const *) array->pdata);
-
- g_strfreev (ids);
- g_ptr_array_free (array, TRUE);
- g_object_unref (settings);
- g_free (abs_uri);
- g_free (rel_uri);
- g_free (sanitize_uname);
- g_object_unref (calendar);
- g_object_unref (sgrp);
- g_object_unref (slist);
-}
-
-static void
-copy_param (GQuark key_id,
- gpointer data,
- gpointer user_data)
-{
- GData **copy = user_data;
-
- g_datalist_id_set_data_full (copy, key_id, g_strdup (data), g_free);
-}
-
-static void
-copy_original_url_parameters (CamelURL *copy_to_url,
- const gchar *copy_from)
-{
- CamelURL *url;
-
- g_return_if_fail (copy_to_url != NULL);
-
- if (!copy_from || !*copy_from)
- return;
-
- url = camel_url_new (copy_from, NULL);
- if (!url)
- return;
-
- if (url->params)
- g_datalist_foreach (&url->params, copy_param, &copy_to_url->params);
-
- camel_url_free (url);
-}
-
-static void
-emae_commit (EConfig *ec,
- EMAccountEditor *emae)
-{
- EAccountList *accounts = e_get_account_list ();
- EAccount *account;
- EAccount *modified_account;
- EAccount *original_account;
- CamelProvider *provider;
- CamelSettings *settings;
- CamelURL *url;
- const gchar *protocol;
- gboolean requires_auth;
-
- modified_account = em_account_editor_get_modified_account (emae);
- original_account = em_account_editor_get_original_account (emae);
- provider = emae_get_store_provider (emae);
-
- /* check for google and yahoo specific settings */
- if (!original_account && emae->priv->is_gmail) {
- if (gtk_toggle_button_get_active ((GtkToggleButton *) emae->priv->gcontacts))
- setup_google_addressbook (emae);
- if (gtk_toggle_button_get_active ((GtkToggleButton *) emae->priv->calendar))
- setup_google_calendar (emae, E_CLIENT_SOURCE_TYPE_EVENTS);
- } else if (!original_account && emae->priv->is_yahoo) {
- if (gtk_toggle_button_get_active ((GtkToggleButton *) emae->priv->calendar))
- setup_yahoo_calendar (emae, E_CLIENT_SOURCE_TYPE_EVENTS);
- if (gtk_toggle_button_get_active ((GtkToggleButton *) emae->priv->tasks))
- setup_yahoo_calendar (emae, E_CLIENT_SOURCE_TYPE_TASKS);
- }
-
- /* Do some last minute tweaking. */
-
- settings = emae->priv->source.settings;
- requires_auth = emae_get_store_requires_auth (emae);
-
- /* Override the selected authentication mechanism name if
- * authentication is not required for the storage service. */
- if (CAMEL_IS_NETWORK_SETTINGS (settings) && !requires_auth)
- g_object_set (settings, "auth-mechanism", NULL, NULL);
-
- settings = emae->priv->transport.settings;
- requires_auth = emae_get_transport_requires_auth (emae);
-
- /* Override the selected authentication mechanism name if
- * authentication is not required for the transport service. */
- if (CAMEL_IS_NETWORK_SETTINGS (settings) && !requires_auth)
- g_object_set (settings, "auth-mechanism", NULL, NULL);
-
- /* Dump the storage service settings to a URL string. */
-
- url = camel_url_new ("dummy://", NULL);
-
- protocol = emae->priv->source.protocol;
- settings = emae->priv->source.settings;
-
- if (g_strcmp0 (protocol, "none") == 0) {
- g_free (modified_account->source->url);
- modified_account->source->url = g_strdup ("");
- } else {
- if (protocol != NULL)
- camel_url_set_protocol (url, protocol);
-
- /* the CamelSaslXOAUTH stores its data into parameters
- * unknown to settings, thus copy these first and overwrite
- * those known during save */
- copy_original_url_parameters (url, modified_account->source->url);
-
- if (settings != NULL)
- camel_settings_save_to_url (settings, url);
-
- g_free (modified_account->source->url);
- modified_account->source->url = camel_url_to_string (url, 0);
- }
-
- camel_url_free (url);
-
- /* Dump the transport service settings to a URL string. */
-
- url = camel_url_new ("dummy://", NULL);
-
- if (!provider || !CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider))
- protocol = emae->priv->transport.protocol;
-
- settings = emae->priv->transport.settings;
-
- if (protocol != NULL)
- camel_url_set_protocol (url, protocol);
-
- /* the CamelSaslXOAUTH stores its data into parameters
- * unknown to settings, thus copy these first and overwrite
- * those known during save */
- copy_original_url_parameters (url, modified_account->transport->url);
-
- if (settings != NULL)
- camel_settings_save_to_url (settings, url);
-
- g_free (modified_account->transport->url);
- modified_account->transport->url = camel_url_to_string (url, 0);
-
- camel_url_free (url);
-
- if (original_account != NULL) {
- forget_password_if_needed (original_account, modified_account, E_ACCOUNT_SOURCE_SAVE_PASSWD, E_ACCOUNT_SOURCE_URL);
- forget_password_if_needed (original_account, modified_account, E_ACCOUNT_TRANSPORT_SAVE_PASSWD, E_ACCOUNT_TRANSPORT_URL);
-
- e_account_import (original_account, modified_account);
- account = original_account;
- e_account_list_change (accounts, account);
- } else {
- e_account_list_add (accounts, modified_account);
- account = modified_account;
- }
-
- if (gtk_toggle_button_get_active (emae->priv->default_account)) {
- EMailBackend *backend;
- EMailSession *session;
- EMailAccountStore *store;
- CamelService *service;
-
- backend = em_account_editor_get_backend (emae);
- session = e_mail_backend_get_session (backend);
-
- service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
-
- store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session));
- e_mail_account_store_set_default_service (store, service);
- }
-
- e_account_list_save (accounts);
-}
-
-void
-em_account_editor_commit (EMAccountEditor *emae)
-{
- emae_commit (E_CONFIG (emae->config), emae);
-}
-
-static void
-em_account_editor_construct (EMAccountEditor *emae,
- EMAccountEditorType type,
- const gchar *id)
-{
- EMAccountEditorPrivate *priv = emae->priv;
- gint i, index;
- GSList *l;
- GList *prov;
- EMConfig *ec;
- EMConfigTargetSettings *target;
- GHashTable *have;
- EConfigItem *items;
-
- emae->type = type;
-
- if (type == EMAE_NOTEBOOK) {
- ec = em_config_new (E_CONFIG_BOOK, id);
- items = emae_editor_items;
- if (!emae_editor_items_translated) {
- for (i = 0; items[i].path; i++) {
- if (items[i].label)
- items[i].label = gettext (items[i].label);
- }
- emae_editor_items_translated = TRUE;
- }
- } else {
- ec = em_config_new (E_CONFIG_ASSISTANT, id);
- items = emae_assistant_items;
- if (!emae_assistant_items_translated) {
- for (i = 0; items[i].path; i++) {
- if (items[i].label)
- items[i].label = _(items[i].label);
- }
- emae_assistant_items_translated = TRUE;
- }
- }
-
- /* Connect "after" to let plugins go first. */
- g_signal_connect_after (
- ec, "commit",
- G_CALLBACK (emae_commit), emae);
-
- g_object_weak_ref (G_OBJECT (ec), emae_config_gone_cb, emae);
-
- emae->config = priv->config = ec;
- l = NULL;
- for (i = 0; items[i].path; i++)
- l = g_slist_prepend (l, &items[i]);
- e_config_add_items ((EConfig *) ec, l, emae_free, emae);
-
- /* This is kinda yuck, we're dynamically mapping from the 'old style' extensibility api to the new one */
- l = NULL;
- have = g_hash_table_new (g_str_hash, g_str_equal);
- index = 20;
- for (prov = priv->providers; prov; prov = g_list_next (prov)) {
- CamelProviderConfEntry *entries = ((CamelProvider *) prov->data)->extra_conf;
-
- for (i = 0; entries && entries[i].type != CAMEL_PROVIDER_CONF_END; i++) {
- struct _receive_options_item *item;
- const gchar *name = entries[i].name;
- gint myindex = index;
-
- if (entries[i].type != CAMEL_PROVIDER_CONF_SECTION_START
- || name == NULL
- || g_hash_table_lookup (have, name))
- continue;
-
- /* override mailcheck since we also insert our own mailcheck item at this index */
- if (name && !strcmp (name, "mailcheck"))
- myindex = 10;
-
- item = g_malloc0 (sizeof (*item));
- item->item.type = E_CONFIG_SECTION_TABLE;
- item->item.path = g_strdup_printf ("20.receive_options/%02d.%s", myindex, name?name:"unnamed");
- item->item.label = g_strdup (entries[i].text);
-
- l = g_slist_prepend (l, item);
-
- item = g_malloc0 (sizeof (*item));
- item->item.type = E_CONFIG_ITEM_TABLE;
- item->item.path = g_strdup_printf ("20.receive_options/%02d.%s/80.camelitem", myindex, name?name:"unnamed");
- item->item.factory = emae_receive_options_extra_item;
- item->item.user_data = g_strdup (entries[i].name);
-
- l = g_slist_prepend (l, item);
-
- index += 10;
- g_hash_table_insert (have, (gpointer) entries[i].name, have);
- }
- }
- g_hash_table_destroy (have);
- e_config_add_items ((EConfig *) ec, l, emae_free_auto, emae);
- priv->extra_items = l;
-
- e_config_add_page_check ((EConfig *) ec, NULL, emae_check_complete, emae);
-
- target = em_config_target_new_settings (
- ec,
- emae->priv->modified_account->id->address,
- emae->priv->source.protocol,
- emae->priv->source.settings,
- emae->priv->transport.protocol,
- emae->priv->transport.settings);
- e_config_set_target ((EConfig *) ec, (EConfigTarget *) target);
-}
-
diff --git a/mail/em-account-editor.h b/mail/em-account-editor.h
deleted file mode 100644
index 18d4b91f9e..0000000000
--- a/mail/em-account-editor.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Jeffrey Stedfast <fejj@ximian.com>
- * Dan Winship <danw@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef EM_ACCOUNT_EDITOR_H
-#define EM_ACCOUNT_EDITOR_H
-
-#include <gtk/gtk.h>
-#include <mail/em-config.h>
-#include <mail/e-mail-backend.h>
-
-#include <libedataserver/e-account.h>
-
-/* Standard GObject macros */
-#define EM_TYPE_ACCOUNT_EDITOR \
- (em_account_editor_get_type ())
-#define EM_ACCOUNT_EDITOR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditor))
-#define EM_ACCOUNT_EDITOR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorClass))
-#define EM_IS_ACCOUNT_EDITOR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), EM_TYPE_ACCOUNT_EDITOR))
-#define EM_IS_ACCOUNT_EDITOR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), EM_TYPE_ACCOUNT_EDITOR))
-#define EM_ACCOUNT_EDITOR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), EM_TYPE_ACCOUNT_EDITOR, EMAccountEditorClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EMAccountEditor EMAccountEditor;
-typedef struct _EMAccountEditorClass EMAccountEditorClass;
-typedef struct _EMAccountEditorPrivate EMAccountEditorPrivate;
-
-typedef struct _server_data ServerData;
-struct _server_data {
- const gchar *key;
- const gchar *recv;
- const gchar *send;
- const gchar *proto;
- CamelNetworkSecurityMethod security_method;
- const gchar *send_user;
- const gchar *recv_user;
- const gchar *send_port;
- const gchar *recv_port;
- CamelNetworkSecurityMethod send_security_method;
- CamelNetworkSecurityMethod recv_security_method;
- const gchar *send_auth;
- const gchar *recv_auth;
-};
-
-typedef enum {
- EMAE_NOTEBOOK,
- EMAE_ASSISTANT,
- EMAE_PAGES
-} EMAccountEditorType;
-
-struct _EMAccountEditor {
- GObject parent;
-
- EMAccountEditorPrivate *priv;
-
- EMAccountEditorType type;
-
- EMConfig *config; /* driver object */
-
- GtkWidget **pages; /* Pages for Anjal's page type editor */
-
- guint do_signature:1; /* allow editing signature */
-};
-
-struct _EMAccountEditorClass {
- GObjectClass parent_class;
-};
-
-GType em_account_editor_get_type (void);
-EMAccountEditor *
- em_account_editor_new (EAccount *account,
- EMAccountEditorType type,
- EMailBackend *backend,
- const gchar *id);
-EMAccountEditor *
- em_account_editor_new_for_pages (EAccount *account,
- EMAccountEditorType type,
- EMailBackend *backend,
- const gchar *id,
- GtkWidget **pages);
-EMailBackend * em_account_editor_get_backend (EMAccountEditor *emae);
-EAccount * em_account_editor_get_modified_account
- (EMAccountEditor *emae);
-EAccount * em_account_editor_get_original_account
- (EMAccountEditor *emae);
-void em_account_editor_commit (EMAccountEditor *emae);
-gboolean em_account_editor_check (EMAccountEditor *emae,
- const gchar *page);
-GtkWidget * em_account_editor_get_widget (EMAccountEditor *emae,
- const gchar *name);
-
-G_END_DECLS
-
-#endif /* EM_ACCOUNT_EDITOR_H */
diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c
index 7ea31635e6..a39a5f834d 100644
--- a/mail/em-composer-utils.c
+++ b/mail/em-composer-utils.c
@@ -31,17 +31,22 @@
#include <glib/gi18n.h>
#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-source-mdn.h>
#include <libevolution-utils/e-alert-dialog.h>
#include <libevolution-utils/e-alert-sink.h>
#include <e-util/e-util.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-utils/mail-mt.h>
#include <libemail-engine/e-mail-folder-utils.h>
#include <libemail-engine/e-mail-session.h>
#include <libemail-engine/e-mail-session-utils.h>
+#include <libemail-engine/e-mail-utils.h>
#include <libemail-engine/mail-ops.h>
#include <libemail-engine/mail-tools.h>
@@ -366,23 +371,31 @@ finished:
}
static gboolean
-composer_presend_check_account (EMsgComposer *composer,
- EMailSession *session)
+composer_presend_check_identity (EMsgComposer *composer,
+ EMailSession *session)
{
EComposerHeaderTable *table;
- EAccount *account;
- gboolean check_passed;
+ ESourceRegistry *registry;
+ ESource *source;
+ const gchar *uid;
+ gboolean success = TRUE;
table = e_msg_composer_get_header_table (composer);
- account = e_composer_header_table_get_account (table);
- check_passed = (account != NULL && account->enabled);
+ registry = e_composer_header_table_get_registry (table);
+ uid = e_composer_header_table_get_identity_uid (table);
+ source = e_source_registry_ref_source (registry, uid);
+ g_return_val_if_fail (source != NULL, FALSE);
- if (!check_passed)
+ if (!e_source_get_enabled (source)) {
e_alert_submit (
E_ALERT_SINK (composer),
"mail:send-no-account-enabled", NULL);
+ success = FALSE;
+ }
- return check_passed;
+ g_object_unref (source);
+
+ return success;
}
static gboolean
@@ -812,9 +825,11 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
{
AsyncContext *context;
EComposerHeaderTable *table;
- const gchar *drafts_folder_uri = NULL;
+ ESourceRegistry *registry;
+ ESource *source;
const gchar *local_drafts_folder_uri;
- EAccount *account;
+ const gchar *identity_uid;
+ gchar *drafts_folder_uri = NULL;
context = g_slice_new0 (AsyncContext);
context->message = g_object_ref (message);
@@ -822,18 +837,30 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
context->composer = g_object_ref (composer);
context->activity = g_object_ref (activity);
- local_drafts_folder_uri =
- e_mail_session_get_local_folder_uri (
- session, E_MAIL_LOCAL_FOLDER_DRAFTS);
-
table = e_msg_composer_get_header_table (composer);
- account = e_composer_header_table_get_account (table);
- if (account != NULL && account->enabled)
- drafts_folder_uri = account->drafts_folder_uri;
+ registry = e_composer_header_table_get_registry (table);
+ identity_uid = e_composer_header_table_get_identity_uid (table);
+ source = e_source_registry_ref_source (registry, identity_uid);
+
+ /* Get the selected identity's preferred Drafts folder. */
+ if (source != NULL) {
+ ESourceMailComposition *extension;
+ const gchar *extension_name;
+ gchar *uri;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ extension = e_source_get_extension (source, extension_name);
+ uri = e_source_mail_composition_dup_drafts_folder (extension);
+
+ drafts_folder_uri = uri;
- if (g_strcmp0 (drafts_folder_uri, local_drafts_folder_uri) == 0)
- drafts_folder_uri = NULL;
+ g_object_unref (source);
+ }
+
+ local_drafts_folder_uri =
+ e_mail_session_get_local_folder_uri (
+ session, E_MAIL_LOCAL_FOLDER_DRAFTS);
if (drafts_folder_uri == NULL) {
composer_save_to_drafts_append_mail (context, NULL);
@@ -849,6 +876,8 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
G_PRIORITY_DEFAULT, cancellable,
(GAsyncReadyCallback)
composer_save_to_drafts_got_folder, context);
+
+ g_free (drafts_folder_uri);
}
}
@@ -976,22 +1005,23 @@ create_new_composer (EShell *shell,
CamelFolder *folder)
{
EMsgComposer *composer;
+ ESourceRegistry *registry;
EComposerHeaderTable *table;
- EAccount *account = NULL;
+ ESource *source = NULL;
+ gchar *identity = NULL;
composer = e_msg_composer_new (shell);
table = e_msg_composer_get_header_table (composer);
+ registry = e_composer_header_table_get_registry (table);
if (folder != NULL) {
CamelStore *store;
- const gchar *uid;
gchar *folder_uri;
GList *list;
store = camel_folder_get_parent_store (folder);
- uid = camel_service_get_uid (CAMEL_SERVICE (store));
- account = e_get_account_by_uid (uid);
+ source = em_utils_ref_mail_identity_for_store (registry, store);
folder_uri = e_mail_folder_uri_from_folder (folder);
@@ -1002,8 +1032,15 @@ create_new_composer (EShell *shell,
g_free (folder_uri);
}
- e_composer_header_table_set_account (table, account);
+ if (source != NULL) {
+ identity = e_source_dup_uid (source);
+ g_object_unref (source);
+ }
+
e_composer_header_table_set_subject (table, subject);
+ e_composer_header_table_set_identity_uid (table, identity);
+
+ g_free (identity);
return composer;
}
@@ -1049,8 +1086,8 @@ em_utils_compose_new_message_with_mailto (EShell *shell,
CamelFolder *folder)
{
EMsgComposer *composer;
+ ESourceRegistry *registry;
EComposerHeaderTable *table;
- CamelService *service = NULL;
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
@@ -1063,25 +1100,29 @@ em_utils_compose_new_message_with_mailto (EShell *shell,
composer = e_msg_composer_new (shell);
table = e_msg_composer_get_header_table (composer);
+ registry = e_composer_header_table_get_registry (table);
+
+ composer_set_no_change (composer);
+
+ gtk_window_present (GTK_WINDOW (composer));
+
+ /* If a CamelFolder was given, we need to backtrack and find
+ * the corresponding ESource with a Mail Identity extension. */
if (folder != NULL) {
+ ESource *source;
CamelStore *store;
store = camel_folder_get_parent_store (folder);
- service = CAMEL_SERVICE (store);
- }
-
- if (service != NULL) {
- const gchar *display_name;
+ source = em_utils_ref_mail_identity_for_store (registry, store);
- display_name = camel_service_get_display_name (service);
- e_composer_header_table_set_account_name (table, display_name);
+ if (source != NULL) {
+ const gchar *uid = e_source_get_uid (source);
+ e_composer_header_table_set_identity_uid (table, uid);
+ g_object_unref (source);
+ }
}
- composer_set_no_change (composer);
-
- gtk_window_present (GTK_WINDOW (composer));
-
return composer;
}
@@ -1302,6 +1343,7 @@ em_utils_edit_message (EShell *shell,
const gchar *message_uid)
{
EMsgComposer *composer;
+ ESourceRegistry *registry;
gboolean folder_is_drafts;
gboolean folder_is_outbox;
gboolean folder_is_templates;
@@ -1310,9 +1352,10 @@ em_utils_edit_message (EShell *shell,
g_return_val_if_fail (CAMEL_IS_FOLDER (folder), NULL);
g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL);
- folder_is_drafts = em_utils_folder_is_drafts (folder);
- folder_is_outbox = em_utils_folder_is_outbox (folder);
- folder_is_templates = em_utils_folder_is_templates (folder);
+ registry = e_shell_get_registry (shell);
+ folder_is_drafts = em_utils_folder_is_drafts (registry, folder);
+ folder_is_outbox = em_utils_folder_is_outbox (registry, folder);
+ folder_is_templates = em_utils_folder_is_templates (registry, folder);
/* Template specific code follows. */
if (folder_is_templates) {
@@ -1339,19 +1382,23 @@ em_utils_edit_message (EShell *shell,
}
composer = e_msg_composer_new_with_message (shell, message, NULL);
- if (folder && !folder_is_templates) {
+ if (!folder_is_templates) {
EComposerHeaderTable *table;
- EAccount *account;
+ ESource *source;
CamelStore *store;
- const gchar *uid;
gchar *folder_uri;
GList *list;
table = e_msg_composer_get_header_table (composer);
store = camel_folder_get_parent_store (folder);
- uid = camel_service_get_uid (CAMEL_SERVICE (store));
- account = e_get_account_by_uid (uid);
+ source = em_utils_ref_mail_identity_for_store (registry, store);
+
+ if (source != NULL) {
+ const gchar *uid = e_source_get_uid (source);
+ e_composer_header_table_set_identity_uid (table, uid);
+ g_object_unref (source);
+ }
folder_uri = e_mail_folder_uri_from_folder (folder);
@@ -1360,8 +1407,6 @@ em_utils_edit_message (EShell *shell,
g_list_free (list);
g_free (folder_uri);
-
- e_composer_header_table_set_account (table, account);
}
e_msg_composer_remove_header (
@@ -1902,8 +1947,11 @@ static EMsgComposer *
redirect_get_composer (EShell *shell,
CamelMimeMessage *message)
{
+ EMsgComposer *composer;
+ ESourceRegistry *registry;
CamelMedium *medium;
- EAccount *account;
+ ESource *source;
+ gchar *identity_uid = NULL;
medium = CAMEL_MEDIUM (message);
@@ -1919,10 +1967,23 @@ redirect_get_composer (EShell *shell,
while (camel_medium_get_header (medium, "Resent-Bcc"))
camel_medium_remove_header (medium, "Resent-Bcc");
- account = em_utils_guess_account_with_recipients (message, NULL);
+ registry = e_shell_get_registry (shell);
+
+ /* This returns a new ESource reference. */
+ source = em_utils_guess_mail_identity_with_recipients (
+ registry, message, NULL);
+
+ if (source != NULL) {
+ identity_uid = e_source_dup_uid (source);
+ g_object_unref (source);
+ }
- return e_msg_composer_new_redirect (
- shell, message, account ? account->name : NULL, NULL);
+ composer = e_msg_composer_new_redirect (
+ shell, message, identity_uid, NULL);
+
+ g_free (identity_uid);
+
+ return composer;
}
/**
@@ -1989,7 +2050,7 @@ em_utils_camel_address_to_destination (CamelInternetAddress *iaddr)
static EMsgComposer *
reply_get_composer (EShell *shell,
CamelMimeMessage *message,
- EAccount *account,
+ const gchar *identity_uid,
CamelInternetAddress *to,
CamelInternetAddress *cc,
CamelFolder *folder,
@@ -2030,9 +2091,9 @@ reply_get_composer (EShell *shell,
}
table = e_msg_composer_get_header_table (composer);
- e_composer_header_table_set_account (table, account);
e_composer_header_table_set_subject (table, subject);
e_composer_header_table_set_destinations_to (table, tov);
+ e_composer_header_table_set_identity_uid (table, identity_uid);
/* Add destinations instead of setting, so we don't remove
* automatic CC addresses that have already been added. */
@@ -2311,64 +2372,6 @@ get_reply_recipient (CamelMimeMessage *message,
}
-static GHashTable *
-generate_recipient_hash (void)
-{
- GHashTable *rcpt_hash;
- EAccount *account, *def;
- EAccountList *account_list;
- EIterator *iterator;
-
- account_list = e_get_account_list ();
- rcpt_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
-
- def = e_get_default_account ();
-
- iterator = e_list_get_iterator (E_LIST (account_list));
-
- while (e_iterator_is_valid (iterator)) {
- account = (EAccount *) e_iterator_get (iterator);
-
- if (account->id->address) {
- EAccount *acnt;
-
- /* Accounts with identical email addresses that are
- * enabled take precedence over the accounts that
- * aren't. If all accounts with matching email
- * addresses are disabled, then the first one in
- * the list takes precedence. The default account
- * always takes precedence no matter what. */
- acnt = g_hash_table_lookup (
- rcpt_hash, account->id->address);
- if (acnt && acnt != def && !acnt->enabled && account->enabled) {
- g_hash_table_remove (
- rcpt_hash, acnt->id->address);
- acnt = NULL;
- }
-
- if (!acnt)
- g_hash_table_insert (
- rcpt_hash, (gchar *)
- account->id->address,
- (gpointer) account);
- }
-
- e_iterator_next (iterator);
- }
-
- g_object_unref (iterator);
-
- /* The default account has to be there if none
- * of the enabled accounts are present. */
- if (g_hash_table_size (rcpt_hash) == 0 && def && def->id->address)
- g_hash_table_insert (
- rcpt_hash, (gchar *)
- def->id->address,
- (gpointer) def);
-
- return rcpt_hash;
-}
-
static void
concat_unique_addrs (CamelInternetAddress *dest,
CamelInternetAddress *src,
@@ -2385,8 +2388,91 @@ concat_unique_addrs (CamelInternetAddress *dest,
}
}
+static GHashTable *
+generate_recipient_hash (ESourceRegistry *registry)
+{
+ GHashTable *rcpt_hash;
+ ESource *default_source;
+ GList *list, *link;
+ const gchar *extension_name;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ rcpt_hash = g_hash_table_new (
+ (GHashFunc) camel_strcase_hash,
+ (GEqualFunc) camel_strcase_equal);
+
+ default_source = e_source_registry_ref_default_mail_identity (registry);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESource *cached_source;
+ ESourceMailIdentity *extension;
+ const gchar *address;
+ gboolean insert_source;
+ gboolean cached_is_default;
+ gboolean cached_is_enabled;
+ gboolean source_is_default;
+ gboolean source_is_enabled;
+
+ /* No default mail identity implies there are no mail
+ * identities at all and so we should never get here. */
+ g_warn_if_fail (default_source != NULL);
+
+ source_is_default = e_source_equal (source, default_source);
+ source_is_enabled = e_source_get_enabled (source);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (source, extension_name);
+
+ address = e_source_mail_identity_get_address (extension);
+
+ if (address == NULL)
+ continue;
+
+ cached_source = g_hash_table_lookup (rcpt_hash, address);
+
+ if (cached_source != NULL) {
+ cached_is_default = e_source_equal (
+ cached_source, default_source);
+ cached_is_enabled =
+ e_source_get_enabled (cached_source);
+ } else {
+ cached_is_default = FALSE;
+ cached_is_enabled = FALSE;
+ }
+
+ /* Accounts with identical email addresses that are enabled
+ * take precedence over disabled accounts. If all accounts
+ * with matching email addresses are disabled, the first
+ * one in the list takes precedence. The default account
+ * always takes precedence no matter what. */
+ insert_source =
+ source_is_default ||
+ cached_source == NULL ||
+ (source_is_enabled &&
+ !cached_is_enabled &&
+ !cached_is_default);
+
+ if (insert_source)
+ g_hash_table_insert (
+ rcpt_hash, (gchar *) address, source);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ if (default_source != NULL)
+ g_object_unref (default_source);
+
+ return rcpt_hash;
+}
+
void
-em_utils_get_reply_all (CamelMimeMessage *message,
+em_utils_get_reply_all (ESourceRegistry *registry,
+ CamelMimeMessage *message,
CamelInternetAddress *to,
CamelInternetAddress *cc,
CamelNNTPAddress *postto)
@@ -2399,6 +2485,7 @@ em_utils_get_reply_all (CamelMimeMessage *message,
const gchar *posthdr = NULL;
GHashTable *rcpt_hash;
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));
g_return_if_fail (CAMEL_IS_INTERNET_ADDRESS (to));
g_return_if_fail (CAMEL_IS_INTERNET_ADDRESS (cc));
@@ -2415,7 +2502,7 @@ em_utils_get_reply_all (CamelMimeMessage *message,
if (postto != NULL && posthdr != NULL)
camel_address_decode (CAMEL_ADDRESS (postto), posthdr);
- rcpt_hash = generate_recipient_hash ();
+ rcpt_hash = generate_recipient_hash (registry);
reply_to = get_reply_to (message);
to_addrs = camel_mime_message_get_recipients (
@@ -2804,10 +2891,12 @@ em_utils_reply_to_message (EShell *shell,
EMFormat *source_formatter,
CamelInternetAddress *address)
{
+ ESourceRegistry *registry;
CamelInternetAddress *to, *cc;
CamelNNTPAddress *postto = NULL;
EMsgComposer *composer;
- EAccount *account;
+ ESource *source;
+ gchar *identity_uid = NULL;
guint32 flags;
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
@@ -2816,11 +2905,20 @@ em_utils_reply_to_message (EShell *shell,
to = camel_internet_address_new ();
cc = camel_internet_address_new ();
- account = em_utils_guess_account_with_recipients (message, folder);
+ registry = e_shell_get_registry (shell);
+
+ /* This returns a new ESource reference. */
+ source = em_utils_guess_mail_identity_with_recipients (
+ registry, message, folder);
+ if (source != NULL) {
+ identity_uid = e_source_dup_uid (source);
+ g_object_unref (source);
+ }
+
flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN;
if (!address && (type == E_MAIL_REPLY_TO_FROM || type == E_MAIL_REPLY_TO_SENDER) &&
- folder && em_utils_folder_is_sent (folder))
+ folder && em_utils_folder_is_sent (registry, folder))
type = E_MAIL_REPLY_TO_ALL;
switch (type) {
@@ -2852,12 +2950,12 @@ em_utils_reply_to_message (EShell *shell,
if (folder)
postto = camel_nntp_address_new ();
- em_utils_get_reply_all (message, to, cc, postto);
+ em_utils_get_reply_all (registry, message, to, cc, postto);
break;
}
composer = reply_get_composer (
- shell, message, account, to, cc, folder, postto);
+ shell, message, identity_uid, to, cc, folder, postto);
e_msg_composer_add_message_attachments (composer, message, TRUE);
if (postto)
@@ -2882,6 +2980,8 @@ em_utils_reply_to_message (EShell *shell,
gtk_widget_show (GTK_WIDGET (composer));
+ g_free (identity_uid);
+
return composer;
}
@@ -2969,7 +3069,7 @@ em_configure_new_composer (EMsgComposer *composer,
g_signal_connect (
composer, "presend",
- G_CALLBACK (composer_presend_check_account), session);
+ G_CALLBACK (composer_presend_check_identity), session);
g_signal_connect (
composer, "presend",
diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h
index 865254ca31..a525cec2a2 100644
--- a/mail/em-composer-utils.h
+++ b/mail/em-composer-utils.h
@@ -67,7 +67,8 @@ gboolean em_utils_is_munged_list_message (CamelMimeMessage *message);
void em_utils_get_reply_sender (CamelMimeMessage *message,
CamelInternetAddress *to,
CamelNNTPAddress *postto);
-void em_utils_get_reply_all (CamelMimeMessage *message,
+void em_utils_get_reply_all (ESourceRegistry *registry,
+ CamelMimeMessage *message,
CamelInternetAddress *to,
CamelInternetAddress *cc,
CamelNNTPAddress *postto);
diff --git a/mail/em-filter-source-element.c b/mail/em-filter-source-element.c
index 5848f938db..4362b11dc2 100644
--- a/mail/em-filter-source-element.c
+++ b/mail/em-filter-source-element.c
@@ -32,23 +32,18 @@
#include <gtk/gtk.h>
#include <camel/camel.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-identity.h>
+
+#include <shell/e-shell.h>
#include <filter/e-filter-part.h>
-#include <libemail-utils/e-account-utils.h>
#define EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), EM_TYPE_FILTER_SOURCE_ELEMENT, EMFilterSourceElementPrivate))
-typedef struct _SourceInfo {
- gchar *account_name;
- gchar *name;
- gchar *address;
- gchar *uid;
-} SourceInfo;
-
struct _EMFilterSourceElementPrivate {
EMailSession *session;
- GList *sources;
gchar *active_id;
};
@@ -63,16 +58,6 @@ enum {
};
static void
-source_info_free (SourceInfo *info)
-{
- g_free (info->account_name);
- g_free (info->name);
- g_free (info->address);
- g_free (info->uid);
- g_free (info);
-}
-
-static void
filter_source_element_source_changed (GtkComboBox *combo_box,
EMFilterSourceElement *fs)
{
@@ -85,52 +70,6 @@ filter_source_element_source_changed (GtkComboBox *combo_box,
}
static void
-filter_source_element_add_source (EMFilterSourceElement *fs,
- const gchar *account_name,
- const gchar *name,
- const gchar *addr,
- const gchar *uid)
-{
- SourceInfo *info;
-
- g_return_if_fail (EM_IS_FILTER_SOURCE_ELEMENT (fs));
-
- info = g_new0 (SourceInfo, 1);
- info->account_name = g_strdup (account_name);
- info->name = g_strdup (name);
- info->address = g_strdup (addr);
- info->uid = g_strdup (uid);
-
- fs->priv->sources = g_list_append (fs->priv->sources, info);
-}
-
-static void
-filter_source_element_get_sources (EMFilterSourceElement *fs)
-{
- EAccountList *accounts;
- const EAccount *account;
- EIterator *it;
-
- /* should this get the global object from mail? */
- accounts = e_get_account_list ();
-
- for (it = e_list_get_iterator ((EList *) accounts);
- e_iterator_is_valid (it);
- e_iterator_next (it)) {
- account = (const EAccount *) e_iterator_get (it);
-
- if (account->source == NULL)
- continue;
-
- filter_source_element_add_source (
- fs, account->name, account->id->name,
- account->id->address, account->uid);
- }
-
- g_object_unref (it);
-}
-
-static void
filter_source_element_set_session (EMFilterSourceElement *element,
EMailSession *session)
{
@@ -198,8 +137,6 @@ filter_source_element_finalize (GObject *object)
priv = EM_FILTER_SOURCE_ELEMENT_GET_PRIVATE (object);
- g_list_foreach (priv->sources, (GFunc) source_info_free, NULL);
- g_list_free (priv->sources);
g_free (priv->active_id);
/* Chain up to parent's finalize() method. */
@@ -305,7 +242,6 @@ filter_source_element_clone (EFilterElement *fe)
EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
EMFilterSourceElement *cpy;
EMailSession *session;
- GList *i;
session = em_filter_source_element_get_session (fs);
cpy = (EMFilterSourceElement *) em_filter_source_element_new (session);
@@ -313,13 +249,6 @@ filter_source_element_clone (EFilterElement *fe)
cpy->priv->active_id = g_strdup (fs->priv->active_id);
- for (i = fs->priv->sources; i != NULL; i = g_list_next (i)) {
- SourceInfo *info = (SourceInfo *) i->data;
- filter_source_element_add_source (
- cpy, info->account_name, info->name,
- info->address, info->uid);
- }
-
return (EFilterElement *) cpy;
}
@@ -327,29 +256,42 @@ static GtkWidget *
filter_source_element_get_widget (EFilterElement *fe)
{
EMFilterSourceElement *fs = (EMFilterSourceElement *) fe;
+ EMailSession *session;
+ ESourceRegistry *registry;
+ GList *list, *link;
GtkWidget *widget;
GtkComboBox *combo_box;
- GList *i;
-
- if (fs->priv->sources == NULL)
- filter_source_element_get_sources (fs);
+ const gchar *extension_name;
widget = gtk_combo_box_text_new ();
combo_box = GTK_COMBO_BOX (widget);
- for (i = fs->priv->sources; i != NULL; i = g_list_next (i)) {
- SourceInfo *info = (SourceInfo *) i->data;
+ session = em_filter_source_element_get_session (fs);
+ registry = e_mail_session_get_registry (session);
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (link = list; link != NULL; link = g_list_next (link)) {
+ ESource *source = E_SOURCE (link->data);
+ ESourceMailIdentity *extension;
const gchar *display_name;
const gchar *address;
const gchar *name;
const gchar *uid;
gchar *label;
- uid = info->uid;
- display_name = info->account_name;
+ uid = e_source_get_uid (source);
+ display_name = e_source_get_display_name (source);
- name = info->name;
- address = info->address;
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
+ extension = e_source_get_extension (source, extension_name);
+
+ name = e_source_mail_identity_get_name (extension);
+ address = e_source_mail_identity_get_address (extension);
+
+ if (name == NULL || address == NULL)
+ continue;
if (g_strcmp0 (display_name, address) == 0)
label = g_strdup_printf (
@@ -365,6 +307,8 @@ filter_source_element_get_widget (EFilterElement *fe)
g_free (label);
}
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
if (fs->priv->active_id != NULL) {
gtk_combo_box_set_active_id (combo_box, fs->priv->active_id);
} else {
diff --git a/mail/em-folder-tree-model.c b/mail/em-folder-tree-model.c
index 20337c54d8..d533c47fea 100644
--- a/mail/em-folder-tree-model.c
+++ b/mail/em-folder-tree-model.c
@@ -36,10 +36,14 @@
#include <glib/gi18n.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+
#include <e-util/e-util.h>
#include <shell/e-shell.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-utils/mail-mt.h>
#include <libemail-engine/e-mail-folder-utils.h>
@@ -605,6 +609,64 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model,
g_object_notify (G_OBJECT (model), "session");
}
+/* Helper for em_folder_tree_model_set_folder_info() */
+static void
+folder_tree_model_get_drafts_folder_uri (ESourceRegistry *registry,
+ CamelStore *store,
+ gchar **drafts_folder_uri)
+{
+ ESource *source;
+ const gchar *extension_name;
+
+ /* In case we fail... */
+ *drafts_folder_uri = NULL;
+
+ source = em_utils_ref_mail_identity_for_store (registry, store);
+ if (source == NULL)
+ return;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
+ if (e_source_has_extension (source, extension_name)) {
+ ESourceMailComposition *extension;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ *drafts_folder_uri =
+ e_source_mail_composition_dup_drafts_folder (extension);
+ }
+
+ g_object_unref (source);
+}
+
+/* Helper for em_folder_tree_model_set_folder_info() */
+static void
+folder_tree_model_get_sent_folder_uri (ESourceRegistry *registry,
+ CamelStore *store,
+ gchar **sent_folder_uri)
+{
+ ESource *source;
+ const gchar *extension_name;
+
+ /* In case we fail... */
+ *sent_folder_uri = NULL;
+
+ source = em_utils_ref_mail_identity_for_store (registry, store);
+ if (source == NULL)
+ return;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ if (e_source_has_extension (source, extension_name)) {
+ ESourceMailSubmission *extension;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ *sent_folder_uri =
+ e_source_mail_submission_dup_sent_folder (extension);
+ }
+
+ g_object_unref (source);
+}
+
void
em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
GtkTreeIter *iter,
@@ -615,8 +677,8 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
GtkTreeRowReference *path_row;
GtkTreeStore *tree_store;
MailFolderCache *folder_cache;
+ ESourceRegistry *registry;
EMailSession *session;
- EAccount *account;
guint unread;
GtkTreePath *path;
GtkTreeIter sub;
@@ -642,10 +704,10 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
session = em_folder_tree_model_get_session (model);
folder_cache = e_mail_session_get_folder_cache (session);
+ registry = e_mail_session_get_registry (session);
uid = camel_service_get_uid (CAMEL_SERVICE (si->store));
store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);
- account = e_get_account_by_uid (uid);
if (!fully_loaded)
load = (fi->child == NULL) && !(fi->flags &
@@ -668,8 +730,8 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
unread = fi->unread;
if (mail_folder_cache_get_folder_from_uri (
folder_cache, uri, &folder) && folder) {
- folder_is_drafts = em_utils_folder_is_drafts (folder);
- folder_is_outbox = em_utils_folder_is_outbox (folder);
+ folder_is_drafts = em_utils_folder_is_drafts (registry, folder);
+ folder_is_outbox = em_utils_folder_is_outbox (registry, folder);
if (folder_is_drafts || folder_is_outbox) {
gint total;
@@ -712,20 +774,32 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model,
}
}
- if (account != NULL && (flags & CAMEL_FOLDER_TYPE_MASK) == 0) {
- if (!folder_is_drafts && account->drafts_folder_uri != NULL) {
+ if ((flags & CAMEL_FOLDER_TYPE_MASK) == 0) {
+ gchar *drafts_folder_uri;
+ gchar *sent_folder_uri;
+
+ folder_tree_model_get_drafts_folder_uri (
+ registry, si->store, &drafts_folder_uri);
+
+ folder_tree_model_get_sent_folder_uri (
+ registry, si->store, &sent_folder_uri);
+
+ if (!folder_is_drafts && drafts_folder_uri != NULL) {
folder_is_drafts = e_mail_folder_uri_equal (
- CAMEL_SESSION (session), uri,
- account->drafts_folder_uri);
+ CAMEL_SESSION (session),
+ uri, drafts_folder_uri);
}
- if (account->sent_folder_uri != NULL) {
+ if (sent_folder_uri != NULL) {
if (e_mail_folder_uri_equal (
- CAMEL_SESSION (session), uri,
- account->sent_folder_uri)) {
+ CAMEL_SESSION (session),
+ uri, sent_folder_uri)) {
add_flags = CAMEL_FOLDER_TYPE_SENT;
}
}
+
+ g_free (drafts_folder_uri);
+ g_free (sent_folder_uri);
}
/* Choose an icon name for the folder. */
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 0c55ecec5f..f60346dc24 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -1546,17 +1546,22 @@ efh_write_attachment (EMFormat *emf,
static void
efh_preparse (EMFormat *emf)
{
- CamelInternetAddress *addr;
-
EMFormatHTML *efh = EM_FORMAT_HTML (emf);
+ CamelInternetAddress *addr;
+ CamelSession *session;
+ ESourceRegistry *registry;
if (!emf->message) {
efh->priv->can_load_images = FALSE;
return;
}
+ session = em_format_get_session (emf);
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
addr = camel_mime_message_get_from (emf->message);
- efh->priv->can_load_images = em_utils_in_addressbook (addr, FALSE);
+ efh->priv->can_load_images = em_utils_in_addressbook (
+ registry, addr, FALSE);
}
static void
@@ -2678,6 +2683,8 @@ efh_format_full_headers (EMFormatHTML *efh,
gboolean have_icon = FALSE;
const gchar *photo_name = NULL;
CamelInternetAddress *cia = NULL;
+ CamelSession *session;
+ ESourceRegistry *registry;
gboolean face_decoded = FALSE, contact_has_photo = FALSE;
guchar *face_header_value = NULL;
gsize face_header_len = 0;
@@ -2689,6 +2696,9 @@ efh_format_full_headers (EMFormatHTML *efh,
if (cancellable && g_cancellable_is_cancelled (cancellable))
return;
+ session = em_format_get_session (emf);
+ registry = e_mail_session_get_registry (E_MAIL_SESSION (session));
+
ct = camel_mime_part_get_content_type ((CamelMimePart *) part);
charset = camel_content_type_param (ct, "charset");
charset = camel_iconv_charset_name (charset);
@@ -2871,7 +2881,8 @@ efh_format_full_headers (EMFormatHTML *efh,
camel_address_decode ((CamelAddress *) cia, (const gchar *) photo_name);
only_local_photo =
em_format_html_get_only_local_photos (efh);
- photopart = em_utils_contact_photo (cia, only_local_photo);
+ photopart = em_utils_contact_photo (
+ registry, cia, only_local_photo);
if (photopart) {
g_string_append (buffer, "<td align=\"right\" valign=\"top\">");
diff --git a/mail/em-subscription-editor.c b/mail/em-subscription-editor.c
index f695a88d87..8221115c46 100644
--- a/mail/em-subscription-editor.c
+++ b/mail/em-subscription-editor.c
@@ -25,7 +25,6 @@
#include <string.h>
#include <glib/gi18n-lib.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-utils/mail-mt.h>
#include <libemail-engine/mail-tools.h>
#include <libemail-engine/mail-ops.h>
@@ -1555,19 +1554,24 @@ subscription_editor_constructed (GObject *object)
/* Pick an initial store based on the default mail account, if
* one wasn't already given in em_subscription_editor_new(). */
if (editor->priv->initial_store == NULL) {
- EAccount *account;
+ ESource *source;
+ ESourceRegistry *registry;
CamelService *service;
EMailSession *session;
- account = e_get_default_account ();
-
session = em_subscription_editor_get_session (editor);
+ registry = e_mail_session_get_registry (session);
+
+ source = e_source_registry_ref_default_mail_account (registry);
service = camel_session_get_service (
- CAMEL_SESSION (session), account->uid);
+ CAMEL_SESSION (session),
+ e_source_get_uid (source));
if (CAMEL_IS_SUBSCRIBABLE (service))
editor->priv->initial_store = g_object_ref (service);
+
+ g_object_unref (source);
}
/* Chain up to parent's constructed() method. */
diff --git a/mail/em-utils.c b/mail/em-utils.c
index 8a6383d755..11dc1217c7 100644
--- a/mail/em-utils.c
+++ b/mail/em-utils.c
@@ -52,6 +52,15 @@
#include <libedataserver/e-data-server-util.h>
#include <libedataserver/e-flag.h>
#include <libedataserver/e-proxy.h>
+#include <libedataserver/e-source-address-book.h>
+#include <libedataserver/e-source-autocomplete.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-composition.h>
+#include <libedataserver/e-source-mail-identity.h>
+#include <libedataserver/e-source-mail-submission.h>
+#include <libedataserver/e-data-server-util.h>
+#include <libedataserver/e-flag.h>
+#include <libedataserver/e-proxy.h>
#include <e-util/e-util.h>
#include <e-util/e-util-private.h>
@@ -62,7 +71,6 @@
#include <shell/e-shell.h>
#include <widgets/misc/e-attachment.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-utils/mail-mt.h>
#include <libemail-engine/e-mail-folder-utils.h>
@@ -1266,10 +1274,13 @@ void
em_utils_empty_trash (GtkWidget *parent,
EMailSession *session)
{
+ ESourceRegistry *registry;
GList *list, *link;
g_return_if_fail (E_IS_MAIL_SESSION (session));
+ registry = e_mail_session_get_registry (session);
+
if (!em_utils_prompt_user ((GtkWindow *) parent,
"prompt-on-empty-trash",
"mail:ask-empty-trash", NULL))
@@ -1278,10 +1289,11 @@ em_utils_empty_trash (GtkWidget *parent,
list = camel_session_list_services (CAMEL_SESSION (session));
for (link = list; link != NULL; link = g_list_next (link)) {
- EAccount *account;
CamelProvider *provider;
CamelService *service;
+ ESource *source;
const gchar *uid;
+ gboolean enabled = TRUE;
service = CAMEL_SERVICE (link->data);
provider = camel_service_get_provider (service);
@@ -1293,16 +1305,15 @@ em_utils_empty_trash (GtkWidget *parent,
if ((provider->flags & CAMEL_PROVIDER_IS_STORAGE) == 0)
continue;
- account = e_get_account_by_uid (uid);
+ source = e_source_registry_ref_source (registry, uid);
- /* The local store has no corresponding
- * EAccount, so skip the enabled check. */
- if (account != NULL) {
- if (!account->enabled)
- continue;
+ if (source != NULL) {
+ enabled = e_source_get_enabled (source);
+ g_object_unref (source);
}
- mail_empty_trash (CAMEL_STORE (service));
+ if (enabled)
+ mail_empty_trash (CAMEL_STORE (service));
}
g_list_free (list);
@@ -1310,29 +1321,6 @@ em_utils_empty_trash (GtkWidget *parent,
/* ********************************************************************** */
-void
-em_utils_clear_get_password_canceled_accounts_flag (void)
-{
- EAccountList *account_list;
- EIterator *iterator;
-
- account_list = e_get_account_list ();
-
- for (iterator = e_list_get_iterator (E_LIST (account_list));
- e_iterator_is_valid (iterator);
- e_iterator_next (iterator)) {
- EAccount *account = (EAccount *) e_iterator_get (iterator);
-
- if (account && account->source)
- account->source->get_password_canceled = FALSE;
-
- if (account && account->transport)
- account->transport->get_password_canceled = FALSE;
- }
-
- g_object_unref (iterator);
-}
-
gchar *
em_utils_url_unescape_amp (const gchar *url)
{
diff --git a/mail/em-utils.h b/mail/em-utils.h
index bce64eebc3..303f0efddd 100644
--- a/mail/em-utils.h
+++ b/mail/em-utils.h
@@ -27,7 +27,6 @@
#include <sys/types.h>
#include <camel/camel.h>
#include <libedataserver/e-proxy.h>
-#include <libedataserver/e-account.h>
#include <libemail-engine/e-mail-session.h>
#include <libemail-engine/e-mail-utils.h>
@@ -73,14 +72,9 @@ gchar *em_utils_message_to_html (CamelSession *session, CamelMimeMessage *msg, c
void em_utils_empty_trash (GtkWidget *parent,
EMailSession *session);
-/* clears flag 'get_password_canceled' at every known accounts, so if needed, get_password will show dialog */
-void em_utils_clear_get_password_canceled_accounts_flag (void);
-
/* Unescapes &amp; back to a real & in URIs */
gchar *em_utils_url_unescape_amp (const gchar *url);
-void emu_free_mail_account_sort_order_cache (void);
-
void emu_restore_folder_tree_state (EMFolderTree *folder_tree);
gboolean em_utils_is_re_in_subject (struct _EShell *shell,
diff --git a/mail/mail-config.ui b/mail/mail-config.ui
index 0d906ed6df..224f659487 100644
--- a/mail/mail-config.ui
+++ b/mail/mail-config.ui
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <!-- interface-requires evolution 0.0 -->
<requires lib="gtk+" version="2.16"/>
<object class="GtkDialog" id="add-custom-junk-header">
<property name="width_request">400</property>
@@ -143,244 +142,6 @@
<action-widget response="-3">junk-header-ok</action-widget>
</action-widgets>
</object>
- <object class="GtkDialog" id="add_script_signature">
- <property name="can_focus">False</property>
- <property name="type_hint">normal</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="button_add_script_add">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <child>
- <object class="GtkAlignment" id="alignment30">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox221">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image5">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-add</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label547">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Add Signature</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_add_script_cancel">
- <property name="label">gtk-cancel</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox160">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkVBox" id="vbox_add_script_signature">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkHBox" id="hboxImageAndHelp">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="pixmap1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="stock">gtk-dialog-info</property>
- <property name="icon-size">6</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label456">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">The output of this script will be used as your
-signature. The name you specify will be used
-for display purposes only. </property>
- <property name="wrap">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="tblNameScript">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="label459">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="justify">center</property>
- <property name="mnemonic_widget">entry_add_script_name</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label460">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Script:</property>
- <property name="use_underline">True</property>
- <property name="justify">center</property>
- <property name="mnemonic_widget">filechooserbutton_add_script</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="entry_add_script_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkFileChooserButton" id="filechooserbutton_add_script">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="title" translatable="yes"></property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- <action-widgets>
- <action-widget response="0">button_add_script_add</action-widget>
- <action-widget response="0">button_add_script_cancel</action-widget>
- </action-widgets>
- </object>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">10</property>
<property name="value">1.5</property>
@@ -845,56 +606,6 @@ for display purposes only. </property>
<property name="position">0</property>
</packing>
</child>
- <child>
- <object class="GtkVBox" id="signature-preview-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="signature-preview-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Preview</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="signature-preview-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkScrolledWindow" id="signature-preview-scrolled-window">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="shadow_type">in</property>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
</object>
<packing>
<property name="position">1</property>
@@ -1706,18 +1417,6 @@ for display purposes only. </property>
<property name="y_options"></property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
</object>
<packing>
<property name="expand">False</property>
@@ -3287,6 +2986,19 @@ for display purposes only. </property>
</packing>
</child>
</object>
+ <object class="GtkSizeGroup" id="composer-combo-box-size-group">
+ <widgets>
+ <widget name="comboboxReplyStyle"/>
+ <widget name="comboboxForwardStyle"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="composer-label-size-group">
+ <widgets>
+ <widget name="lblCharset"/>
+ <widget name="lblReplyStyle"/>
+ <widget name="lblForwardStyle"/>
+ </widgets>
+ </object>
<object class="GtkListStore" id="use_ssl_model">
<columns>
<!-- column-name Label -->
@@ -3309,2864 +3021,4 @@ for display purposes only. </property>
</row>
</data>
</object>
- <object class="GtkVBox" id="vboxFoldersBorder">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkVBox" id="special-folders-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="special-folders-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Special Folders</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="special-folders-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="xscale">0</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="special-folders-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">5</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="drafts_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Drafts _Folder:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="sent_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Sent _Messages Folder:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="trash_folder_check">
- <property name="label" translatable="yes">_Trash Folder:</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="junk_folder_check">
- <property name="label" translatable="yes">_Junk Folder:</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="revert-button-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="xscale">0</property>
- <child>
- <object class="GtkButton" id="default_folders_button">
- <property name="label">gtk-revert-to-saved</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_stock">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="EMFolderSelectionButton" id="drafts_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="EMFolderSelectionButton" id="sent_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="EMFolderSelectionButton" id="trash_folder_butt">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="EMFolderSelectionButton" id="junk_folder_butt">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="composing-messages-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="composing-messages-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Composing Messages</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="composing-messages-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="composing-messages-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">4</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkAlignment" id="always-bcc-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">18</property>
- <child>
- <object class="GtkEntry" id="bcc_addrs">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="always_bcc">
- <property name="label" translatable="yes">Always _blind carbon-copy (bcc) to:</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="always-cc-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">18</property>
- <child>
- <object class="GtkEntry" id="cc_addrs">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="always_cc">
- <property name="label" translatable="yes">Alway_s carbon-copy (cc) to:</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="message-receipts-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="message-receipts-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Message Receipts</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="message-receipts-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkHBox" id="message-receipts-hbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="label583">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">S_end message receipts:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">receipt_policy_dropdown</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="receipt_policy_dropdown">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <object class="GtkVBox" id="vboxIdentityBorder">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkVBox" id="management-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="management-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Account Information</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="management-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="management-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">2</property>
- <child>
- <object class="GtkVBox" id="account_vbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="management_description_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Type the name by which you would like to refer to this account.
-For example: "Work" or "Personal"</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hboxIdentityName">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="management_name_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Name:</property>
- <property name="use_underline">True</property>
- <property name="justify">right</property>
- <property name="mnemonic_widget">management_name</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="management_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="identity-required-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="identity-required-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Required Information</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="identity-required-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="identity-required-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkEntry" id="identity_address">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <accessibility>
- <relation type="labelled-by" target="identity_address_label"/>
- <relation type="labelled-by" target="identity-required-header"/>
- </accessibility>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="identity_address_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Email _Address:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">identity_address</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="identity_full_name_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Full Nam_e:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">identity_full_name</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="identity_full_name">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <accessibility>
- <relation type="labelled-by" target="identity-required-header"/>
- <relation type="labelled-by" target="identity_full_name_label"/>
- </accessibility>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="identity-optional-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="identity-optional-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Optional Information</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="identity-optional-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="identity-optional-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">4</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="sigLabel">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Signat_ure:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">signature_dropdown</property>
- </object>
- <packing>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox169">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkComboBox" id="signature_dropdown">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="sigAddNew">
- <property name="label" translatable="yes">Add Ne_w Signature...</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="sigAddNewClicked" swapped="no"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="identity_organization">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <accessibility>
- <relation type="labelled-by" target="identity_organization_label"/>
- <relation type="labelled-by" target="identity-optional-header"/>
- </accessibility>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="identity_organization_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Or_ganization:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">identity_organization</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="identity_reply_to">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- <accessibility>
- <relation type="labelled-by" target="identity-optional-header"/>
- <relation type="labelled-by" target="reply_to_label"/>
- </accessibility>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="reply_to_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Re_ply-To:</property>
- <property name="use_underline">True</property>
- <property name="justify">center</property>
- <property name="mnemonic_widget">identity_reply_to</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="management_default">
- <property name="label" translatable="yes">_Make this my default account</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <object class="GtkVBox" id="vboxSecurityBorder">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkVBox" id="security-general-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="security-general-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">General</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="security-general-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkCheckButton" id="pgp_no_imip_sign">
- <property name="label" translatable="yes">_Do not sign meeting requests (for Outlook compatibility)</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="pgp-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="pgp-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Pretty Good Privacy (PGP/GPG)</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="pgp-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="pgp-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="column_spacing">6</property>
- <property name="row_spacing">2</property>
- <child>
- <object class="GtkVBox" id="vboxPGP">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkHBox" id="hbox63">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="pgp_key_id_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">PGP/GPG _Key ID:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">pgp_key</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="pgp_key">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="pgp_hash_algo_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Si_gning algorithm:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">pgp_hash_algo</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="pgp_hash_algo">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="model">hash_algo_model</property>
- <child>
- <object class="GtkCellRendererText" id="pgp_hash_algo_renderer"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="pgp_always_sign">
- <property name="label" translatable="yes">Al_ways sign outgoing messages when using this account</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="pgp_encrypt_to_self">
- <property name="label" translatable="yes">Always encrypt to _myself when sending encrypted messages</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="pgp_always_trust">
- <property name="label" translatable="yes">Always _trust keys in my keyring when encrypting</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="smime-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="smime-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Secure MIME (S/MIME)</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="smime-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="smime_table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">7</property>
- <property name="n_columns">3</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkEntry" id="smime_sign_key">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="smime_encrypt_key">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="smime_encrypt_to_self">
- <property name="label" translatable="yes">Also encrypt to sel_f when sending encrypted messages</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">3</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="smime_encrypt_default">
- <property name="label" translatable="yes">Encrypt out_going messages (by default)</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">3</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="smime_sign_default">
- <property name="label" translatable="yes">Digitally sign o_utgoing messages (by default)</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="right_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkHSeparator" id="hseparator1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="right_attach">3</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- <property name="y_padding">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Encry_ption certificate:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">smime_encrypt_key</property>
- </object>
- <packing>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label469">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Sig_ning certificate:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">smime_sign_key</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox208">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkButton" id="smime_encrypt_key_select">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <child>
- <object class="GtkAlignment" id="alignment28">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-open</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="button98">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">S_elect...</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="smime_encrypt_key_clear">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <child>
- <object class="GtkAlignment" id="alignment35">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox230">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image10">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-clear</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label577">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Clea_r</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="smime_hash_algo_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Signing _algorithm:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">smime_hash_algo</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="smime_hash_algo_alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="xscale">0</property>
- <child>
- <object class="GtkComboBox" id="smime_hash_algo">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="model">hash_algo_model</property>
- <child>
- <object class="GtkCellRendererText" id="smime_hash_algo_renderer"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="yalign">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox209">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkButton" id="smime_sign_key_select">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <child>
- <object class="GtkAlignment" id="alignment29">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-open</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Select...</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="smime_sign_key_clear">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <child>
- <object class="GtkAlignment" id="alignment34">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xscale">0</property>
- <property name="yscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox229">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkImage" id="image9">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-clear</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label576">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Cle_ar</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <object class="GtkVBox" id="vboxSourceBorder">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkTable" id="source-type-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">3</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="source_type_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Server _Type:</property>
- <property name="use_underline">True</property>
- <property name="justify">right</property>
- <property name="mnemonic_widget">source_type_dropdown</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label442">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Description:</property>
- <property name="justify">center</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="source_description">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">description</property>
- <property name="wrap">True</property>
- <property name="width-chars">40</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBoxText" id="source_type_dropdown">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHSeparator" id="source-separator">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="source-config-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="source-config-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Configuration</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="source-config-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="source-config-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">3</property>
- <property name="n_columns">4</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="source_host_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Server:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">source_host</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="source_port_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label">_Port:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">source_port</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="source_user_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">User_name:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">source_user</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="source_host">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="EPortEntry" id="source_port" type-func="e_port_entry_get_type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="has_entry">True</property>
- </object>
- <packing>
- <property name="left_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="source_user">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">4</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="source_path_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Path:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">source_path_entry</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkFileChooserButton" id="source_path_entry">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="title" translatable="yes">Mailbox location</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="source-security-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="source-security-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Security</property>
- <property name="mnemonic_widget">source_auth_dropdown</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="source-security-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkVBox" id="source-security-vbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkHBox" id="source_ssl_hbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="lblSourceUseSSL">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Use secure connection:</property>
- <property name="use_underline">True</property>
- <property name="justify">center</property>
- <property name="mnemonic_widget">source_use_ssl</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="source_use_ssl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="model">use_ssl_model</property>
- <property name="id_column">1</property>
- <child>
- <object class="GtkCellRendererText" id="source_use_ssl_renderer"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="source_ssl_disabled">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-dialog-warning</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label514">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">SSL is not supported in this build of Evolution</property>
- <property name="justify">center</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="source-auth-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="source-auth-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">_Authentication Type</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">source_auth_dropdown</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="source-auth-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkVBox" id="source-auth-vbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkHBox" id="hbox199">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="EAuthComboBox" id="source_auth_dropdown" type-func="e_auth_combo_box_get_type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="source_check_supported">
- <property name="label" translatable="yes">Ch_eck for Supported Types</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="source_remember_password">
- <property name="label" translatable="yes">Re_member password</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- <object class="GtkVBox" id="vboxTransportBorder">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="border_width">12</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkTable" id="transport-type-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">3</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="transport_type_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Server _Type:</property>
- <property name="use_underline">True</property>
- <property name="justify">right</property>
- <property name="mnemonic_widget">transport_type_dropdown</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label50">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Description:</property>
- <property name="justify">right</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBoxText" id="transport_type_dropdown">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="transport_description">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">description</property>
- <property name="wrap">True</property>
- <property name="width-chars">40</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHSeparator" id="transport-separator">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="transport-server-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="transport-server-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Server Configuration</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="transport-server-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="transport-server-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="n_columns">4</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="transport_host_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">_Server:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">transport_host</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="transport_port_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Port:</property>
- <property name="use_underline">True</property>
- <property name="justify">right</property>
- <property name="mnemonic_widget">transport_port</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="transport_host">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="EPortEntry" id="transport_port" type-func="e_port_entry_get_type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="has_entry">True</property>
- </object>
- <packing>
- <property name="left_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="transport_needs_auth">
- <property name="label" translatable="yes">Ser_ver requires authentication</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="transport-security-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="transport-security-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Security</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="transport-security-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="transport-security-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">2</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkHBox" id="transport_ssl_disabled">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="stock">gtk-dialog-warning</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="transport_ssl_disabled_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">SSL is not supported in this build of Evolution</property>
- <property name="justify">center</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="transport_ssl_hbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel" id="lblTransportUseSSL">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">_Use secure connection:</property>
- <property name="use_underline">True</property>
- <property name="justify">center</property>
- <property name="mnemonic_widget">transport_use_ssl</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="transport_use_ssl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="model">use_ssl_model</property>
- <property name="id_column">1</property>
- <child>
- <object class="GtkCellRendererText" id="transport_use_ssl_renderer"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="y_options"></property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="transport-auth-section">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="transport-auth-header">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Authentication</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="transport-auth-alignment">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkTable" id="transport-auth-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">12</property>
- <property name="row_spacing">6</property>
- <child>
- <object class="GtkLabel" id="transport_auth_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">T_ype:</property>
- <property name="use_underline">True</property>
- <property name="justify">center</property>
- <property name="mnemonic_widget">transport_auth_dropdown</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="transport_user_label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">User _Name:</property>
- <property name="use_underline">True</property>
- <property name="justify">right</property>
- <property name="mnemonic_widget">transport_user</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="transport_user">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">●</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="transport_remember_password">
- <property name="label" translatable="yes">Remember _password</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="xscale">0</property>
- <child>
- <object class="GtkHBox" id="hbox195">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="EAuthComboBox" id="transport_auth_dropdown" type-func="e_auth_combo_box_get_type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="transport_check_supported">
- <property name="label" translatable="yes">Ch_eck for Supported Types</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- <object class="GtkSizeGroup" id="composer-combo-box-size-group">
- <widgets>
- <widget name="comboboxReplyStyle"/>
- <widget name="comboboxForwardStyle"/>
- </widgets>
- </object>
- <object class="GtkSizeGroup" id="composer-label-size-group">
- <widgets>
- <widget name="lblCharset"/>
- <widget name="lblReplyStyle"/>
- <widget name="lblForwardStyle"/>
- </widgets>
- </object>
- <object class="GtkVBox" id="vboxReviewBorder">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkTable" id="personal-details-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="row_spacing">4</property>
- <property name="column_spacing">8</property>
- <child>
- <object class="GtkLabel" id="personal-details-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Personal Details:</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="personal-name-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Name:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="personal-name-entry">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="personal-email-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Email address:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="personal-email-entry">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkTable" id="server-details-table">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="n_rows">5</property>
- <property name="n_columns">3</property>
- <property name="row_spacing">4</property>
- <property name="column_spacing">8</property>
- <child>
- <object class="GtkLabel" id="details-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Details:</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="details-label-receiving">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Receiving</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="details-label-sending">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Sending</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="details-server-type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Server type:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="details-server-address">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Server address:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="details-user-name">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Username:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="details-encryption">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Encryption:</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="receive_server_type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">none</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="send_server_type">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">none</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="receive_server_address">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">none</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="send_server_address">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">none</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="receive_username">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="send_username">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="receive_encryption">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="send_encryption">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">label</property>
- </object>
- <packing>
- <property name="left_attach">2</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
</interface>
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index ee3cd164e7..d68b928124 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -29,12 +29,12 @@
#include <glib/gi18n.h>
-#include <libedataserver/e-account-list.h>
+#include <libedataserver/e-source-mail-account.h>
+#include <libedataserver/e-source-mail-submission.h>
#include <shell/e-shell.h>
#include <e-util/e-util.h>
-#include <libemail-utils/e-account-utils.h>
#include <libemail-utils/mail-mt.h>
/* This is our hack, not part of libcamel. */
@@ -490,7 +490,7 @@ static struct _send_data *
build_dialog (GtkWindow *parent,
EMailSession *session,
CamelFolder *outbox,
- EAccount *outgoing_account,
+ CamelService *transport,
gboolean allow_send)
{
GtkDialog *gd;
@@ -508,7 +508,6 @@ build_dialog (GtkWindow *parent,
GtkWidget *progress_bar;
GtkWidget *cancel_button;
EMailAccountStore *account_store;
- CamelService *transport = NULL;
struct _send_info *info;
gchar *pretty_url;
EMEventTargetSendReceive *target;
@@ -516,17 +515,6 @@ build_dialog (GtkWindow *parent,
account_store = e_mail_ui_session_get_account_store (E_MAIL_UI_SESSION (session));
- /* Convert the outgoing account to a CamelTransport. */
- if (outgoing_account != NULL) {
- gchar *transport_uid;
-
- transport_uid = g_strdup_printf (
- "%s-transport", outgoing_account->uid);
- transport = camel_session_get_service (
- CAMEL_SESSION (session), transport_uid);
- g_free (transport_uid);
- }
-
send_recv_dialog = gtk_dialog_new ();
gd = GTK_DIALOG (send_recv_dialog);
@@ -1124,14 +1112,57 @@ receive_update_got_store (CamelStore *store,
}
}
+static CamelService *
+get_default_transport (EMailSession *session)
+{
+ ESource *source;
+ ESourceRegistry *registry;
+ CamelService *service;
+ const gchar *extension_name;
+ const gchar *uid;
+
+ registry = e_mail_session_get_registry (session);
+ source = e_source_registry_ref_default_mail_identity (registry);
+
+ if (source == NULL)
+ return NULL;
+
+ extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
+ if (e_source_has_extension (source, extension_name)) {
+ ESourceMailSubmission *extension;
+ gchar *uid;
+
+ extension = e_source_get_extension (source, extension_name);
+ uid = e_source_mail_submission_dup_transport_uid (extension);
+
+ g_object_unref (source);
+ source = e_source_registry_ref_source (registry, uid);
+
+ g_free (uid);
+ } else {
+ g_object_unref (source);
+ source = NULL;
+ }
+
+ if (source == NULL)
+ return NULL;
+
+ uid = e_source_get_uid (source);
+ service = camel_session_get_service (CAMEL_SESSION (session), uid);
+
+ g_object_unref (source);
+
+ return service;
+}
+
static GtkWidget *
send_receive (GtkWindow *parent,
EMailSession *session,
gboolean allow_send)
{
CamelFolder *local_outbox;
+ CamelService *transport;
struct _send_data *data;
- EAccount *account;
GList *scan;
if (send_recv_dialog != NULL) {
@@ -1144,16 +1175,14 @@ send_receive (GtkWindow *parent,
if (!camel_session_get_online (CAMEL_SESSION (session)))
return send_recv_dialog;
- account = e_get_default_account ();
- if (!account || !account->transport->url)
- return send_recv_dialog;
+ transport = get_default_transport (session);
local_outbox =
e_mail_session_get_local_folder (
session, E_MAIL_LOCAL_FOLDER_OUTBOX);
data = build_dialog (
- parent, session, local_outbox, account, allow_send);
+ parent, session, local_outbox, transport, allow_send);
for (scan = data->infos; scan != NULL; scan = scan->next) {
struct _send_info *info = scan->data;
@@ -1165,7 +1194,7 @@ send_receive (GtkWindow *parent,
case SEND_RECEIVE:
mail_fetch_mail (
CAMEL_STORE (info->service),
- info->keep_on_server, 0, -1,
+ CAMEL_FETCH_OLD_MESSAGES, -1,
E_FILTER_SOURCE_INCOMING,
NULL, NULL, NULL,
info->cancellable,
@@ -1210,201 +1239,6 @@ mail_receive (GtkWindow *parent,
return send_receive (parent, session, FALSE);
}
-struct _auto_data {
- EAccount *account;
- EMailSession *session;
- gint period; /* in seconds */
- gint timeout_id;
-};
-
-static GHashTable *auto_active;
-
-static gboolean
-auto_timeout (gpointer data)
-{
- CamelService *service;
- CamelSession *session;
- struct _auto_data *info = data;
-
- session = CAMEL_SESSION (info->session);
-
- service = camel_session_get_service (
- session, info->account->uid);
- g_return_val_if_fail (CAMEL_IS_SERVICE (service), TRUE);
-
- if (camel_session_get_online (session))
- mail_receive_service (service);
-
- return TRUE;
-}
-
-static void
-auto_account_removed (EAccountList *eal,
- EAccount *ea,
- gpointer dummy)
-{
- struct _auto_data *info = g_object_get_data((GObject *)ea, "mail-autoreceive");
-
- g_return_if_fail (info != NULL);
-
- if (info->timeout_id) {
- g_source_remove (info->timeout_id);
- info->timeout_id = 0;
- }
-}
-
-static void
-auto_account_finalized (struct _auto_data *info)
-{
- if (info->session != NULL)
- g_object_unref (info->session);
- if (info->timeout_id)
- g_source_remove (info->timeout_id);
- g_free (info);
-}
-
-static void
-auto_account_commit (struct _auto_data *info)
-{
- gint period, check;
-
- check = info->account->enabled
- && e_account_get_bool (info->account, E_ACCOUNT_SOURCE_AUTO_CHECK)
- && e_account_get_string (info->account, E_ACCOUNT_SOURCE_URL);
- period = e_account_get_int (info->account, E_ACCOUNT_SOURCE_AUTO_CHECK_TIME) * 60;
- period = MAX (60, period);
-
- if (info->timeout_id
- && (!check
- || period != info->period)) {
- g_source_remove (info->timeout_id);
- info->timeout_id = 0;
- }
- info->period = period;
- if (check && info->timeout_id == 0)
- info->timeout_id = g_timeout_add_seconds (info->period, auto_timeout, info);
-}
-
-static void
-auto_account_added (EAccountList *eal,
- EAccount *ea,
- EMailSession *session)
-{
- struct _auto_data *info;
-
- info = g_malloc0 (sizeof (*info));
- info->account = ea;
- info->session = g_object_ref (session);
- g_object_set_data_full (
- G_OBJECT (ea), "mail-autoreceive", info,
- (GDestroyNotify) auto_account_finalized);
- auto_account_commit (info);
-}
-
-static void
-auto_account_changed (EAccountList *eal,
- EAccount *ea,
- gpointer dummy)
-{
- struct _auto_data *info;
-
- info = g_object_get_data (G_OBJECT (ea), "mail-autoreceive");
-
- if (info != NULL)
- auto_account_commit (info);
-}
-
-static void
-auto_online (EShell *shell)
-{
- EIterator *iter;
- EAccountList *accounts;
- EShellSettings *shell_settings;
- struct _auto_data *info;
- gboolean can_update_all;
-
- if (!e_shell_get_online (shell))
- return;
-
- shell_settings = e_shell_get_shell_settings (shell);
-
- can_update_all =
- e_shell_settings_get_boolean (
- shell_settings, "mail-check-on-start") &&
- e_shell_settings_get_boolean (
- shell_settings, "mail-check-all-on-start");
-
- accounts = e_get_account_list ();
- for (iter = e_list_get_iterator ((EList *) accounts);
- e_iterator_is_valid (iter);
- e_iterator_next (iter)) {
- EAccount *account = (EAccount *) e_iterator_get (iter);
-
- if (!account || !account->enabled)
- continue;
-
- info = g_object_get_data (
- G_OBJECT (account), "mail-autoreceive");
- if (info && (info->timeout_id || can_update_all))
- auto_timeout (info);
- }
-
- if (iter)
- g_object_unref (iter);
-}
-
-/* call to setup initial, and after changes are made to the config */
-/* FIXME: Need a cleanup funciton for when object is deactivated */
-void
-mail_autoreceive_init (EMailSession *session)
-{
- EShell *shell;
- EShellSettings *shell_settings;
- EAccountList *accounts;
- EIterator *iter;
-
- g_return_if_fail (E_IS_MAIL_SESSION (session));
-
- if (auto_active)
- return;
-
- accounts = e_get_account_list ();
- auto_active = g_hash_table_new (g_str_hash, g_str_equal);
-
- g_signal_connect (
- accounts, "account-added",
- G_CALLBACK (auto_account_added), session);
- g_signal_connect (
- accounts, "account-removed",
- G_CALLBACK (auto_account_removed), NULL);
- g_signal_connect (
- accounts, "account-changed",
- G_CALLBACK (auto_account_changed), NULL);
-
- for (iter = e_list_get_iterator ((EList *) accounts);
- e_iterator_is_valid (iter);
- e_iterator_next (iter))
- auto_account_added (
- accounts, (EAccount *)
- e_iterator_get (iter), session);
-
- shell = e_shell_get_default ();
- shell_settings = e_shell_get_shell_settings (shell);
-
- if (e_shell_settings_get_boolean (
- shell_settings, "mail-check-on-start")) {
- auto_online (shell);
-
- /* also flush outbox on start */
- if (e_shell_get_online (shell))
- mail_send (session);
- }
-
- g_signal_connect (
- shell, "notify::online",
- G_CALLBACK (auto_online), NULL);
-}
-
/* We setup the download info's in a hashtable, if we later
* need to build the gui, we insert them in to add them. */
void
@@ -1458,7 +1292,7 @@ mail_receive_service (CamelService *service)
case SEND_RECEIVE:
mail_fetch_mail (
CAMEL_STORE (service),
- info->keep_on_server, 0, -1,
+ CAMEL_FETCH_OLD_MESSAGES, -1,
E_FILTER_SOURCE_INCOMING,
NULL, NULL, NULL,
info->cancellable,
@@ -1495,16 +1329,14 @@ mail_send (EMailSession *session)
{
CamelFolder *local_outbox;
CamelService *service;
- EAccount *account;
struct _send_info *info;
struct _send_data *data;
send_info_t type = SEND_INVALID;
- gchar *transport_uid;
g_return_if_fail (E_IS_MAIL_SESSION (session));
- account = e_get_default_transport ();
- if (account == NULL || account->transport->url == NULL)
+ service = get_default_transport (session);
+ if (service == NULL)
return;
data = setup_send_data (session);
@@ -1515,24 +1347,12 @@ mail_send (EMailSession *session)
return;
}
- transport_uid = g_strconcat (account->uid, "-transport", NULL);
-
- service = camel_session_get_service (
- CAMEL_SESSION (session), transport_uid);
-
- if (!CAMEL_IS_TRANSPORT (service)) {
- g_free (transport_uid);
- return;
- }
-
d(printf("starting non-interactive send of '%s'\n", transport->url));
type = get_receive_type (service);
- if (type == SEND_INVALID) {
- g_free (transport_uid);
+ if (type == SEND_INVALID)
return;
- }
info = g_malloc0 (sizeof (*info));
info->type = SEND_SEND;
@@ -1556,10 +1376,6 @@ mail_send (EMailSession *session)
e_mail_session_get_local_folder (
session, E_MAIL_LOCAL_FOLDER_OUTBOX);
- g_free (transport_uid);
-
- g_return_if_fail (CAMEL_IS_TRANSPORT (service));
-
mail_send_queue (
session, local_outbox,
CAMEL_TRANSPORT (service),
diff --git a/mail/mail.error.xml b/mail/mail.error.xml
index c996362a22..65cf052db6 100644
--- a/mail/mail.error.xml
+++ b/mail/mail.error.xml
@@ -300,24 +300,6 @@ all proxy information will be deleted permanently.</_secondary>
<button _label="_Disable" response="GTK_RESPONSE_YES"/>
</error>
- <error id="no-save-signature" type="error">
- <_primary>Could not save signature file.</_primary>
- <secondary xml:space="preserve">{0}.</secondary>
- </error>
-
- <error id="signature-notscript" type="error">
- <_primary>Cannot set signature script "{0}".</_primary>
- <_secondary xml:space="preserve">The script file must exist and be executable.</_secondary>
- </error>
-
- <error id="ask-signature-changed" type="question" default="GTK_RESPONSE_YES">
- <_primary>Do you wish to save your changes?</_primary>
- <_secondary xml:space="preserve">This signature has been changed, but has not been saved.</_secondary>
- <button _label="_Discard changes" response="GTK_RESPONSE_NO"/>
- <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
- <button stock="gtk-save" response="GTK_RESPONSE_YES"/>
- </error>
-
<error id="vfolder-notexist" type="error">
<_primary>Cannot edit Search Folder "{0}" as it does not exist.</_primary>
<_secondary xml:space="preserve">This folder may have been added implicitly,
@@ -444,16 +426,6 @@ An mbox account will be created to preserve the old mbox folders. You can delete
<button _label="N_ever" response="GTK_RESPONSE_CANCEL"/>
</error>
- <error id="signature-already-exists" type="error" modal="true">
- <_primary>Signature Already Exists</_primary>
- <_secondary>A signature already exists with the name "{0}". Please specify a different name. </_secondary>
- </error>
-
- <error id="blank-signature" type="error" modal="true">
- <_primary>Blank Signature</_primary>
- <_secondary>Please provide an unique name to identify this signature.</_secondary>
- </error>
-
<error id="send-no-account-enabled" type="warning">
<_primary>This message cannot be sent because the account you chose to send with is not enabled</_primary>
<_secondary xml:space="preserve">Please enable the account or send using another account.</_secondary>
diff --git a/mail/test-mail-autoconfig.c b/mail/test-mail-autoconfig.c
new file mode 100644
index 0000000000..10977a17b2
--- /dev/null
+++ b/mail/test-mail-autoconfig.c
@@ -0,0 +1,53 @@
+/*
+ * test-mail-autoconfig.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <stdlib.h>
+
+#include "e-mail-autoconfig.h"
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ EMailAutoconfig *autoconfig;
+ GError *error = NULL;
+
+ g_type_init ();
+
+ if (argc < 2) {
+ g_printerr ("USAGE: %s EMAIL-ADDRESS\n", argv[0]);
+ exit (EXIT_FAILURE);
+ }
+
+ autoconfig = e_mail_autoconfig_new_sync (argv[1], NULL, &error);
+
+ if (error != NULL) {
+ g_warn_if_fail (autoconfig == NULL);
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
+
+ g_assert (E_IS_MAIL_AUTOCONFIG (autoconfig));
+
+ g_print ("%s\n", e_mail_autoconfig_get_markup_content (autoconfig));
+
+ g_object_unref (autoconfig);
+
+ return EXIT_SUCCESS;
+}