diff options
-rw-r--r-- | mail/em-account-editor.c | 1603 | ||||
-rw-r--r-- | mail/em-config.c | 177 | ||||
-rw-r--r-- | mail/em-config.h | 38 | ||||
-rw-r--r-- | mail/mail-config.ui | 4 | ||||
-rw-r--r-- | modules/mail/e-mail-config-hook.c | 2 | ||||
-rw-r--r-- | plugins/backup-restore/backup-restore.c | 8 | ||||
-rw-r--r-- | plugins/backup-restore/org-gnome-backup-restore.eplug.xml | 2 | ||||
-rw-r--r-- | plugins/imap-features/imap-headers.c | 32 | ||||
-rw-r--r-- | plugins/imap-features/org-gnome-imap-features.eplug.xml | 2 | ||||
-rw-r--r-- | widgets/misc/e-auth-combo-box.c | 5 | ||||
-rw-r--r-- | widgets/misc/e-port-entry.c | 230 |
11 files changed, 1304 insertions, 799 deletions
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c index 3441fcdc47..0d930a1184 100644 --- a/mail/em-account-editor.c +++ b/mail/em-account-editor.c @@ -125,7 +125,6 @@ typedef struct _EMAccountEditorService { EPortEntry *port; GtkLabel *userlabel; GtkEntry *username; - GtkEntry *path; GtkLabel *pathlabel; GtkWidget *pathentry; @@ -146,9 +145,15 @@ typedef struct _EMAccountEditorService { GCancellable *checking; GtkWidget *check_dialog; - CamelProvider *provider; + 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 { @@ -229,8 +234,20 @@ enum { 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_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); @@ -240,6 +257,14 @@ static ServerData * emae_check_servers (const gchar *email); static gpointer parent_class; static void +emae_config_target_changed_cb (EMAccountEditor *emae) +{ + e_config_target_changed ( + (EConfig *) emae->config, + E_CONFIG_TARGET_CHANGED_STATE); +} + +static void emae_set_original_account (EMAccountEditor *emae, EAccount *original_account) { @@ -280,6 +305,10 @@ emae_set_original_account (EMAccountEditor *emae, emae->priv->original_account = original_account; emae->priv->modified_account = modified_account; + + g_signal_connect_swapped ( + emae->priv->modified_account, "changed", + G_CALLBACK (emae_config_target_changed_cb), emae); } static void @@ -295,7 +324,15 @@ emae_set_backend (EMAccountEditor *emae, static CamelProvider * emae_get_store_provider (EMAccountEditor *emae) { - return emae->priv->source.provider; + CamelProvider *provider = NULL; + const gchar *protocol; + + protocol = emae->priv->source.protocol; + + if (protocol != NULL) + provider = camel_provider_get (protocol, NULL); + + return provider; } static gboolean @@ -313,10 +350,118 @@ emae_set_store_requires_auth (EMAccountEditor *emae, 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) { - return emae->priv->transport.provider; + CamelProvider *provider = NULL; + const gchar *protocol; + + protocol = emae->priv->transport.protocol; + + if (protocol != NULL) + provider = camel_provider_get (protocol, NULL); + + return provider; } static gboolean @@ -334,6 +479,106 @@ emae_set_transport_requires_auth (EMAccountEditor *emae, 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, @@ -359,11 +604,83 @@ emae_set_property (GObject *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); @@ -411,6 +728,48 @@ emae_get_property (GObject *object, 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, @@ -424,6 +783,48 @@ emae_get_property (GObject *object, 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); @@ -442,6 +843,9 @@ emae_dispose (GObject *object) } 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; } @@ -452,11 +856,17 @@ emae_dispose (GObject *object) } 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; } @@ -541,7 +951,7 @@ emae_class_init (GObjectClass *class) g_param_spec_pointer ( "store-provider", "Store Provider", - "CamelProvider for storage service", + "CamelProvider for the storage service", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); @@ -559,11 +969,82 @@ emae_class_init (GObjectClass *class) 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 transport service", + "CamelProvider for the transport service", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); @@ -578,6 +1059,77 @@ emae_class_init (GObjectClass *class) 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 @@ -591,6 +1143,10 @@ emae_init (EMAccountEditor *emae) 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"; } GType @@ -784,6 +1340,7 @@ emae_auto_detect (EMAccountEditor *emae) { EMAccountEditorPrivate *priv = emae->priv; EMAccountEditorService *service = &priv->source; + CamelProvider *provider; GHashTable *auto_detected; GSList *l; CamelProviderConfEntry *entries; @@ -791,15 +1348,19 @@ emae_auto_detect (EMAccountEditor *emae) gint i; CamelURL *url; - if (service->provider == NULL - || (entries = service->provider->extra_conf) == NULL) + 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 (service->provider, url, &auto_detected, NULL); + camel_provider_auto_detect (provider, url, &auto_detected, NULL); camel_url_free (url); + if (auto_detected == NULL) { d (printf (" no values detected\n")); return; @@ -1027,7 +1588,6 @@ emae_setup_signatures (EMAccountEditor *emae, gtk_combo_box_set_active (dropdown, active); g_signal_connect (dropdown, "changed", G_CALLBACK(emae_signaturetype_changed), emae); - gtk_widget_set_sensitive ((GtkWidget *) dropdown, e_account_writable (account, E_ACCOUNT_ID_SIGNATURE)); button = e_builder_get_widget (builder, "sigAddNew"); g_signal_connect (button, "clicked", G_CALLBACK(emae_signature_new), emae); @@ -1102,7 +1662,6 @@ emae_setup_receipt_policy (EMAccountEditor *emae, gtk_combo_box_set_active (dropdown, active); g_signal_connect (dropdown, "changed", G_CALLBACK(emae_receipt_policy_changed), emae); - gtk_widget_set_sensitive ((GtkWidget *) dropdown, e_account_writable (account, E_ACCOUNT_RECEIPT_POLICY)); return (GtkWidget *) dropdown; } @@ -1143,7 +1702,6 @@ emae_account_entry (EMAccountEditor *emae, 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); - gtk_widget_set_sensitive ((GtkWidget *) entry, e_account_writable (account, item)); return entry; } @@ -1170,16 +1728,12 @@ emae_account_toggle_widget (EMAccountEditor *emae, { EAccount *account; gboolean active; - gboolean writable; account = em_account_editor_get_modified_account (emae); active = e_account_get_bool (account, item); gtk_toggle_button_set_active (toggle, active); - writable = e_account_writable (account, item); - gtk_widget_set_sensitive (GTK_WIDGET (toggle), writable); - g_object_set_data ( G_OBJECT (toggle), "account-item", GINT_TO_POINTER (item)); @@ -1224,7 +1778,6 @@ emae_account_spinint_widget (EMAccountEditor *emae, gint item) { EAccount *account; - gboolean writable; gint v_int; account = em_account_editor_get_modified_account (emae); @@ -1232,9 +1785,6 @@ emae_account_spinint_widget (EMAccountEditor *emae, v_int = e_account_get_int (account, item); gtk_spin_button_set_value (spin, v_int); - writable = e_account_writable (account, item); - gtk_widget_set_sensitive (GTK_WIDGET (spin), writable); - g_object_set_data ( G_OBJECT (spin), "account-item", GINT_TO_POINTER (item)); @@ -1290,8 +1840,6 @@ emae_account_folder (EMAccountEditor *emae, g_signal_connect (folder, "selected", G_CALLBACK(emae_account_folder_changed), emae); gtk_widget_show ((GtkWidget *) folder); - gtk_widget_set_sensitive ((GtkWidget *) folder, e_account_writable (account, item)); - return folder; } @@ -1399,54 +1947,6 @@ smime_encrypt_key_clear (GtkWidget *w, } #endif -static void -emae_url_set_host (CamelURL *url, - const gchar *txt) -{ - gchar *host; - - if (txt && *txt) { - host = g_strdup (txt); - g_strstrip (host); - camel_url_set_host (url, host); - g_free (host); - } -} - -static void -emae_url_set_port (CamelURL *url, - const gchar *port) -{ - if (port && *port) - camel_url_set_port (url, atoi (port)); -} - -/* This is used to map a funciton which will set on the url a string value. - * if widgets[0] is set, it is the entry which will be called against setval () - * We need our own function for host:port decoding, as above */ -struct _provider_host_info { - guint32 flag; - void (*setval)(CamelURL *, const gchar *); - glong widgets[3]; -}; - -static struct _provider_host_info emae_source_host_info[] = { - { CAMEL_URL_PART_HOST, emae_url_set_host, { G_STRUCT_OFFSET (EMAccountEditorService, hostname), G_STRUCT_OFFSET (EMAccountEditorService, hostlabel), }, }, - { CAMEL_URL_PART_PORT, emae_url_set_port, { G_STRUCT_OFFSET (EMAccountEditorService, port), G_STRUCT_OFFSET (EMAccountEditorService, portlabel), }, }, - { CAMEL_URL_PART_USER, camel_url_set_user, { G_STRUCT_OFFSET (EMAccountEditorService, username), G_STRUCT_OFFSET (EMAccountEditorService, userlabel), } }, - { CAMEL_URL_PART_PATH, camel_url_set_path, { G_STRUCT_OFFSET (EMAccountEditorService, path), G_STRUCT_OFFSET (EMAccountEditorService, pathlabel), G_STRUCT_OFFSET (EMAccountEditorService, pathentry) }, }, - { CAMEL_URL_PART_AUTH, NULL, { 0, G_STRUCT_OFFSET (EMAccountEditorService, auth_frame), }, }, - { 0 }, -}; - -static struct _provider_host_info emae_transport_host_info[] = { - { CAMEL_URL_PART_HOST, emae_url_set_host, { G_STRUCT_OFFSET (EMAccountEditorService, hostname), G_STRUCT_OFFSET (EMAccountEditorService, hostlabel), }, }, - { CAMEL_URL_PART_PORT, emae_url_set_port, { G_STRUCT_OFFSET (EMAccountEditorService, port), G_STRUCT_OFFSET (EMAccountEditorService, portlabel), }, }, - { CAMEL_URL_PART_USER, camel_url_set_user, { G_STRUCT_OFFSET (EMAccountEditorService, username), G_STRUCT_OFFSET (EMAccountEditorService, userlabel), } }, - { CAMEL_URL_PART_AUTH, NULL, { 0, G_STRUCT_OFFSET (EMAccountEditorService, auth_frame), }, }, - { 0 }, -}; - /* 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 @@ -1483,8 +1983,6 @@ static struct _service_info { const gchar *remember_password; - struct _provider_host_info *host_info; - } emae_service_info[CAMEL_NUM_PROVIDER_TYPES] = { { E_ACCOUNT_SOURCE_URL, @@ -1516,9 +2014,8 @@ static struct _service_info { "source_auth_dropdown", "source_check_supported", - "source_remember_password", - - emae_source_host_info }, + "source_remember_password" + }, { E_ACCOUNT_TRANSPORT_URL, E_ACCOUNT_TRANSPORT_SAVE_PASSWD, @@ -1549,123 +2046,49 @@ static struct _service_info { "transport_auth_dropdown", "transport_check_supported", - "transport_remember_password", - - emae_transport_host_info, - }, + "transport_remember_password" + } }; static void -emae_uri_changed (EMAccountEditorService *service, - CamelURL *url) +emae_file_chooser_changed (GtkFileChooser *file_chooser, + EMAccountEditorService *service) { - EAccount *account; - gchar *uri; - - account = em_account_editor_get_modified_account (service->emae); - uri = camel_url_to_string (url, 0); + CamelLocalSettings *local_settings; + const gchar *filename; - e_account_set_string (account, emae_service_info[service->type].account_uri_key, uri); - - /* small hack for providers which are store and transport - copy settings across */ - if (service->type == CAMEL_PROVIDER_STORE - && service->provider - && CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (service->provider)) - e_account_set_string (account, E_ACCOUNT_TRANSPORT_URL, uri); - - g_free (uri); -} - -static void -emae_service_url_changed (EMAccountEditorService *service, - void (*setval)(CamelURL *, const gchar *), - GtkWidget *entry) -{ - gchar *text; - - CamelURL *url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key); - - if (GTK_IS_ENTRY (entry)) - text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); - else if (E_IS_PORT_ENTRY (entry)) { - text = g_strdup_printf ("%i", e_port_entry_get_port (E_PORT_ENTRY (entry))); - } else - return; - - g_strstrip (text); - - setval (url, (text && text[0]) ? text : NULL); - - emae_uri_changed (service, url); - camel_url_free (url); - g_free (text); -} - -static void -emae_service_url_path_changed (EMAccountEditorService *service, - void (*setval)(CamelURL *, const gchar *), - GtkWidget *widget) -{ - CamelURL *url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key); - const gchar *text = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); - - setval (url, (text && text[0]) ? text : NULL); - - emae_uri_changed (service, url); - camel_url_free (url); -} - -static void -emae_hostname_changed (GtkEntry *entry, - EMAccountEditorService *service) -{ - emae_service_url_changed (service, emae_url_set_host, GTK_WIDGET (entry)); -} - -static void -emae_port_changed (EPortEntry *pentry, - EMAccountEditorService *service) -{ - emae_service_url_changed (service, emae_url_set_port, GTK_WIDGET (pentry)); -} - -static void -emae_username_changed (GtkEntry *entry, - EMAccountEditorService *service) -{ - emae_service_url_changed (service, camel_url_set_user, GTK_WIDGET (entry)); -} - -static void -emae_path_changed (GtkWidget *widget, - EMAccountEditorService *service) -{ - emae_service_url_path_changed (service, camel_url_set_path, widget); -} - -static void -emae_ssl_changed (GtkComboBox *dropdown, - EMAccountEditorService *service) -{ - CamelURL *url; - - url = emae_account_url ( - service->emae, - emae_service_info[service->type].account_uri_key); - camel_url_set_port (url, e_port_entry_get_port (service->port)); - emae_uri_changed (service, url); - camel_url_free (url); + 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_setup_settings (EMAccountEditorService *service) { - EConfig *config; - EMConfigTargetAccount *target; 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); + + /* If we already have a CamelSettings instance + * of the appropriate type, leave it alone. */ + if (service->settings != NULL) { + if (G_OBJECT_TYPE (service->settings) == settings_type) + return; + } + url = emae_account_url ( service->emae, emae_service_info[service->type].account_uri_key); @@ -1673,33 +2096,56 @@ emae_setup_settings (EMAccountEditorService *service) /* Destroy any old CamelSettings instances. * Changing CamelProviders invalidates them. */ - if (service->settings != NULL) { + if (service->settings != NULL) camel_settings_save_to_url (service->settings, url); - g_object_unref (service->settings); - service->settings = NULL; + + 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); } - g_return_if_fail (service->provider != NULL); + camel_url_free (url); - service_type = service->provider->object_types[service->type]; - g_return_if_fail (g_type_is_a (service_type, CAMEL_TYPE_SERVICE)); + if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) { + emae_set_store_settings (service->emae, settings); + emae_set_transport_settings (service->emae, settings); - class = g_type_class_ref (service_type); + } else if (service->type == CAMEL_PROVIDER_STORE) { + emae_set_store_settings (service->emae, settings); - if (g_type_is_a (class->settings_type, CAMEL_TYPE_SETTINGS)) { - service->settings = g_object_new (class->settings_type, NULL); - camel_settings_load_from_url (service->settings, url); + } else if (service->type == CAMEL_PROVIDER_TRANSPORT) { + emae_set_transport_settings (service->emae, settings); } - g_type_class_unref (class); - camel_url_free (url); + if (CAMEL_IS_NETWORK_SETTINGS (settings)) { + const gchar *auth_mechanism; + gboolean service_requires_auth; + + auth_mechanism = + camel_network_settings_get_auth_mechanism ( + CAMEL_NETWORK_SETTINGS (settings)); + + service_requires_auth = (auth_mechanism != NULL); + + 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); - /* If settings implements CamelNetworkSettings, bind the - * "security-method" property to the security combo box - * and to the EPortEntry widget. */ - if (CAMEL_IS_NETWORK_SETTINGS (service->settings)) { g_object_bind_property_full ( - service->settings, "security-method", + settings, "security-method", service->use_ssl, "active-id", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE, @@ -1708,144 +2154,174 @@ emae_setup_settings (EMAccountEditorService *service) NULL, (GDestroyNotify) NULL); g_object_bind_property ( - service->settings, "security-method", + 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); + + switch (service->type) { + case CAMEL_PROVIDER_STORE: + emae_set_store_requires_auth ( + service->emae, service_requires_auth); + break; + + case CAMEL_PROVIDER_TRANSPORT: + emae_set_transport_requires_auth ( + service->emae, service_requires_auth); + break; + + default: + g_warn_if_reached (); + } } - /* Update the EConfigTarget so it has the latest CamelSettings. */ + if (CAMEL_IS_LOCAL_SETTINGS (settings)) { + const gchar *path; - config = E_CONFIG (service->emae->priv->config); - target = (EMConfigTargetAccount *) config->target; + path = camel_local_settings_get_path ( + CAMEL_LOCAL_SETTINGS (settings)); + gtk_file_chooser_set_filename ( + GTK_FILE_CHOOSER (service->pathentry), path); + } - em_config_target_new_account_update_settings ( - config, target, service->emae->priv->source.settings); + g_object_unref (settings); } static void emae_service_provider_changed (EMAccountEditorService *service) { - EAccount *account; - gint i, j; - gint old_port; - void (*show)(GtkWidget *); - CamelURL *url = emae_account_url (service->emae, emae_service_info[service->type].account_uri_key); + EConfig *config; + EMConfigTargetSettings *target; + CamelProvider *provider; + const gchar *description; - account = em_account_editor_get_modified_account (service->emae); + provider = camel_provider_get (service->protocol, NULL); - if (service->provider) { - gint enable; - GtkWidget *dwidget = NULL; + description = (provider != NULL) ? provider->description : ""; + gtk_label_set_text (service->description, description); - /* Remember the current port. Any following changes in SSL would overwrite it - and we don't want that since user can be using a non-standard port and we - would lost the value this way. */ - old_port = e_port_entry_get_port (service->port); + 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); - camel_url_set_protocol (url, service->provider->protocol); - gtk_label_set_text (service->description, service->provider->description); gtk_widget_show (service->frame); - enable = e_account_writable_option (account, service->provider->protocol, "auth"); - gtk_widget_set_sensitive ((GtkWidget *) service->authtype, enable); - gtk_widget_set_sensitive ((GtkWidget *) service->check_supported, enable); - - enable = e_account_writable_option (account, service->provider->protocol, "use_ssl"); - gtk_widget_set_sensitive ((GtkWidget *) service->use_ssl, enable); - - enable = e_account_writable (account, emae_service_info[service->type].save_passwd_key); - gtk_widget_set_sensitive ((GtkWidget *) service->remember, enable); - - for (i = 0; emae_service_info[service->type].host_info[i].flag; i++) { - GtkWidget *w; - gint hide; - struct _provider_host_info *info = &emae_service_info[service->type].host_info[i]; - - enable = CAMEL_PROVIDER_ALLOWS (service->provider, info->flag); - hide = CAMEL_PROVIDER_HIDDEN (service->provider, info->flag); - show = (enable && !hide) ? gtk_widget_show : gtk_widget_hide; - - for (j = 0; j < G_N_ELEMENTS (info->widgets); j++) { - if (info->widgets[j] && (w = G_STRUCT_MEMBER (GtkWidget *, service, info->widgets[j]))) { - show (w); - if (j == 0) { - if (dwidget == NULL && enable) - dwidget = w; - - if (info->setval && !hide) { - if (GTK_IS_ENTRY (w)) - info->setval (url, enable ? gtk_entry_get_text ((GtkEntry *) w) : NULL); - else if (E_IS_PORT_ENTRY (w)) - info->setval (url, enable ? g_strdup_printf ("%i", - e_port_entry_get_port (E_PORT_ENTRY (w))) : NULL); - } - } - } - } - } + 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; - if (dwidget) - gtk_widget_grab_focus (dwidget); + 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; - if (CAMEL_PROVIDER_ALLOWS (service->provider, CAMEL_URL_PART_AUTH)) { - if (service->needs_auth && !CAMEL_PROVIDER_NEEDS (service->provider, CAMEL_URL_PART_AUTH)) + 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); - if (service->provider->flags & CAMEL_PROVIDER_SUPPORTS_SSL) { - camel_url_set_port (url, e_port_entry_get_port (service->port)); - show = gtk_widget_show; - } else { - show = gtk_widget_hide; - } - show (service->ssl_frame); - show (service->ssl_hbox); #else gtk_widget_hide (service->ssl_hbox); gtk_widget_show (service->no_ssl); #endif - /* When everything is set it is safe to put back user's original port. */ - if (url->port && service->provider->port_entries) - e_port_entry_set_port (service->port, old_port); - } else { - camel_url_set_protocol (url, NULL); - gtk_label_set_text (service->description, ""); gtk_widget_hide (service->frame); gtk_widget_hide (service->auth_frame); gtk_widget_hide (service->ssl_frame); } - /* FIXME: linked services? */ - /* FIXME: permissions setup */ + /* Update the EConfigTarget so it has the latest CamelSettings. */ - emae_uri_changed (service, url); - camel_url_free (url); + 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 *dropdown, +emae_provider_changed (GtkComboBox *combo_box, EMAccountEditorService *service) { - gint id = gtk_combo_box_get_active (dropdown); - GtkTreeModel *model; - GtkTreeIter iter; + const gchar *active_protocol; - if (id == -1) - return; + active_protocol = gtk_combo_box_get_active_id (combo_box); - model = gtk_combo_box_get_model (dropdown); - if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, id)) + if (g_strcmp0 (active_protocol, service->protocol) == 0) return; - gtk_tree_model_get (model, &iter, 1, &service->provider, -1); + service->protocol = active_protocol; switch (service->type) { case CAMEL_PROVIDER_STORE: @@ -1864,109 +2340,60 @@ emae_provider_changed (GtkComboBox *dropdown, emae_service_provider_changed (service); - e_config_target_changed ((EConfig *) service->emae->priv->config, E_CONFIG_TARGET_CHANGED_REBUILD); + e_config_target_changed ( + (EConfig *) service->emae->priv->config, + E_CONFIG_TARGET_CHANGED_REBUILD); } static void emae_refresh_providers (EMAccountEditor *emae, EMAccountEditorService *service) { - EAccount *account; - GtkListStore *store; - GtkTreeIter iter; - GList *l; - GtkCellRenderer *cell = gtk_cell_renderer_text_new (); - GtkComboBox *dropdown; - gint active = 0, i; - struct _service_info *info = &emae_service_info[service->type]; - const gchar *uri; - gchar *current = NULL; - CamelURL *url; - - account = em_account_editor_get_modified_account (emae); - uri = e_account_get_string (account, info->account_uri_key); - - dropdown = service->providers; - gtk_widget_show ((GtkWidget *) dropdown); + GtkComboBoxText *combo_box; + GList *link; - if (uri) { - const gchar *colon = strchr (uri, ':'); - gint len; - - if (colon) { - len = colon - uri; - current = g_alloca (len + 1); - memcpy (current, uri, len); - current[len] = 0; - } - } else { - /* Promote the newer IMAP provider over the older one. */ - current = (gchar *) "imapx"; - } + combo_box = GTK_COMBO_BOX_TEXT (service->providers); - store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); + g_signal_handlers_block_by_func ( + combo_box, emae_provider_changed, service); - i = 0; + gtk_combo_box_text_remove_all (combo_box); /* We just special case each type here, its just easier */ - if (service->type == CAMEL_PROVIDER_STORE) { - gtk_list_store_append (store, &iter); - /* Translators: "None" for receiving account type, beside of IMAP, POP3, ... */ - gtk_list_store_set (store, &iter, 0, C_("mail-receiving", "None"), 1, NULL, -1); - i++; - } + if (service->type == CAMEL_PROVIDER_STORE) + gtk_combo_box_text_append ( + combo_box, NULL, + C_("mail-receiving", "None")); - for (l = emae->priv->providers; l; l = l->next) { - CamelProvider *provider = l->data; + for (link = emae->priv->providers; link != NULL; link = link->next) { + CamelProvider *provider = link->data; + gboolean mail_or_news_domain; - if (!((strcmp (provider->domain, "mail") == 0 - || strcmp (provider->domain, "news") == 0) + mail_or_news_domain = + (g_strcmp0 (provider->domain, "mail") == 0) || + (g_strcmp0 (provider->domain, "news") == 0); + + /* FIXME This expression is awesomely unreadable! */ + if (!(mail_or_news_domain && provider->object_types[service->type] - && (service->type != CAMEL_PROVIDER_STORE || (provider->flags & CAMEL_PROVIDER_IS_SOURCE) != 0)) + && (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_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, provider->name, 1, provider, -1); - - /* find the displayed and set default */ - if (i == 0 || (current && strcmp (provider->protocol, current) == 0)) { - CamelURL *url; - - service->provider = provider; - emae_setup_settings (service); - active = i; - - url = emae_account_url (emae, info->account_uri_key); - if (current == NULL) { - /* we need to set this value on the uri too */ - camel_url_set_protocol (url, provider->protocol); - } - - emae_uri_changed (service, url); - uri = e_account_get_string (account, info->account_uri_key); - camel_url_free (url); - } - i++; + gtk_combo_box_text_append ( + combo_box, + provider->protocol, + provider->name); } - gtk_cell_layout_clear ((GtkCellLayout *) dropdown); - gtk_combo_box_set_model (dropdown, (GtkTreeModel *) store); - gtk_cell_layout_pack_start ((GtkCellLayout *) dropdown, cell, TRUE); - gtk_cell_layout_set_attributes ((GtkCellLayout *)dropdown, cell, "text", 0, NULL); - - g_signal_handlers_disconnect_by_func (dropdown, emae_provider_changed, service); - gtk_combo_box_set_active (dropdown, -1); /* needed for gtkcombo bug (?) */ - gtk_combo_box_set_active (dropdown, active); - g_signal_connect (dropdown, "changed", G_CALLBACK(emae_provider_changed), service); - - if (!uri || (url = camel_url_new (uri, NULL)) == NULL) { - return; - } + g_signal_handlers_unblock_by_func ( + combo_box, emae_provider_changed, service); - camel_url_free (url); + gtk_combo_box_set_active_id ( + GTK_COMBO_BOX (combo_box), service->protocol); } static void @@ -1979,12 +2406,12 @@ emae_authtype_changed (GtkComboBox *combo_box, mechanism = gtk_combo_box_get_active_id (combo_box); - if (mechanism != NULL) { + if (mechanism != NULL && *mechanism != '\0') { authtype = camel_sasl_authtype (mechanism); g_warn_if_fail (authtype != NULL); } - sensitive = (authtype != NULL) && (authtype->need_password); + sensitive = (authtype == NULL) || (authtype->need_password); gtk_widget_set_sensitive (GTK_WIDGET (service->remember), sensitive); } @@ -2057,32 +2484,23 @@ emae_check_authtype (GtkWidget *w, CamelService *camel_service; EMailBackend *backend; EMailSession *session; - EAccount *account; GtkWidget *editor; gpointer parent; gchar *uid; - gchar *url_string; - CamelURL *url; GError *error = NULL; - account = em_account_editor_get_modified_account (service->emae); 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); - url_string = (gchar *) e_account_get_string ( - account, emae_service_info[service->type].account_uri_key); - url = camel_url_new (url_string, NULL); /* to test on actual data, not on previously used */ camel_service = camel_session_add_service ( CAMEL_SESSION (session), uid, - url->protocol, service->type, &error); + service->protocol, service->type, &error); - camel_url_free (url); - g_free (url_string); g_free (uid); if (camel_service != NULL && service->settings != NULL) @@ -2136,21 +2554,18 @@ emae_setup_service (EMAccountEditor *emae, EMAccountEditorService *service, GtkBuilder *builder) { - EAccount *account; struct _service_info *info = &emae_service_info[service->type]; - CamelURL *url = emae_account_url (emae, info->account_uri_key); - CamelNetworkSettings *network_settings = NULL; - const gchar *auth_mechanism = NULL; - - account = em_account_editor_get_modified_account (emae); + CamelProvider *provider; + CamelURL *url; - service->provider = url && url->protocol ? camel_provider_get (url->protocol, NULL) : NULL; + /* GtkComboBox internalizes ID strings, which for the provider + * combo box are protocol names. So we'll do the same here. */ + url = emae_account_url (emae, info->account_uri_key); + if (url != NULL && url->protocol != NULL) + service->protocol = g_intern_string (url->protocol); + camel_url_free (url); - if (CAMEL_IS_NETWORK_SETTINGS (service->settings)) { - network_settings = CAMEL_NETWORK_SETTINGS (service->settings); - auth_mechanism = camel_network_settings_get_auth_mechanism ( - network_settings); - } + provider = camel_provider_get (service->protocol, NULL); /* Extract all widgets we need from the builder file. */ @@ -2179,6 +2594,15 @@ emae_setup_service (EMAccountEditor *emae, 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) { @@ -2187,13 +2611,14 @@ emae_setup_service (EMAccountEditor *emae, service->needs_auth = NULL; } - g_signal_connect (service->hostname, "changed", G_CALLBACK (emae_hostname_changed), service); - g_signal_connect (service->port, "changed", G_CALLBACK (emae_port_changed), service); - g_signal_connect (service->username, "changed", G_CALLBACK (emae_username_changed), service); - if (service->pathentry) - g_signal_connect (GTK_FILE_CHOOSER (service->pathentry), "selection-changed", G_CALLBACK (emae_path_changed), service); + g_signal_connect ( + service->providers, "changed", + G_CALLBACK (emae_provider_changed), service); - g_signal_connect (service->use_ssl, "changed", G_CALLBACK(emae_ssl_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", @@ -2210,13 +2635,6 @@ emae_setup_service (EMAccountEditor *emae, service->authtype, "provider", G_BINDING_SYNC_CREATE); - if (network_settings != NULL) - g_object_bind_property ( - network_settings, "auth-mechanism", - service->authtype, "active-id", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - if (service->needs_auth != NULL) { g_object_bind_property ( emae, "store-requires-auth", @@ -2229,8 +2647,50 @@ emae_setup_service (EMAccountEditor *emae, G_BINDING_SYNC_CREATE); } - emae_set_store_requires_auth ( - emae, auth_mechanism != NULL); + 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; @@ -2240,13 +2700,6 @@ emae_setup_service (EMAccountEditor *emae, service->authtype, "provider", G_BINDING_SYNC_CREATE); - if (network_settings != NULL) - g_object_bind_property ( - network_settings, "auth-mechanism", - service->authtype, "active-id", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - if (service->needs_auth != NULL) { g_object_bind_property ( emae, "transport-requires-auth", @@ -2259,8 +2712,40 @@ emae_setup_service (EMAccountEditor *emae, G_BINDING_SYNC_CREATE); } - emae_set_transport_requires_auth ( - emae, auth_mechanism != NULL); + 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; @@ -2268,52 +2753,39 @@ emae_setup_service (EMAccountEditor *emae, g_warn_if_reached (); } - /* configure ui for current settings */ - if (url->host) { - gtk_entry_set_text (service->hostname, url->host); - } - - if (url->user && *url->user) { - gtk_entry_set_text (service->username, url->user); - } - if (service->pathentry) { - GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; + GtkFileChooserAction action; + gboolean need_path_dir; + const gchar *label; - if (service->provider && (service->provider->url_flags & CAMEL_URL_NEED_PATH_DIR) == 0) + 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), - action == GTK_FILE_CHOOSER_ACTION_OPEN ? _("Fil_e:") : _("_Path:")); + 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); - - if (url->path) - gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (service->pathentry), url->path); } /* old authtype will be destroyed when we exit */ emae_refresh_providers (emae, service); - if (service->provider && service->provider->port_entries) - e_port_entry_set_camel_entries (service->port, service->provider->port_entries); - - /* Set the port after SSL is set, because it would overwrite the - * port value (through emae_ssl_changed signal) */ - if (url->port && service->provider->port_entries) { - e_port_entry_set_port (service->port, url->port); - } - - if (!e_account_writable (account, info->account_uri_key)) - gtk_widget_set_sensitive (service->container, FALSE); - else - gtk_widget_set_sensitive (service->container, TRUE); + if (provider != NULL && provider->port_entries) + e_port_entry_set_camel_entries ( + service->port, provider->port_entries); emae_service_provider_changed (service); - - camel_url_free (url); } static GtkWidget * @@ -2786,12 +3258,16 @@ 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); @@ -2821,7 +3297,7 @@ emae_option_options (EMAccountEditorService *service, gtk_list_store_append (store, &iter); gtk_list_store_set ( store, &iter, 0, vl, 1, dgettext ( - service->provider->translation_domain, cp), -1); + provider->translation_domain, cp), -1); g_free (vl); g_free (cp); @@ -2859,11 +3335,13 @@ emae_receive_options_item (EConfig *ec, gpointer data) { EMAccountEditor *emae = data; + CamelProvider *provider; GtkWidget *w, *box, *spin; guint row; - if (emae->priv->source.provider == NULL - || emae->priv->source.provider->extra_conf == NULL) + provider = emae_get_store_provider (emae); + + if (provider == NULL || provider->extra_conf == NULL) return NULL; if (old) { @@ -2923,6 +3401,7 @@ emae_receive_options_extra_item (EConfig *ec, GtkWidget *widget; GtkLabel *label; GtkTable *table; + CamelProvider *provider; CamelProviderConfEntry *entries; guint row; GHashTable *extra; @@ -2933,12 +3412,13 @@ emae_receive_options_extra_item (EConfig *ec, service = &emae->priv->source; section_name = eitem->user_data; - if (emae->priv->source.provider == NULL) - return NULL; + provider = emae_get_store_provider (emae); - if (emae->priv->source.provider->extra_conf == NULL) + if (provider == NULL || provider->extra_conf == NULL) return NULL; + entries = provider->extra_conf; + if (emae->type == EMAE_PAGES) { GtkWidget *box; @@ -2952,7 +3432,6 @@ emae_receive_options_extra_item (EConfig *ec, GTK_BOX (emae->pages[2]), box, FALSE, FALSE, 0); } - entries = emae->priv->source.provider->extra_conf; 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) @@ -3095,11 +3574,17 @@ emae_send_page (EConfig *ec, { EMAccountEditor *emae = data; EMAccountEditorPrivate *priv = emae->priv; + CamelProvider *provider; GtkWidget *w; GtkBuilder *builder; + provider = emae_get_store_provider (emae); + + if (provider == NULL) + return NULL; + /* no transport options page at all for these types of providers */ - if (priv->source.provider && CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (priv->source.provider)) { + if (CAMEL_PROVIDER_IS_STORE_AND_TRANSPORT (provider)) { memset (&priv->transport.frame, 0, ((gchar *) &priv->transport.check_dialog) - ((gchar *) &priv->transport.frame)); return NULL; } @@ -3249,6 +3734,7 @@ emae_defaults_page (EConfig *ec, EMAccountEditorPrivate *priv = emae->priv; EMFolderSelectionButton *button; CamelProviderFlags flags; + CamelProvider *provider; CamelSettings *settings; CamelStore *store = NULL; EMailBackend *backend; @@ -3279,6 +3765,7 @@ emae_defaults_page (EConfig *ec, store = CAMEL_STORE (service); } + provider = emae_get_store_provider (emae); settings = emae->priv->source.settings; /* Make sure we have a valid EMailBackend. */ @@ -3338,8 +3825,9 @@ emae_defaults_page (EConfig *ec, } flags = CAMEL_PROVIDER_ALLOW_REAL_TRASH_FOLDER; - visible = (emae->priv->source.provider != NULL) && - ((emae->priv->source.provider->flags & flags) != 0); + 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); @@ -3383,8 +3871,9 @@ emae_defaults_page (EConfig *ec, } flags = CAMEL_PROVIDER_ALLOW_REAL_JUNK_FOLDER; - visible = (emae->priv->source.provider != NULL) && - ((emae->priv->source.provider->flags & flags) != 0); + 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); @@ -3400,18 +3889,12 @@ emae_defaults_page (EConfig *ec, 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 ((GtkWidget *) priv->drafts_folder_button, e_account_writable (account, E_ACCOUNT_DRAFTS_FOLDER_URI)); - gtk_widget_set_sensitive ( (GtkWidget *) priv->sent_folder_button, - e_account_writable (account, E_ACCOUNT_SENT_FOLDER_URI) - && - (emae->priv->source.provider ? !(emae->priv->source.provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER): TRUE) + (provider ? !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER): TRUE) ); gtk_widget_set_sensitive ((GtkWidget *) priv->restore_folders_button, - (e_account_writable (account, E_ACCOUNT_SENT_FOLDER_URI) - && ((emae->priv->source.provider && !( emae->priv->source.provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)) - || e_account_writable (account, E_ACCOUNT_DRAFTS_FOLDER_URI)))); + (provider && !(provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER))); /* Receipt policy */ emae_setup_receipt_policy (emae, builder); @@ -3499,7 +3982,6 @@ emae_account_hash_algo_combo (EMAccountEditor *emae, 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); - gtk_widget_set_sensitive (GTK_WIDGET (combobox), e_account_writable (account, item)); return combobox; } @@ -3757,41 +4239,64 @@ static gboolean emae_service_complete (EMAccountEditor *emae, EMAccountEditorService *service) { - EAccount *account; - CamelURL *url; - gint ok = TRUE; - const gchar *uri; - - if (service->provider == NULL) + CamelProvider *provider; + 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; + + provider = camel_provider_get (service->protocol, NULL); + + if (provider == NULL) return TRUE; - account = em_account_editor_get_modified_account (emae); + if (CAMEL_IS_NETWORK_SETTINGS (service->settings)) { + CamelNetworkSettings *network_settings; - uri = e_account_get_string (account, emae_service_info[service->type].account_uri_key); - if (uri == NULL || (url = camel_url_new (uri, NULL)) == NULL) - return FALSE; + 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_PROVIDER_NEEDS (service->provider, CAMEL_URL_PART_HOST)) { - if (url->host == NULL || url->host[0] == 0 || (!e_port_entry_is_valid (service->port) && service->provider->port_entries)) - ok = FALSE; + 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 (ok - && (service->needs_auth == NULL - || CAMEL_PROVIDER_NEEDS (service->provider, CAMEL_URL_PART_AUTH) - || gtk_toggle_button_get_active (service->needs_auth)) - && CAMEL_PROVIDER_NEEDS (service->provider, CAMEL_URL_PART_USER) - && (url->user == NULL || url->user[0] == 0)) - ok = FALSE; - - if (ok - && CAMEL_PROVIDER_NEEDS (service->provider, CAMEL_URL_PART_PATH) - && (url->path == NULL || url->path[0] == 0)) - ok = FALSE; + if (need_auth || service->requires_auth) + if (need_user && !have_user) + return FALSE; - camel_url_free (url); + if (need_path && !have_path) + return FALSE; - return ok; + return TRUE; } static ServerData * @@ -3868,7 +4373,6 @@ emae_check_complete (EConfig *ec, refresh = TRUE; if (sdata && sdata->recv_user && *sdata->recv_user) use_user = g_str_equal (sdata->recv_user, "@") ? tmp : sdata->recv_user; - camel_url_set_user (url, use_user); gtk_entry_set_text (emae->priv->source.username, use_user); if (sdata != NULL) { @@ -3937,7 +4441,6 @@ emae_check_complete (EConfig *ec, if (sdata->send_user && *sdata->send_user) use_user = g_str_equal (sdata->send_user, "@") ? tmp : sdata->send_user; - camel_url_set_user (url, use_user); gtk_entry_set_text (emae->priv->transport.username, use_user); uri = camel_url_to_string (url, 0); @@ -3957,9 +4460,13 @@ emae_check_complete (EConfig *ec, } } else if (!strcmp (pageid, "20.receive_options")) { - if (emae->priv->source.provider - && emae->priv->extra_provider != emae->priv->source.provider) { - emae->priv->extra_provider = emae->priv->source.provider; + 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); } } else if (!strcmp (pageid, "40.management")) { @@ -4093,12 +4600,13 @@ emae_commit (EConfig *ec, EAccount *original_account; 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); - /*** Do some last minute tweaking. ***/ + /* Do some last minute tweaking. */ settings = emae->priv->source.settings; requires_auth = emae_get_store_requires_auth (emae); @@ -4116,50 +4624,41 @@ emae_commit (EConfig *ec, if (CAMEL_IS_NETWORK_SETTINGS (settings) && !requires_auth) g_object_set (settings, "auth-mechanism", NULL, NULL); - /*** Dump each service's CamelSettings to a URL string. ***/ + /* Dump the storage service settings to a URL string. */ - url = camel_url_new (modified_account->source->url, NULL); - if (url != NULL) { - if (emae->priv->source.settings != NULL) { - gchar *host = g_strdup (url->host); - gchar *path = g_strdup (url->path); - gint port = url->port; + url = g_new0 (CamelURL, 1); - camel_settings_save_to_url ( - emae->priv->source.settings, url); + protocol = emae->priv->source.protocol; + settings = emae->priv->source.settings; - camel_url_set_host (url, host); - camel_url_set_path (url, path); - camel_url_set_port (url, port); + if (protocol != NULL) + camel_url_set_protocol (url, protocol); - g_free (host); - g_free (path); - } - g_free (modified_account->source->url); - modified_account->source->url = camel_url_to_string (url, 0); - camel_url_free (url); - } + if (settings != NULL) + camel_settings_save_to_url (settings, url); - url = camel_url_new (modified_account->transport->url, NULL); - if (url != NULL) { - if (emae->priv->transport.settings != NULL) { - gchar *host = g_strdup (url->host); - gchar *path = g_strdup (url->path); - gint port = url->port; - - camel_settings_save_to_url ( - emae->priv->transport.settings, url); - camel_url_set_host (url, host); - camel_url_set_path (url, path); - camel_url_set_port (url, port); - - g_free (host); - g_free (path); - } - g_free (modified_account->transport->url); - modified_account->transport->url = camel_url_to_string (url, 0); - camel_url_free (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 = g_new0 (CamelURL, 1); + + protocol = emae->priv->transport.protocol; + settings = emae->priv->transport.settings; + + if (protocol != NULL) + camel_url_set_protocol (url, protocol); + + 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) { d (printf ("Committing account '%s'\n", e_account_get_string (modified_account, E_ACCOUNT_NAME))); @@ -4170,15 +4669,19 @@ emae_commit (EConfig *ec, account = original_account; e_account_list_change (accounts, account); } else { + CamelProvider *provider; + d (printf ("Adding new account '%s'\n", e_account_get_string (account, E_ACCOUNT_NAME))); e_account_list_add (accounts, modified_account); account = modified_account; + provider = emae_get_store_provider (emae); + /* HACK: this will add the account to the folder tree. * We should just be listening to the account list directly for changed events */ if (account->enabled - && emae->priv->source.provider - && (emae->priv->source.provider->flags & CAMEL_PROVIDER_IS_STORAGE)) { + && provider != NULL + && (provider->flags & CAMEL_PROVIDER_IS_STORAGE)) { EMailBackend *backend; EMailSession *session; @@ -4206,20 +4709,20 @@ em_account_editor_construct (EMAccountEditor *emae, const gchar *id) { EMAccountEditorPrivate *priv = emae->priv; - EAccount *original_account; - EAccount *modified_account; gint i, index; GSList *l; GList *prov; EMConfig *ec; - EMConfigTargetAccount *target; + EMConfigTargetSettings *target; GHashTable *have; EConfigItem *items; emae->type = type; /* sort the providers, remote first */ - priv->providers = g_list_sort (camel_provider_list (TRUE), (GCompareFunc) provider_compare); + priv->providers = g_list_sort ( + camel_provider_list (TRUE), + (GCompareFunc) provider_compare); if (type == EMAE_NOTEBOOK) { ec = em_config_new (E_CONFIG_BOOK, id); @@ -4300,11 +4803,13 @@ em_account_editor_construct (EMAccountEditor *emae, e_config_add_page_check ((EConfig *) ec, NULL, emae_check_complete, emae); - original_account = em_account_editor_get_original_account (emae); - modified_account = em_account_editor_get_modified_account (emae); - target = em_config_target_new_account ( - ec, original_account, modified_account, - emae->priv->source.settings); + 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-config.c b/mail/em-config.c index c9bcf0a7a4..e9c1105c85 100644 --- a/mail/em-config.c +++ b/mail/em-config.c @@ -40,31 +40,6 @@ G_DEFINE_TYPE (EMConfig, em_config, E_TYPE_CONFIG) -struct _EMConfigPrivate { - gint account_changed_id; -}; - -static void -emp_account_changed (EAccount *ea, - gint id, - EMConfig *emc) -{ - e_config_target_changed ((EConfig *) emc, E_CONFIG_TARGET_CHANGED_STATE); -} - -static void -em_config_finalize (GObject *object) -{ - /* Note we can't be unreffed if a target exists, so the target - * will need to be freed first which will clean up any - * listeners */ - - g_free (((EMConfig *) object)->priv); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (em_config_parent_class)->finalize (object); -} - static void em_config_set_target (EConfig *ep, EConfigTarget *t) @@ -80,16 +55,16 @@ em_config_set_target (EConfig *ep, case EM_CONFIG_TARGET_PREFS: { /*EMConfigTargetPrefs *s = (EMConfigTargetPrefs *)t;*/ break; } - case EM_CONFIG_TARGET_ACCOUNT: { - EMConfigTargetAccount *s = (EMConfigTargetAccount *) t; - EMConfig *config = (EMConfig *) ep; - - config->priv->account_changed_id = g_signal_connect ( - s->modified_account, "changed", - G_CALLBACK (emp_account_changed), ep); - - em_config_target_new_account_update_settings ( - ep, s, s->settings); + case EM_CONFIG_TARGET_SETTINGS: { + EMConfigTargetSettings *s = (EMConfigTargetSettings *) t; + + em_config_target_update_settings ( + ep, s, + s->email_address, + s->storage_protocol, + s->storage_settings, + s->transport_protocol, + s->transport_settings); break; } } } @@ -105,18 +80,11 @@ em_config_target_free (EConfig *ep, break; case EM_CONFIG_TARGET_PREFS: break; - case EM_CONFIG_TARGET_ACCOUNT: { - EMConfigTargetAccount *s = (EMConfigTargetAccount *) t; - EMConfig *config = (EMConfig *) ep; - - if (config->priv->account_changed_id > 0) { - g_signal_handler_disconnect ( - s->modified_account, - config->priv->account_changed_id); - config->priv->account_changed_id = 0; - } - - em_config_target_new_account_update_settings (ep, s, NULL); + case EM_CONFIG_TARGET_SETTINGS: { + EMConfigTargetSettings *s = (EMConfigTargetSettings *) t; + + em_config_target_update_settings ( + ep, s, NULL, NULL, NULL, NULL, NULL); break; } } } @@ -133,15 +101,14 @@ em_config_target_free (EConfig *ep, if (s->gconf) g_object_unref (s->gconf); break; } - case EM_CONFIG_TARGET_ACCOUNT: { - EMConfigTargetAccount *s = (EMConfigTargetAccount *) t; - - if (s->original_account != NULL) - g_object_unref (s->original_account); - if (s->modified_account != NULL) - g_object_unref (s->modified_account); - if (s->settings != NULL) - g_object_unref (s->settings); + case EM_CONFIG_TARGET_SETTINGS: { + EMConfigTargetSettings *s = (EMConfigTargetSettings *) t; + + g_free (s->email_address); + if (s->storage_settings != NULL) + g_object_unref (s->storage_settings); + if (s->transport_settings != NULL) + g_object_unref (s->transport_settings); break; } } @@ -152,11 +119,8 @@ em_config_target_free (EConfig *ep, static void em_config_class_init (EMConfigClass *class) { - GObjectClass *object_class; EConfigClass *config_class; - object_class = G_OBJECT_CLASS (class); - object_class->finalize = em_config_finalize; config_class = E_CONFIG_CLASS (class); config_class->set_target = em_config_set_target; @@ -166,7 +130,6 @@ em_config_class_init (EMConfigClass *class) static void em_config_init (EMConfig *emp) { - emp->priv = g_malloc0 (sizeof (*emp->priv)); } EMConfig * @@ -212,56 +175,78 @@ em_config_target_new_prefs (EMConfig *emp, return t; } -EMConfigTargetAccount * -em_config_target_new_account (EMConfig *emp, - EAccount *original_account, - EAccount *modified_account, - CamelSettings *settings) +EMConfigTargetSettings * +em_config_target_new_settings (EMConfig *emp, + const gchar *email_address, + const gchar *storage_protocol, + CamelSettings *storage_settings, + const gchar *transport_protocol, + CamelSettings *transport_settings) { - EMConfigTargetAccount *t; + EMConfigTargetSettings *target; - t = e_config_target_new ( - &emp->config, EM_CONFIG_TARGET_ACCOUNT, sizeof (*t)); + target = e_config_target_new ( + &emp->config, EM_CONFIG_TARGET_SETTINGS, sizeof (*target)); - if (original_account != NULL) - t->original_account = g_object_ref (original_account); - else - t->original_account = NULL; + if (storage_protocol != NULL) + storage_protocol = g_intern_string (storage_protocol); - if (modified_account != NULL) - t->modified_account = g_object_ref (modified_account); - else - t->modified_account = NULL; + if (storage_settings != NULL) + g_object_ref (storage_settings); - if (settings != NULL) - t->settings = g_object_ref (settings); - else - t->settings = NULL; + if (transport_protocol != NULL) + transport_protocol = g_intern_string (transport_protocol); - return t; + if (transport_settings != NULL) + g_object_ref (transport_settings); + + target->email_address = g_strdup (email_address); + + target->storage_protocol = storage_protocol; + target->storage_settings = storage_settings; + + target->transport_protocol = transport_protocol; + target->transport_settings = transport_settings; + + return target; } void -em_config_target_new_account_update_settings (EConfig *ep, - EMConfigTargetAccount *target, - CamelSettings *settings) +em_config_target_update_settings (EConfig *ep, + EMConfigTargetSettings *target, + const gchar *email_address, + const gchar *storage_protocol, + CamelSettings *storage_settings, + const gchar *transport_protocol, + CamelSettings *transport_settings) { g_return_if_fail (ep != NULL); g_return_if_fail (target != NULL); - if (settings) - g_object_ref (settings); + if (storage_protocol != NULL) + storage_protocol = g_intern_string (storage_protocol); - if (target->settings != NULL) { - g_signal_handlers_disconnect_by_func ( - target->settings, emp_account_changed, ep); - g_object_unref (target->settings); - } + if (storage_settings != NULL) + g_object_ref (storage_settings); + + if (transport_protocol != NULL) + transport_protocol = g_intern_string (transport_protocol); + + if (transport_settings != NULL) + g_object_ref (transport_settings); + + if (target->storage_settings != NULL) + g_object_unref (target->storage_settings); + + if (target->transport_settings != NULL) + g_object_unref (target->transport_settings); + + g_free (target->email_address); + target->email_address = g_strdup (email_address); - target->settings = settings; + target->storage_protocol = storage_protocol; + target->storage_settings = storage_settings; - if (target->settings != NULL) - g_signal_connect ( - target->settings, "notify", - G_CALLBACK (emp_account_changed), ep); + target->transport_protocol = transport_protocol; + target->transport_settings = transport_settings; } diff --git a/mail/em-config.h b/mail/em-config.h index dcd5194ea5..24a75fb511 100644 --- a/mail/em-config.h +++ b/mail/em-config.h @@ -40,12 +40,12 @@ typedef struct _EMConfigPrivate EMConfigPrivate; enum _em_config_target_t { EM_CONFIG_TARGET_FOLDER, EM_CONFIG_TARGET_PREFS, - EM_CONFIG_TARGET_ACCOUNT + EM_CONFIG_TARGET_SETTINGS }; typedef struct _EMConfigTargetFolder EMConfigTargetFolder; typedef struct _EMConfigTargetPrefs EMConfigTargetPrefs; -typedef struct _EMConfigTargetAccount EMConfigTargetAccount; +typedef struct _EMConfigTargetSettings EMConfigTargetSettings; struct _EMConfigTargetFolder { EConfigTarget target; @@ -60,12 +60,16 @@ struct _EMConfigTargetPrefs { GConfClient *gconf; }; -struct _EMConfigTargetAccount { +struct _EMConfigTargetSettings { EConfigTarget target; - EAccount *original_account; - EAccount *modified_account; - CamelSettings *settings; + gchar *email_address; + + const gchar *storage_protocol; + CamelSettings *storage_settings; + + const gchar *transport_protocol; + CamelSettings *transport_settings; }; typedef struct _EConfigItem EMConfigItem; @@ -88,15 +92,21 @@ EMConfigTargetFolder * EMConfigTargetPrefs * em_config_target_new_prefs (EMConfig *emp, GConfClient *gconf); -EMConfigTargetAccount * - em_config_target_new_account (EMConfig *emp, - EAccount *original_account, - EAccount *modified_account, - CamelSettings *settings); -void em_config_target_new_account_update_settings +EMConfigTargetSettings * + em_config_target_new_settings (EMConfig *emp, + const gchar *email_address, + const gchar *storage_protocol, + CamelSettings *storage_settings, + const gchar *transport_protocol, + CamelSettings *transport_settings); +void em_config_target_update_settings (EConfig *ep, - EMConfigTargetAccount *target, - CamelSettings *settings); + EMConfigTargetSettings *target, + const gchar *email_address, + const gchar *storage_protocol, + CamelSettings *storage_settings, + const gchar *transport_protocol, + CamelSettings *transport_settings); G_END_DECLS diff --git a/mail/mail-config.ui b/mail/mail-config.ui index 9098b603a3..55510b660e 100644 --- a/mail/mail-config.ui +++ b/mail/mail-config.ui @@ -4897,7 +4897,7 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkComboBox" id="source_type_dropdown"> + <object class="GtkComboBoxText" id="source_type_dropdown"> <property name="visible">True</property> <property name="can_focus">False</property> </object> @@ -5378,7 +5378,7 @@ For example: "Work" or "Personal"</property> </packing> </child> <child> - <object class="GtkComboBox" id="transport_type_dropdown"> + <object class="GtkComboBoxText" id="transport_type_dropdown"> <property name="visible">True</property> <property name="can_focus">False</property> </object> diff --git a/modules/mail/e-mail-config-hook.c b/modules/mail/e-mail-config-hook.c index b247c90ec2..cc9734647b 100644 --- a/modules/mail/e-mail-config-hook.c +++ b/modules/mail/e-mail-config-hook.c @@ -35,7 +35,7 @@ static const EConfigHookTargetMask no_masks[] = { static const EConfigHookTargetMap targets[] = { { "folder", EM_CONFIG_TARGET_FOLDER, no_masks }, { "prefs", EM_CONFIG_TARGET_PREFS, no_masks }, - { "account", EM_CONFIG_TARGET_ACCOUNT, no_masks }, + { "settings", EM_CONFIG_TARGET_SETTINGS, no_masks }, { NULL } }; diff --git a/plugins/backup-restore/backup-restore.c b/plugins/backup-restore/backup-restore.c index acef0ae223..1a389703e9 100644 --- a/plugins/backup-restore/backup-restore.c +++ b/plugins/backup-restore/backup-restore.c @@ -52,9 +52,9 @@ gboolean e_plugin_ui_init (GtkUIManager *ui_manager, GtkWidget * backup_restore_page (EPlugin *ep, EConfigHookItemFactoryData *hook_data); void backup_restore_commit (EPlugin *ep, - EMConfigTargetAccount *target); + EMConfigTargetSettings *target); void backup_restore_abort (EPlugin *ep, - EMConfigTargetAccount *target); + EMConfigTargetSettings *target); typedef enum _br_flags { BR_OK = 1 << 0, @@ -434,7 +434,7 @@ backup_restore_page (EPlugin *ep, void backup_restore_commit (EPlugin *ep, - EMConfigTargetAccount *target) + EMConfigTargetSettings *target) { GObject *assistant; gchar *file; @@ -456,7 +456,7 @@ backup_restore_commit (EPlugin *ep, void backup_restore_abort (EPlugin *ep, - EMConfigTargetAccount *target) + EMConfigTargetSettings *target) { /* Nothing really */ } diff --git a/plugins/backup-restore/org-gnome-backup-restore.eplug.xml b/plugins/backup-restore/org-gnome-backup-restore.eplug.xml index 653ad6299f..4899b2dd8a 100644 --- a/plugins/backup-restore/org-gnome-backup-restore.eplug.xml +++ b/plugins/backup-restore/org-gnome-backup-restore.eplug.xml @@ -23,7 +23,7 @@ </hook> <hook class="org.gnome.evolution.mail.config:1.0"> - <group target="account" id="org.gnome.evolution.mail.config.accountWizard" commit="backup_restore_commit" abort="backup_restore_abort"> + <group target="settings" id="org.gnome.evolution.mail.config.accountWizard" commit="backup_restore_commit" abort="backup_restore_abort"> <item type="page" path="0.startup_page.10.backup_restore" factory="backup_restore_page"/> </group> </hook> diff --git a/plugins/imap-features/imap-headers.c b/plugins/imap-features/imap-headers.c index a496106372..f09f880b36 100644 --- a/plugins/imap-features/imap-headers.c +++ b/plugins/imap-features/imap-headers.c @@ -78,18 +78,17 @@ void imap_headers_commit (EPlugin *efp, EConfigHookItemFactoryData *data) { - EMConfigTargetAccount *target_account; + EMConfigTargetSettings *target; CamelFetchHeadersType fetch_headers; - CamelSettings *settings; - EAccount *modified_account; gboolean use_imap = g_getenv ("USE_IMAP") != NULL; + const gchar *protocol; - target_account = (EMConfigTargetAccount *) data->config->target; - modified_account = target_account->modified_account; - settings = target_account->settings; + target = (EMConfigTargetSettings *) data->config->target; + protocol = target->storage_protocol; + + if (g_strcmp0 (protocol, "imap") == 0 || + (use_imap && g_strcmp0 (protocol, "groupwise") == 0)) { - if (g_str_has_prefix (modified_account->source->url, "imap://") || - (use_imap && g_str_has_prefix (modified_account->source->url, "groupwise://"))) { GtkTreeModel *model; GtkTreeIter iter; gint n_children; @@ -123,7 +122,7 @@ imap_headers_commit (EPlugin *efp, fetch_headers = CAMEL_FETCH_HEADERS_BASIC_AND_MAILING_LIST; g_object_set ( - settings, + target->storage_settings, "fetch-headers", fetch_headers, "fetch-headers-extra", strv, NULL); @@ -249,9 +248,7 @@ GtkWidget * org_gnome_imap_headers (EPlugin *epl, EConfigHookItemFactoryData *data) { - EMConfigTargetAccount *target_account; - CamelSettings *settings; - EAccount *account; + EMConfigTargetSettings *target; GtkWidget *vbox; GtkBuilder *builder; GtkWidget *button; @@ -262,19 +259,20 @@ org_gnome_imap_headers (EPlugin *epl, CamelFetchHeadersType fetch_headers = 0; gchar **extra_headers = NULL; gboolean use_imap = g_getenv ("USE_IMAP") != NULL; + const gchar *protocol; guint ii, length = 0; ui = g_new0 (EPImapFeaturesData, 1); - target_account = (EMConfigTargetAccount *) data->config->target; - account = target_account->modified_account; - settings = target_account->settings; + target = (EMConfigTargetSettings *) data->config->target; + protocol = target->storage_protocol; - if (!g_str_has_prefix (account->source->url, "imap://") && !(use_imap && g_str_has_prefix (account->source->url, "groupwise://"))) + if (g_strcmp0 (protocol, "imap") != 0 && + !(use_imap && g_strcmp0 (protocol, "groupwise") == 0)) return NULL; g_object_get ( - settings, + target->storage_settings, "fetch-headers", &fetch_headers, "fetch-headers-extra", &extra_headers, NULL); diff --git a/plugins/imap-features/org-gnome-imap-features.eplug.xml b/plugins/imap-features/org-gnome-imap-features.eplug.xml index fdbfdc78ef..c4d27bddd0 100644 --- a/plugins/imap-features/org-gnome-imap-features.eplug.xml +++ b/plugins/imap-features/org-gnome-imap-features.eplug.xml @@ -8,7 +8,7 @@ <hook class="org.gnome.evolution.mail.config:1.0"> <group id="org.gnome.evolution.mail.config.accountEditor" - target="account" commit = "imap_headers_commit" abort="imap_headers_abort"> + target="settings" commit = "imap_headers_commit" abort="imap_headers_abort"> <item type="page" path="70.IMAP Headers" label="IMAP Headers" factory="org_gnome_imap_headers"/> </group> </hook> diff --git a/widgets/misc/e-auth-combo-box.c b/widgets/misc/e-auth-combo-box.c index 48bd15cc1e..182e171c00 100644 --- a/widgets/misc/e-auth-combo-box.c +++ b/widgets/misc/e-auth-combo-box.c @@ -79,10 +79,11 @@ auth_combo_box_rebuild_model (EAuthComboBox *combo_box) } /* Try selecting the previous mechanism. */ - gtk_combo_box_set_active_id (gtk_combo_box, active_id); + if (active_id != NULL) + gtk_combo_box_set_active_id (gtk_combo_box, active_id); /* Or else fall back to the first mechanism. */ - if (gtk_combo_box_get_active_id (gtk_combo_box) == NULL) + if (gtk_combo_box_get_active (gtk_combo_box) == -1) gtk_combo_box_set_active (gtk_combo_box, 0); } diff --git a/widgets/misc/e-port-entry.c b/widgets/misc/e-port-entry.c index dd27ffa371..cc90302771 100644 --- a/widgets/misc/e-port-entry.c +++ b/widgets/misc/e-port-entry.c @@ -11,19 +11,20 @@ * Dan Vratil <dvratil@redhat.com> */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include "e-port-entry.h" +#include <config.h> +#include <errno.h> #include <stddef.h> #include <string.h> +#define E_PORT_ENTRY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_PORT_ENTRY, EPortEntryPrivate)) + struct _EPortEntryPrivate { - guint port; - gboolean is_valid; CamelNetworkSecurityMethod method; + CamelProviderPortEntry *entries; }; enum { @@ -44,89 +45,98 @@ G_DEFINE_TYPE ( e_port_entry, GTK_TYPE_COMBO_BOX) -static void -port_entry_set_is_valid (EPortEntry *port_entry, - gboolean is_valid) +static GtkEntry * +port_entry_get_entry (EPortEntry *port_entry) { - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - port_entry->priv->is_valid = is_valid; - - g_object_notify (G_OBJECT (port_entry), "is-valid"); + return GTK_ENTRY (gtk_bin_get_child (GTK_BIN (port_entry))); } -/** - * Returns number of port currently selected in the widget, no matter - * what value is in the PORT property - */ -static gint -port_entry_get_model_active_port (EPortEntry *port_entry) +static gboolean +port_entry_get_numeric_port (EPortEntry *port_entry, + gint *out_port) { - const gchar *port; + GtkEntry *entry; + const gchar *port_string; + gboolean valid; + gint port; - port = gtk_combo_box_get_active_id (GTK_COMBO_BOX (port_entry)); + entry = port_entry_get_entry (port_entry); - if (!port) { - GtkWidget *entry = gtk_bin_get_child (GTK_BIN (port_entry)); - port = gtk_entry_get_text (GTK_ENTRY (entry)); - } + port_string = gtk_entry_get_text (entry); + g_return_val_if_fail (port_string != NULL, FALSE); + + errno = 0; + port = strtol (port_string, NULL, 10); + valid = (errno == 0) && (port == CLAMP (port, 1, G_MAXUINT16)); - return atoi (port); + if (valid && out_port != NULL) + *out_port = port; + + return valid; } static void -port_entry_port_changed (EPortEntry *port_entry) +port_entry_text_changed (GtkEditable *editable, + EPortEntry *port_entry) { - GtkTreeModel *model; - GtkTreeIter iter; - const gchar *port; - const gchar *tooltip; - - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (port_entry)); - g_return_if_fail (model); - - if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (port_entry), &iter)) { - GtkWidget *entry = gtk_bin_get_child (GTK_BIN (port_entry)); - port = gtk_entry_get_text (GTK_ENTRY (entry)); - - /* Try if user just haven't happened to enter a default port */ - gtk_combo_box_set_active_id (GTK_COMBO_BOX (port_entry), port); - } else { - gtk_tree_model_get (model, &iter, PORT_NUM_COLUMN, &port, -1); + GObject *object = G_OBJECT (port_entry); + const gchar *desc = NULL; + gint port = 0; + gint ii = 0; + + g_object_freeze_notify (object); + + port_entry_get_numeric_port (port_entry, &port); + + if (port_entry->priv->entries != NULL) { + while (port_entry->priv->entries[ii].port > 0) { + if (port == port_entry->priv->entries[ii].port) { + desc = port_entry->priv->entries[ii].desc; + break; + } + ii++; + } } - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (port_entry), &iter)) { - gtk_tree_model_get (model, &iter, PORT_DESC_COLUMN, &tooltip, -1); - gtk_widget_set_tooltip_text (GTK_WIDGET (port_entry), tooltip); - } else { + if (desc != NULL) + gtk_widget_set_tooltip_text (GTK_WIDGET (port_entry), desc); + else gtk_widget_set_has_tooltip (GTK_WIDGET (port_entry), FALSE); - } - if (port == NULL || *port == '\0') { - port_entry->priv->port = 0; - port_entry_set_is_valid (port_entry, FALSE); - } else { - port_entry->priv->port = atoi (port); - if ((port_entry->priv->port <= 0) || - (port_entry->priv->port > G_MAXUINT16)) { - port_entry->priv->port = 0; - port_entry_set_is_valid (port_entry, FALSE); - } else { - port_entry_set_is_valid (port_entry, TRUE); - } - } + g_object_notify (object, "port"); + g_object_notify (object, "is-valid"); - g_object_notify (G_OBJECT (port_entry), "port"); + g_object_thaw_notify (object); } static void port_entry_method_changed (EPortEntry *port_entry) { CamelNetworkSecurityMethod method; + gboolean standard_port = FALSE; + gboolean valid; + gint port = 0; + gint ii = 0; method = e_port_entry_get_security_method (port_entry); + valid = port_entry_get_numeric_port (port_entry, &port); + + /* Only change the port number if it's currently on a standard + * port (i.e. listed in a CamelProviderPortEntry). Otherwise, + * leave custom port numbers alone. */ + + if (valid && port_entry->priv->entries != NULL) { + while (port_entry->priv->entries[ii].port > 0) { + if (port == port_entry->priv->entries[ii].port) { + standard_port = TRUE; + break; + } + ii++; + } + } + + if (valid && !standard_port) + return; switch (method) { case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT: @@ -145,12 +155,6 @@ port_entry_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { - case PROP_IS_VALID: - port_entry_set_is_valid ( - E_PORT_ENTRY (object), - g_value_get_boolean (value)); - return; - case PROP_PORT: e_port_entry_set_port ( E_PORT_ENTRY (object), @@ -197,6 +201,21 @@ port_entry_get_property (GObject *object, } static void +port_entry_constructed (GObject *object) +{ + GtkEntry *entry; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_port_entry_parent_class)->constructed (object); + + entry = port_entry_get_entry (E_PORT_ENTRY (object)); + + g_signal_connect_after ( + entry, "changed", + G_CALLBACK (port_entry_text_changed), object); +} + +static void port_entry_get_preferred_width (GtkWidget *widget, gint *minimum_size, gint *natural_size) @@ -204,7 +223,7 @@ port_entry_get_preferred_width (GtkWidget *widget, PangoContext *context; PangoFontMetrics *metrics; PangoFontDescription *font_desc; - GtkStyleContext *style_context; + GtkStyleContext *style_context; GtkStateFlags state; gint digit_width; gint parent_entry_width_min; @@ -257,6 +276,7 @@ e_port_entry_class_init (EPortEntryClass *class) object_class = G_OBJECT_CLASS (class); object_class->set_property = port_entry_set_property; object_class->get_property = port_entry_get_property; + object_class->constructed = port_entry_constructed; widget_class = GTK_WIDGET_CLASS (class); widget_class->get_preferred_width = port_entry_get_preferred_width; @@ -304,10 +324,7 @@ e_port_entry_init (EPortEntry *port_entry) GtkCellRenderer *renderer; GtkListStore *store; - port_entry->priv = G_TYPE_INSTANCE_GET_PRIVATE ( - port_entry, E_TYPE_PORT_ENTRY, EPortEntryPrivate); - port_entry->priv->port = 0; - port_entry->priv->is_valid = FALSE; + port_entry->priv = E_PORT_ENTRY_GET_PRIVATE (port_entry); store = gtk_list_store_new ( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); @@ -335,11 +352,6 @@ e_port_entry_init (EPortEntry *port_entry) GTK_CELL_LAYOUT (port_entry), renderer, "text", PORT_DESC_COLUMN); - /* Update the port property when port is changed */ - g_signal_connect ( - port_entry, "changed", - G_CALLBACK (port_entry_port_changed), NULL); - g_signal_connect ( port_entry, "notify::security-method", G_CALLBACK (port_entry_method_changed), NULL); @@ -356,22 +368,31 @@ void e_port_entry_set_camel_entries (EPortEntry *port_entry, CamelProviderPortEntry *entries) { + GtkComboBox *combo_box; GtkTreeIter iter; GtkTreeModel *model; GtkListStore *store; + gint port = 0; gint i = 0; g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); g_return_if_fail (entries); - model = gtk_combo_box_get_model (GTK_COMBO_BOX (port_entry)); - store = GTK_LIST_STORE (model); + port_entry->priv->entries = entries; + + combo_box = GTK_COMBO_BOX (port_entry); + model = gtk_combo_box_get_model (combo_box); + store = GTK_LIST_STORE (model); gtk_list_store_clear (store); while (entries[i].port > 0) { gchar *port_string; + /* Grab the first port number. */ + if (port == 0) + port = entries[i].port; + port_string = g_strdup_printf ("%i", entries[i].port); gtk_list_store_append (store, &iter); @@ -386,49 +407,34 @@ e_port_entry_set_camel_entries (EPortEntry *port_entry, g_free (port_string); } - /* Activate the first port */ - if (i > 0) - e_port_entry_set_port (port_entry, entries[0].port); + e_port_entry_set_port (port_entry, port); } gint e_port_entry_get_port (EPortEntry *port_entry) { + gint port = 0; + g_return_val_if_fail (E_IS_PORT_ENTRY (port_entry), 0); - return port_entry->priv->port; + port_entry_get_numeric_port (port_entry, &port); + + return port; } void e_port_entry_set_port (EPortEntry *port_entry, gint port) { - g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - - port_entry->priv->port = port; - if ((port <= 0) || (port > G_MAXUINT16)) - port_entry_set_is_valid (port_entry, FALSE); - else { - gchar *port_string; - - port_string = g_strdup_printf ("%i", port); - - gtk_combo_box_set_active_id ( - GTK_COMBO_BOX (port_entry), port_string); + GtkEntry *entry; + gchar *port_string; - if (port_entry_get_model_active_port (port_entry) != port) { - GtkWidget *entry; - - entry = gtk_bin_get_child (GTK_BIN (port_entry)); - gtk_entry_set_text (GTK_ENTRY (entry), port_string); - } - - port_entry_set_is_valid (port_entry, TRUE); - - g_free (port_string); - } + g_return_if_fail (E_IS_PORT_ENTRY (port_entry)); - g_object_notify (G_OBJECT (port_entry), "port"); + entry = port_entry_get_entry (port_entry); + port_string = g_strdup_printf ("%i", port); + gtk_entry_set_text (entry, port_string); + g_free (port_string); } gboolean @@ -436,7 +442,7 @@ e_port_entry_is_valid (EPortEntry *port_entry) { g_return_val_if_fail (E_IS_PORT_ENTRY (port_entry), FALSE); - return port_entry->priv->is_valid; + return port_entry_get_numeric_port (port_entry, NULL); } CamelNetworkSecurityMethod |