diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2013-10-15 23:12:05 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2013-10-26 00:51:12 +0800 |
commit | ad6059bc0d63ab8503fe631dd3583c6ef8816b54 (patch) | |
tree | dc7adc791c45bd8e916601524f0c46581623eeba | |
parent | 559d4cf8bf8f309b33ae3ff426ebb4f2c6015c79 (diff) | |
download | gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.tar gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.tar.gz gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.tar.bz2 gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.tar.lz gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.tar.xz gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.tar.zst gsoc2013-evolution-ad6059bc0d63ab8503fe631dd3583c6ef8816b54.zip |
Add EProxyPreferences.
-rw-r--r-- | doc/reference/evolution-util/evolution-util-docs.sgml | 1 | ||||
-rw-r--r-- | doc/reference/evolution-util/evolution-util-sections.txt | 22 | ||||
-rw-r--r-- | doc/reference/evolution-util/evolution-util.types | 1 | ||||
-rw-r--r-- | e-util/Makefile.am | 7 | ||||
-rw-r--r-- | e-util/e-proxy-preferences.c | 694 | ||||
-rw-r--r-- | e-util/e-proxy-preferences.h | 84 | ||||
-rw-r--r-- | e-util/e-util.h | 1 | ||||
-rw-r--r-- | e-util/test-proxy-preferences.c | 86 | ||||
-rw-r--r-- | po/POTFILES.in | 1 |
9 files changed, 897 insertions, 0 deletions
diff --git a/doc/reference/evolution-util/evolution-util-docs.sgml b/doc/reference/evolution-util/evolution-util-docs.sgml index 9075c3a65e..f91ea627bf 100644 --- a/doc/reference/evolution-util/evolution-util-docs.sgml +++ b/doc/reference/evolution-util/evolution-util-docs.sgml @@ -250,6 +250,7 @@ <xi:include href="xml/e-proxy-combo-box.xml"/> <xi:include href="xml/e-proxy-editor.xml"/> <xi:include href="xml/e-proxy-link-selector.xml"/> + <xi:include href="xml/e-proxy-preferences.xml"/> <xi:include href="xml/e-proxy-selector.xml"/> <xi:include href="xml/e-search-bar.xml"/> <xi:include href="xml/e-selectable.xml"/> diff --git a/doc/reference/evolution-util/evolution-util-sections.txt b/doc/reference/evolution-util/evolution-util-sections.txt index 30e92b6edf..d777c098e1 100644 --- a/doc/reference/evolution-util/evolution-util-sections.txt +++ b/doc/reference/evolution-util/evolution-util-sections.txt @@ -2815,6 +2815,28 @@ EProxyLinkSelectorPrivate </SECTION> <SECTION> +<FILE>e-proxy-preferences</FILE> +<TITLE>EProxyPreferences</TITLE> +EProxyPreferences +e_proxy_preferences_new +e_proxy_preferences_submit +e_proxy_preferences_get_registry +e_proxy_preferences_get_show_advanced +e_proxy_preferences_set_show_advanced +<SUBSECTION Standard> +E_PROXY_PREFERENCES +E_IS_PROXY_PREFERENCES +E_TYPE_PROXY_PREFERENCES +E_PROXY_PREFERENCES_CLASS +E_IS_PROXY_PREFERENCES_CLASS +E_PROXY_PREFERENCES_GET_CLASS +EProxyPreferencesClass +e_proxy_preferences_get_type +<SUBSECTION Private> +EProxyPreferencesPrivate +</SECTION> + +<SECTION> <FILE>e-proxy-selector</FILE> <TITLE>EProxySelector</TITLE> EProxySelector diff --git a/doc/reference/evolution-util/evolution-util.types b/doc/reference/evolution-util/evolution-util.types index 778e3b86f4..c47d820386 100644 --- a/doc/reference/evolution-util/evolution-util.types +++ b/doc/reference/evolution-util/evolution-util.types @@ -104,6 +104,7 @@ e_printable_get_type e_proxy_combo_box_get_type e_proxy_editor_get_type e_proxy_link_selector_get_type +e_proxy_preferences_get_type e_proxy_selector_get_type e_reflow_get_type e_reflow_model_get_type diff --git a/e-util/Makefile.am b/e-util/Makefile.am index d3c58002e7..54ef384000 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -63,6 +63,7 @@ noinst_PROGRAMS = \ test-mail-signatures \ test-name-selector \ test-preferences-window \ + test-proxy-preferences \ test-source-combo-box \ test-source-config \ test-source-selector \ @@ -227,6 +228,7 @@ evolution_util_include_HEADERS = \ e-proxy-combo-box.h \ e-proxy-editor.h \ e-proxy-link-selector.h \ + e-proxy-preferences.h \ e-proxy-selector.h \ e-reflow-model.h \ e-reflow.h \ @@ -469,6 +471,7 @@ libevolution_util_la_SOURCES = \ e-proxy-combo-box.c \ e-proxy-editor.c \ e-proxy-link-selector.c \ + e-proxy-preferences.c \ e-proxy-selector.c \ e-reflow-model.c \ e-reflow.c \ @@ -627,6 +630,10 @@ test_preferences_window_CPPFLAGS = $(TEST_CPPFLAGS) test_preferences_window_SOURCES = test-preferences-window.c test_preferences_window_LDADD = $(TEST_LDADD) +test_proxy_preferences_CPPFLAGS = $(TEST_CPPFLAGS) +test_proxy_preferences_SOURCES = test-proxy-preferences.c +test_proxy_preferences_LDADD = $(TEST_LDADD) + test_source_combo_box_CPPFLAGS = $(TEST_CPPFLAGS) test_source_combo_box_SOURCES = test-source-combo-box.c test_source_combo_box_LDADD = $(TEST_LDADD) diff --git a/e-util/e-proxy-preferences.c b/e-util/e-proxy-preferences.c new file mode 100644 index 0000000000..57c3d328b8 --- /dev/null +++ b/e-util/e-proxy-preferences.c @@ -0,0 +1,694 @@ +/* + * e-proxy-preferences.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +/** + * SECTION: e-proxy-preferences + * @include: e-util/e-util.h + * @short_description: Manage network proxy preferences + * + * #EProxyPreferences is the main widget for displaying network proxy + * preferences. A link button toggles between a basic mode (for most + * users) and advanced mode. Basic mode only shows proxy details for + * the built-in proxy profile, which all new accounts use by default. + * Advanced mode reveals a sidebar of proxy profiles, allowing users + * to create or delete custom profiles and apply them to particular + * accounts. + **/ + +#include "e-proxy-preferences.h" + +#include <config.h> +#include <glib/gi18n-lib.h> + +#include <e-util/e-proxy-editor.h> +#include <e-util/e-proxy-link-selector.h> +#include <e-util/e-proxy-selector.h> + +#define E_PROXY_PREFERENCES_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_PROXY_PREFERENCES, EProxyPreferencesPrivate)) + +/* Rate-limit committing proxy changes to the registry. */ +#define COMMIT_DELAY_SECS 2 + +struct _EProxyPreferencesPrivate { + ESourceRegistry *registry; + gulong source_changed_handler_id; + + /* The widgets are not referenced. */ + GtkWidget *proxy_selector; + GtkWidget *proxy_editor; + + GMutex commit_lock; + guint commit_timeout_id; + GHashTable *commit_sources; + + gboolean show_advanced; +}; + +enum { + PROP_0, + PROP_REGISTRY, + PROP_SHOW_ADVANCED +}; + +/* Forward Declarations */ +static void proxy_preferences_commit_changes + (EProxyPreferences *preferences); + +G_DEFINE_TYPE ( + EProxyPreferences, + e_proxy_preferences, + GTK_TYPE_BOX) + +static gboolean +proxy_preferences_commit_timeout_cb (gpointer user_data) +{ + EProxyPreferences *preferences = user_data; + + proxy_preferences_commit_changes (preferences); + + return FALSE; +} + +static void +proxy_preferences_commit_stash (EProxyPreferences *preferences, + ESource *source, + gboolean start_timeout) +{ + g_mutex_lock (&preferences->priv->commit_lock); + + g_hash_table_replace ( + preferences->priv->commit_sources, + e_source_dup_uid (source), + e_weak_ref_new (source)); + + if (preferences->priv->commit_timeout_id > 0) { + g_source_remove (preferences->priv->commit_timeout_id); + preferences->priv->commit_timeout_id = 0; + } + + if (start_timeout) { + preferences->priv->commit_timeout_id = + g_timeout_add_seconds ( + COMMIT_DELAY_SECS, + proxy_preferences_commit_timeout_cb, + preferences); + } + + g_mutex_unlock (&preferences->priv->commit_lock); +} + +static GList * +proxy_preferences_commit_claim (EProxyPreferences *preferences) +{ + GQueue queue = G_QUEUE_INIT; + GList *list, *link; + + g_mutex_lock (&preferences->priv->commit_lock); + + if (preferences->priv->commit_timeout_id > 0) { + g_source_remove (preferences->priv->commit_timeout_id); + preferences->priv->commit_timeout_id = 0; + } + + /* Returns a list of GWeakRefs which may hold an ESource. */ + list = g_hash_table_get_values (preferences->priv->commit_sources); + + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source; + + source = g_weak_ref_get ((GWeakRef *) link->data); + if (source != NULL) + g_queue_push_tail (&queue, source); + } + + g_list_free (list); + + g_hash_table_remove_all (preferences->priv->commit_sources); + + g_mutex_unlock (&preferences->priv->commit_lock); + + return g_queue_peek_head_link (&queue); +} + +static gboolean +proxy_preferences_activate_link_cb (GtkLinkButton *button, + EProxyPreferences *preferences) +{ + EProxySelector *selector; + + selector = E_PROXY_SELECTOR (preferences->priv->proxy_selector); + + if (e_proxy_preferences_get_show_advanced (preferences)) { + /* Basic mode always shows the built-in proxy profile. */ + e_proxy_preferences_set_show_advanced (preferences, FALSE); + e_proxy_selector_set_selected (selector, NULL); + } else { + e_proxy_preferences_set_show_advanced (preferences, TRUE); + } + + return TRUE; +} + +static gboolean +proxy_preferences_switch_to_label (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + const gchar *string; + + if (g_value_get_boolean (source_value)) + string = _("Switch to Basic Proxy Preferences"); + else + string = _("Switch to Advanced Proxy Preferences"); + + g_value_set_string (target_value, string); + + return TRUE; +} + +static gboolean +proxy_preferences_source_to_display_name (GBinding *binding, + const GValue *source_value, + GValue *target_value, + gpointer user_data) +{ + ESource *source; + gchar *display_name; + + source = g_value_get_object (source_value); + g_return_val_if_fail (source != NULL, FALSE); + + display_name = e_source_dup_display_name (source); + g_value_take_string (target_value, display_name); + + return TRUE; +} + +static void +proxy_preferences_write_done_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + ESource *source; + EProxyPreferences *preferences; + GError *error = NULL; + + source = E_SOURCE (source_object); + preferences = E_PROXY_PREFERENCES (user_data); + + e_source_write_finish (source, result, &error); + + /* FIXME Display the error in an alert sink. */ + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + } + + g_object_unref (preferences); +} + +static void +proxy_preferences_commit_changes (EProxyPreferences *preferences) +{ + GList *list, *link; + + list = proxy_preferences_commit_claim (preferences); + + for (link = list; link != NULL; link = g_list_next (link)) { + e_source_write ( + E_SOURCE (link->data), NULL, + proxy_preferences_write_done_cb, + g_object_ref (preferences)); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); +} + +static void +proxy_preferences_source_changed_cb (ESourceRegistry *registry, + ESource *source, + EProxyPreferences *preferences) +{ + if (e_source_has_extension (source, E_SOURCE_EXTENSION_PROXY)) + proxy_preferences_commit_stash (preferences, source, TRUE); +} + +static void +proxy_preferences_set_registry (EProxyPreferences *preferences, + ESourceRegistry *registry) +{ + gulong handler_id; + + g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); + g_return_if_fail (preferences->priv->registry == NULL); + + preferences->priv->registry = g_object_ref (registry); + + handler_id = g_signal_connect ( + registry, "source-changed", + G_CALLBACK (proxy_preferences_source_changed_cb), preferences); + preferences->priv->source_changed_handler_id = handler_id; +} + +static void +proxy_preferences_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_REGISTRY: + proxy_preferences_set_registry ( + E_PROXY_PREFERENCES (object), + g_value_get_object (value)); + return; + + case PROP_SHOW_ADVANCED: + e_proxy_preferences_set_show_advanced ( + E_PROXY_PREFERENCES (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +proxy_preferences_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_REGISTRY: + g_value_set_object ( + value, + e_proxy_preferences_get_registry ( + E_PROXY_PREFERENCES (object))); + return; + + case PROP_SHOW_ADVANCED: + g_value_set_boolean ( + value, + e_proxy_preferences_get_show_advanced ( + E_PROXY_PREFERENCES (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +proxy_preferences_dispose (GObject *object) +{ + EProxyPreferencesPrivate *priv; + + priv = E_PROXY_PREFERENCES_GET_PRIVATE (object); + + if (priv->source_changed_handler_id > 0) { + g_signal_handler_disconnect ( + priv->registry, + priv->source_changed_handler_id); + priv->source_changed_handler_id = 0; + } + + if (priv->commit_timeout_id > 0) { + g_source_remove (priv->commit_timeout_id); + priv->commit_timeout_id = 0; + } + + g_clear_object (&priv->registry); + + g_hash_table_remove_all (priv->commit_sources); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_proxy_preferences_parent_class)->dispose (object); +} + +static void +proxy_preferences_finalize (GObject *object) +{ + EProxyPreferencesPrivate *priv; + + priv = E_PROXY_PREFERENCES_GET_PRIVATE (object); + + g_mutex_clear (&priv->commit_lock); + g_hash_table_destroy (priv->commit_sources); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_proxy_preferences_parent_class)->finalize (object); +} + +static void +proxy_preferences_constructed (GObject *object) +{ + EProxyPreferences *preferences; + ESourceRegistry *registry; + GtkWidget *widget; + GtkWidget *container; + GtkWidget *container2; + PangoAttribute *attr; + PangoAttrList *attr_list; + GList *list; + const gchar *extension_name; + gboolean show_advanced; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_proxy_preferences_parent_class)-> + constructed (object); + + preferences = E_PROXY_PREFERENCES (object); + registry = e_proxy_preferences_get_registry (preferences); + + gtk_orientable_set_orientation ( + GTK_ORIENTABLE (preferences), GTK_ORIENTATION_VERTICAL); + gtk_box_set_spacing (GTK_BOX (preferences), 12); + + widget = gtk_grid_new (); + gtk_grid_set_row_spacing (GTK_GRID (widget), 12); + gtk_grid_set_column_spacing (GTK_GRID (widget), 12); + gtk_box_pack_start (GTK_BOX (preferences), widget, TRUE, TRUE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = e_proxy_selector_new (registry); + gtk_widget_set_vexpand (widget, TRUE); + gtk_widget_set_size_request (widget, 200, -1); + gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 1, 3); + preferences->priv->proxy_selector = widget; /* do not reference */ + + g_object_bind_property ( + preferences, "show-advanced", + widget, "visible", + G_BINDING_SYNC_CREATE); + + attr_list = pango_attr_list_new (); + attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); + pango_attr_list_insert (attr_list, attr); + + widget = gtk_label_new (""); + gtk_widget_set_hexpand (widget, TRUE); + gtk_widget_set_valign (widget, GTK_ALIGN_START); + gtk_label_set_attributes (GTK_LABEL (widget), attr_list); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_grid_attach (GTK_GRID (container), widget, 1, 0, 1, 1); + gtk_widget_show (widget); + + g_object_bind_property_full ( + preferences->priv->proxy_selector, "selected", + widget, "label", + G_BINDING_SYNC_CREATE, + proxy_preferences_source_to_display_name, + NULL, NULL, NULL); + + pango_attr_list_unref (attr_list); + + widget = e_proxy_editor_new (registry); + gtk_widget_set_margin_left (widget, 12); + gtk_widget_set_valign (widget, GTK_ALIGN_START); + gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1); + preferences->priv->proxy_editor = widget; /* do not reference */ + gtk_widget_show (widget); + + g_object_bind_property ( + preferences->priv->proxy_selector, "selected", + widget, "source", + G_BINDING_SYNC_CREATE); + + widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_widget_set_margin_left (widget, 12); + gtk_widget_set_vexpand (widget, TRUE); + gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1); + gtk_widget_show (widget); + + container = widget; + + /* Nested containers to control multiple levels of visibility. */ + + widget = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_widget_set_vexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (container), widget); + + g_object_bind_property ( + preferences, "show-advanced", + widget, "visible", + G_BINDING_SYNC_CREATE); + + container = widget; + + widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_container_add (GTK_CONTAINER (container), widget); + + container = widget; + + widget = gtk_label_new ( + _("Apply custom proxy settings to these accounts:")); + gtk_widget_set_halign (widget, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + gtk_widget_show (widget); + + container2 = widget; + + widget = e_proxy_link_selector_new (registry); + gtk_container_add (GTK_CONTAINER (container2), widget); + gtk_widget_show (widget); + + g_object_bind_property ( + preferences->priv->proxy_selector, "selected", + widget, "target-source", + G_BINDING_SYNC_CREATE); + + /* This is bound to the GtkBox created above. */ + g_object_bind_property ( + widget, "show-toggles", + container, "visible", + G_BINDING_SYNC_CREATE); + + widget = gtk_link_button_new (""); + gtk_widget_set_halign (widget, GTK_ALIGN_START); + gtk_widget_set_tooltip_markup ( + widget, _( + "<b>Advanced Proxy Preferences</b> lets you " + "define alternate network proxies and apply " + "them to specific accounts")); + gtk_box_pack_start (GTK_BOX (preferences), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_object_bind_property_full ( + preferences, "show-advanced", + widget, "label", + G_BINDING_SYNC_CREATE, + proxy_preferences_switch_to_label, + NULL, NULL, NULL); + + g_object_bind_property ( + preferences, "show-advanced", + widget, "has-tooltip", + G_BINDING_SYNC_CREATE | + G_BINDING_INVERT_BOOLEAN); + + g_signal_connect ( + widget, "activate-link", + G_CALLBACK (proxy_preferences_activate_link_cb), + preferences); + + extension_name = E_SOURCE_EXTENSION_PROXY; + list = e_source_registry_list_sources (registry, extension_name); + show_advanced = (g_list_length (list) > 1); + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + /* Switch to advanced mode if there are multiple proxy profiles. */ + e_proxy_preferences_set_show_advanced (preferences, show_advanced); +} + +static void +e_proxy_preferences_class_init (EProxyPreferencesClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (EProxyPreferencesPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = proxy_preferences_set_property; + object_class->get_property = proxy_preferences_get_property; + object_class->dispose = proxy_preferences_dispose; + object_class->finalize = proxy_preferences_finalize; + object_class->constructed = proxy_preferences_constructed; + + g_object_class_install_property ( + object_class, + PROP_REGISTRY, + g_param_spec_object ( + "registry", + "Registry", + "Data source registry", + E_TYPE_SOURCE_REGISTRY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_SHOW_ADVANCED, + g_param_spec_boolean ( + "show-advanced", + "Show Advanced", + "Show advanced proxy preferences", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_proxy_preferences_init (EProxyPreferences *preferences) +{ + GHashTable *commit_sources; + + /* Keys are UIDs, values are allocated GWeakRefs. */ + commit_sources = g_hash_table_new_full ( + (GHashFunc) g_str_hash, + (GEqualFunc) g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) e_weak_ref_free); + + preferences->priv = E_PROXY_PREFERENCES_GET_PRIVATE (preferences); + + g_mutex_init (&preferences->priv->commit_lock); + preferences->priv->commit_sources = commit_sources; +} + +/** + * e_proxy_preferences_new: + * @registry: an #ESourceRegistry + * + * Creates a new #EProxyPreferences widget using #ESource instances in + * @registry. + * + * Returns: a new #EProxyPreferences + **/ +GtkWidget * +e_proxy_preferences_new (ESourceRegistry *registry) +{ + g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); + + return g_object_new ( + E_TYPE_PROXY_PREFERENCES, + "registry", registry, NULL); +} + +/** + * e_proxy_preferences_submit: + * @preferences: an #EProxyPreferences + * + * Writes the displayed proxy profile details to the #ESource being edited, + * and submits the changes to the registry service asynchronously. + * + * Normally changes are submitted to the registry service automatically + * after a brief delay, but changes may sometimes need to be submitted + * explicitly such as when the top-level window is closing. + **/ +void +e_proxy_preferences_submit (EProxyPreferences *preferences) +{ + EProxyEditor *proxy_editor; + ESource *source; + + g_return_if_fail (E_IS_PROXY_PREFERENCES (preferences)); + + proxy_editor = E_PROXY_EDITOR (preferences->priv->proxy_editor); + + /* Save user changes to the proxy source. */ + e_proxy_editor_save (proxy_editor); + + /* This part normally happens from a "source-changed" + * signal handler, but we can't wait for that here. */ + source = e_proxy_editor_ref_source (proxy_editor); + proxy_preferences_commit_stash (preferences, source, FALSE); + g_object_unref (source); + + /* Commit any pending changes immediately. */ + proxy_preferences_commit_changes (preferences); +} + +/** + * e_proxy_preferences_get_registry: + * @preferences: an #EProxyPreferences + * + * Returns the #ESourceRegistry passed to e_proxy_preferences_new(). + * + * Returns: an #ESourceRegistry + **/ +ESourceRegistry * +e_proxy_preferences_get_registry (EProxyPreferences *preferences) +{ + g_return_val_if_fail (E_IS_PROXY_PREFERENCES (preferences), NULL); + + return preferences->priv->registry; +} + +/** + * e_proxy_preferences_get_show_advanced: + * @preferences: an #EProxyPreferences + * + * Returns whether @preferences is currently in advanced mode. + * + * Returns: whether advanced proxy preferences are visible + **/ +gboolean +e_proxy_preferences_get_show_advanced (EProxyPreferences *preferences) +{ + g_return_val_if_fail (E_IS_PROXY_PREFERENCES (preferences), FALSE); + + return preferences->priv->show_advanced; +} + +/** + * e_proxy_preferences_set_show_advanced: + * @preferences: an #EProxyPreferences + * @show_advanced: whether to show advanced proxy preferences + * + * Switches @preferences to advanced mode if @show_advanced is %TRUE, + * or to basic mode if @show_advanced is %FALSE. + **/ +void +e_proxy_preferences_set_show_advanced (EProxyPreferences *preferences, + gboolean show_advanced) +{ + g_return_if_fail (E_IS_PROXY_PREFERENCES (preferences)); + + if (show_advanced == preferences->priv->show_advanced) + return; + + preferences->priv->show_advanced = show_advanced; + + g_object_notify (G_OBJECT (preferences), "show-advanced"); +} + diff --git a/e-util/e-proxy-preferences.h b/e-util/e-proxy-preferences.h new file mode 100644 index 0000000000..859c16bb94 --- /dev/null +++ b/e-util/e-proxy-preferences.h @@ -0,0 +1,84 @@ +/* + * e-proxy-preferences.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#if !defined (__E_UTIL_H_INSIDE__) && !defined (LIBEUTIL_COMPILATION) +#error "Only <e-util/e-util.h> should be included directly." +#endif + +#ifndef E_PROXY_PREFERENCES_H +#define E_PROXY_PREFERENCES_H + +#include <gtk/gtk.h> +#include <libedataserver/libedataserver.h> + +/* Standard GObject macros */ +#define E_TYPE_PROXY_PREFERENCES \ + (e_proxy_preferences_get_type ()) +#define E_PROXY_PREFERENCES(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_PROXY_PREFERENCES, EProxyPreferences)) +#define E_PROXY_PREFERENCES_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_PROXY_PREFERENCES, EProxyPreferencesClass)) +#define E_IS_PROXY_PREFERENCES(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_PROXY_PREFERENCES)) +#define E_IS_PROXY_PREFERENCES_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_PROXY_PREFERENCES)) +#define E_PROXY_PREFERENCES_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_PROXY_PREFERENCES, EProxyPreferencesClass)) + +G_BEGIN_DECLS + +typedef struct _EProxyPreferences EProxyPreferences; +typedef struct _EProxyPreferencesClass EProxyPreferencesClass; +typedef struct _EProxyPreferencesPrivate EProxyPreferencesPrivate; + +/** + * EProxyPreferences: + * + * Contains only private data that should be read and manipulated using the + * functions below. + **/ +struct _EProxyPreferences { + GtkBox parent; + EProxyPreferencesPrivate *priv; +}; + +struct _EProxyPreferencesClass { + GtkBoxClass parent_class; +}; + +GType e_proxy_preferences_get_type (void) G_GNUC_CONST; +GtkWidget * e_proxy_preferences_new (ESourceRegistry *registry); +void e_proxy_preferences_submit (EProxyPreferences *preferences); +ESourceRegistry * + e_proxy_preferences_get_registry + (EProxyPreferences *preferences); +gboolean e_proxy_preferences_get_show_advanced + (EProxyPreferences *preferences); +void e_proxy_preferences_set_show_advanced + (EProxyPreferences *preferences, + gboolean show_advanced); + +G_END_DECLS + +#endif /* E_PROXY_PREFERENCES_H */ + diff --git a/e-util/e-util.h b/e-util/e-util.h index 494e4105a5..f2022ff879 100644 --- a/e-util/e-util.h +++ b/e-util/e-util.h @@ -146,6 +146,7 @@ #include <e-util/e-proxy-combo-box.h> #include <e-util/e-proxy-editor.h> #include <e-util/e-proxy-link-selector.h> +#include <e-util/e-proxy-preferences.h> #include <e-util/e-proxy-selector.h> #include <e-util/e-reflow-model.h> #include <e-util/e-reflow.h> diff --git a/e-util/test-proxy-preferences.c b/e-util/test-proxy-preferences.c new file mode 100644 index 0000000000..bd86cda184 --- /dev/null +++ b/e-util/test-proxy-preferences.c @@ -0,0 +1,86 @@ +/* + * test-proxy-preferences.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#include <e-util/e-util.h> + +static EProxyPreferences *preferences; + +static gboolean +quit_delay_cb (gpointer user_data) +{ + gtk_main_quit (); + + return FALSE; +} + +static gint +delete_event_cb (GtkWidget *widget, + GdkEventAny *event, + gpointer data) +{ + e_proxy_preferences_submit (preferences); + + /* Cycle the main loop for a bit longer to + * give the commit operation time to finish. */ + g_timeout_add_seconds (1, quit_delay_cb, NULL); + + return FALSE; +} + +gint +main (gint argc, + gchar **argv) +{ + ESourceRegistry *registry; + GtkWidget *window; + GtkWidget *widget; + GError *local_error = NULL; + + gtk_init (&argc, &argv); + + registry = e_source_registry_new_sync (NULL, &local_error); + + if (local_error != NULL) { + g_error ( + "Failed to load ESource registry: %s", + local_error->message); + g_assert_not_reached (); + } + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width (GTK_CONTAINER (window), 12); + gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); + gtk_window_set_title (GTK_WINDOW (window), "Proxy Preferences"); + gtk_widget_show (window); + + g_signal_connect ( + window, "delete-event", + G_CALLBACK (delete_event_cb), NULL); + + widget = e_proxy_preferences_new (registry); + gtk_container_add (GTK_CONTAINER (window), widget); + preferences = E_PROXY_PREFERENCES (widget); + gtk_widget_show (widget); + + g_object_unref (registry); + + gtk_main (); + + return 0; +} + diff --git a/po/POTFILES.in b/po/POTFILES.in index 92f975bdcb..d4d4de79a2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -244,6 +244,7 @@ e-util/e-popup-action.c e-util/e-preferences-window.c e-util/e-print.c e-util/e-proxy-editor.c +e-util/e-proxy-preferences.c e-util/e-proxy-selector.c e-util/e-rule-context.c e-util/e-rule-editor.c |