aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-proxy-link-selector.c
diff options
context:
space:
mode:
Diffstat (limited to 'e-util/e-proxy-link-selector.c')
-rw-r--r--e-util/e-proxy-link-selector.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/e-util/e-proxy-link-selector.c b/e-util/e-proxy-link-selector.c
new file mode 100644
index 0000000000..bb72142817
--- /dev/null
+++ b/e-util/e-proxy-link-selector.c
@@ -0,0 +1,290 @@
+/*
+ * e-proxy-link-selector.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-proxy-link-selector.h"
+
+#define E_PROXY_LINK_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_PROXY_LINK_SELECTOR, EProxyLinkSelectorPrivate))
+
+struct _EProxyLinkSelectorPrivate {
+ ESource *target_source;
+ ESource *fallback_source;
+};
+
+enum {
+ PROP_0,
+ PROP_TARGET_SOURCE
+};
+
+G_DEFINE_TYPE (
+ EProxyLinkSelector,
+ e_proxy_link_selector,
+ E_TYPE_SOURCE_SELECTOR)
+
+static gboolean
+proxy_link_selector_target_source_to_show_toggles (GBinding *binding,
+ const GValue *source_value,
+ GValue *target_value,
+ gpointer user_data)
+{
+ ESource *target_source;
+ ESource *fallback_source;
+ gboolean show_toggles;
+
+ fallback_source = E_SOURCE (user_data);
+ target_source = g_value_get_object (source_value);
+ show_toggles = !e_source_equal (target_source, fallback_source);
+ g_value_set_boolean (target_value, show_toggles);
+
+ return TRUE;
+}
+
+static void
+proxy_link_selector_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TARGET_SOURCE:
+ e_proxy_link_selector_set_target_source (
+ E_PROXY_LINK_SELECTOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+proxy_link_selector_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_TARGET_SOURCE:
+ g_value_take_object (
+ value,
+ e_proxy_link_selector_ref_target_source (
+ E_PROXY_LINK_SELECTOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+proxy_link_selector_dispose (GObject *object)
+{
+ EProxyLinkSelectorPrivate *priv;
+
+ priv = E_PROXY_LINK_SELECTOR_GET_PRIVATE (object);
+
+ g_clear_object (&priv->target_source);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_proxy_link_selector_parent_class)->dispose (object);
+}
+
+static void
+proxy_link_selector_constructed (GObject *object)
+{
+ EProxyLinkSelectorPrivate *priv;
+ ESourceSelector *selector;
+ ESourceRegistry *registry;
+ ESource *builtin_proxy;
+
+ priv = E_PROXY_LINK_SELECTOR_GET_PRIVATE (object);
+
+ selector = E_SOURCE_SELECTOR (object);
+ registry = e_source_selector_get_registry (selector);
+
+ /* Set the target and fallback sources before chaining up. */
+
+ builtin_proxy = e_source_registry_ref_builtin_proxy (registry);
+ g_return_if_fail (builtin_proxy != NULL);
+
+ priv->target_source = g_object_ref (builtin_proxy);
+ priv->fallback_source = g_object_ref (builtin_proxy);
+
+ g_object_unref (builtin_proxy);
+
+ /* Hide toggle buttons when the target source is the same as
+ * the fallback source since toggling the buttons would have
+ * no effect in that particular case. */
+ g_object_bind_property_full (
+ selector, "target-source",
+ selector, "show-toggles",
+ G_BINDING_SYNC_CREATE,
+ proxy_link_selector_target_source_to_show_toggles,
+ NULL,
+ g_object_ref (priv->fallback_source),
+ (GDestroyNotify) g_object_unref);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_proxy_link_selector_parent_class)->
+ constructed (object);
+
+ /* This triggers a model rebuild, so chain up first. */
+ e_source_selector_set_show_icons (selector, TRUE);
+}
+
+static gboolean
+proxy_link_selector_get_source_selected (ESourceSelector *selector,
+ ESource *source)
+{
+ EProxyLinkSelector *link_selector;
+ ESourceAuthentication *extension;
+ const gchar *extension_name;
+ const gchar *target_uid;
+ gboolean selected = FALSE;
+ gchar *uid;
+
+ link_selector = E_PROXY_LINK_SELECTOR (selector);
+
+ /* Make sure this source has an Authentication extension. */
+ extension_name = e_source_selector_get_extension_name (selector);
+ if (!e_source_has_extension (source, extension_name))
+ return FALSE;
+
+ extension = e_source_get_extension (source, extension_name);
+ g_return_val_if_fail (E_IS_SOURCE_AUTHENTICATION (extension), FALSE);
+
+ uid = e_source_authentication_dup_proxy_uid (extension);
+ target_uid = e_source_get_uid (link_selector->priv->target_source);
+ selected = (g_strcmp0 (uid, target_uid) == 0);
+ g_free (uid);
+
+ return selected;
+}
+
+static void
+proxy_link_selector_set_source_selected (ESourceSelector *selector,
+ ESource *source,
+ gboolean selected)
+{
+ EProxyLinkSelector *link_selector;
+ ESourceAuthentication *extension;
+ ESource *target_source;
+ const gchar *extension_name;
+ const gchar *new_target_uid;
+ const gchar *old_target_uid;
+
+ link_selector = E_PROXY_LINK_SELECTOR (selector);
+
+ /* Make sure this source has an Authentication extension. */
+ extension_name = e_source_selector_get_extension_name (selector);
+ if (!e_source_has_extension (source, extension_name))
+ return;
+
+ extension = e_source_get_extension (source, extension_name);
+ g_return_if_fail (E_IS_SOURCE_AUTHENTICATION (extension));
+
+ if (selected)
+ target_source = link_selector->priv->target_source;
+ else
+ target_source = link_selector->priv->fallback_source;
+
+ new_target_uid = e_source_get_uid (target_source);
+ old_target_uid = e_source_authentication_get_proxy_uid (extension);
+
+ if (g_strcmp0 (new_target_uid, old_target_uid) != 0) {
+ e_source_authentication_set_proxy_uid (
+ extension, new_target_uid);
+ e_source_selector_queue_write (selector, source);
+ }
+}
+
+static void
+e_proxy_link_selector_class_init (EProxyLinkSelectorClass *class)
+{
+ GObjectClass *object_class;
+ ESourceSelectorClass *source_selector_class;
+
+ g_type_class_add_private (class, sizeof (EProxyLinkSelectorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = proxy_link_selector_set_property;
+ object_class->get_property = proxy_link_selector_get_property;
+ object_class->dispose = proxy_link_selector_dispose;
+ object_class->constructed = proxy_link_selector_constructed;
+
+ source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ source_selector_class->get_source_selected =
+ proxy_link_selector_get_source_selected;
+ source_selector_class->set_source_selected =
+ proxy_link_selector_set_source_selected;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TARGET_SOURCE,
+ g_param_spec_object (
+ "target-source",
+ "Target Source",
+ "The data source to link to "
+ "when the checkbox is active",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+e_proxy_link_selector_init (EProxyLinkSelector *selector)
+{
+ selector->priv = E_PROXY_LINK_SELECTOR_GET_PRIVATE (selector);
+}
+
+GtkWidget *
+e_proxy_link_selector_new (ESourceRegistry *registry)
+{
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ return g_object_new (
+ E_TYPE_PROXY_LINK_SELECTOR,
+ "extension-name", E_SOURCE_EXTENSION_AUTHENTICATION,
+ "registry", registry, NULL);
+}
+
+ESource *
+e_proxy_link_selector_ref_target_source (EProxyLinkSelector *selector)
+{
+ g_return_val_if_fail (E_IS_PROXY_LINK_SELECTOR (selector), NULL);
+
+ return g_object_ref (selector->priv->target_source);
+}
+
+void
+e_proxy_link_selector_set_target_source (EProxyLinkSelector *selector,
+ ESource *target_source)
+{
+ g_return_if_fail (E_IS_PROXY_LINK_SELECTOR (selector));
+ g_return_if_fail (E_IS_SOURCE (target_source));
+
+ if (target_source == selector->priv->target_source)
+ return;
+
+ g_clear_object (&selector->priv->target_source);
+ selector->priv->target_source = g_object_ref (target_source);
+
+ g_object_notify (G_OBJECT (selector), "target-source");
+
+ e_source_selector_update_all_rows (E_SOURCE_SELECTOR (selector));
+}
+