aboutsummaryrefslogblamecommitdiffstats
path: root/e-util/e-proxy-link-selector.c
blob: 360604b14125e5624d02823f4597dc9168363924 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11


                          


                                                                           
  



                                                                             
  

                                                                           


   










                                                                       










































































































































































































































                                                                              







                                                                           










                                                                     












                                                                     







                                                                         














                                                                          

















                                                                         
/*
 * 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.
 *
 * 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 General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

/**
 * SECTION: e-proxy-link-selector
 * @include: e-util/e-util.h
 * @short_description: Link accounts to a proxy profile
 *
 * #EProxyLinkSelector shows all network-based accounts in a tree view,
 * with a checkbox next to each account.  The checkbox allows users to
 * choose between linking the account to a pre-determined user-defined
 * proxy profile, or to the built-in default proxy profile.
 **/

#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);
}

/**
 * e_proxy_link_selector_new:
 * @registry: an #ESourceRegistry
 *
 * Creates a new #EProxyLinkSelector using #ESource instances in @registry.
 *
 * Returns: a new #EProxyLinkSelector
 **/
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);
}

/**
 * e_proxy_link_selector_ref_target_source:
 * @selector: an #EProxyLinkSelector
 *
 * Returns the target network proxy profile #ESource.
 *
 * See e_proxy_link_selector_set_target_source() for further details.
 *
 * The returned #ESource is referenced for thread-safety and must be
 * unreferenced with g_object_unref() when finished with it.
 *
 * Returns: an #ESource
 **/
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);
}

/**
 * e_proxy_link_selector_set_target_source:
 * @selector: an #EProxyLinkSelector
 * @target_source: an #ESource
 *
 * Sets the target network proxy profile #ESource.
 *
 * Checking the box next to an account name in @selector will link the
 * account to @target_source.  The account will then use @target_source
 * as its #GProxyResolver when connecting to a remote host.
 *
 * As a special case, if @target_source refers to the built-in network
 * proxy profile, then @selector will hide its checkboxes since they would
 * otherwise link accounts to the same #ESource when checked or unchecked.
 **/
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));
}