aboutsummaryrefslogblamecommitdiffstats
path: root/e-util/e-auth-combo-box.c
blob: bd3d8c78eabd60c8faca746ca5856b5d049d44f8 (plain) (tree)
















































































                                                                             

                                                                       

                                                       
                                                           




































































































                                                                             





                                                          








































































                                                                          
/*
 * e-auth-combo-box.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-auth-combo-box.h"

#define E_AUTH_COMBO_BOX_GET_PRIVATE(obj) \
    (G_TYPE_INSTANCE_GET_PRIVATE \
    ((obj), E_TYPE_AUTH_COMBO_BOX, EAuthComboBoxPrivate))

struct _EAuthComboBoxPrivate {
    CamelProvider *provider;
};

enum {
    PROP_0,
    PROP_PROVIDER
};

enum {
    COLUMN_MECHANISM,
    COLUMN_DISPLAY_NAME,
    COLUMN_STRIKETHROUGH,
    COLUMN_AUTHTYPE,
    NUM_COLUMNS
};

G_DEFINE_TYPE (
    EAuthComboBox,
    e_auth_combo_box,
    GTK_TYPE_COMBO_BOX)

static void
auth_combo_box_rebuild_model (EAuthComboBox *combo_box)
{
    GtkComboBox *gtk_combo_box;
    CamelProvider *provider;
    GtkTreeModel *model;
    GList *link;
    const gchar *active_id;

    provider = e_auth_combo_box_get_provider (combo_box);

    gtk_combo_box = GTK_COMBO_BOX (combo_box);
    model = gtk_combo_box_get_model (gtk_combo_box);
    active_id = gtk_combo_box_get_active_id (gtk_combo_box);

    gtk_list_store_clear (GTK_LIST_STORE (model));

    if (provider == NULL)
        return;

    for (link = provider->authtypes; link != NULL; link = link->next) {
        CamelServiceAuthType *authtype = link->data;
        GtkTreeIter iter;

        gtk_list_store_append (GTK_LIST_STORE (model), &iter);

        gtk_list_store_set (
            GTK_LIST_STORE (model), &iter,
            COLUMN_MECHANISM, authtype->authproto,
            COLUMN_DISPLAY_NAME, authtype->name,
            COLUMN_AUTHTYPE, authtype,
            -1);
    }

    /* Try selecting the previous mechanism. */
    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 (gtk_combo_box) == -1)
        gtk_combo_box_set_active (gtk_combo_box, 0);
}

static void
auth_combo_box_set_property (GObject *object,
                             guint property_id,
                             const GValue *value,
                             GParamSpec *pspec)
{
    switch (property_id) {
        case PROP_PROVIDER:
            e_auth_combo_box_set_provider (
                E_AUTH_COMBO_BOX (object),
                g_value_get_pointer (value));
            return;
    }

    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}

static void
auth_combo_box_get_property (GObject *object,
                             guint property_id,
                             GValue *value,
                             GParamSpec *pspec)
{
    switch (property_id) {
        case PROP_PROVIDER:
            g_value_set_pointer (
                value,
                e_auth_combo_box_get_provider (
                E_AUTH_COMBO_BOX (object)));
            return;
    }

    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}

static void
auth_combo_box_constructed (GObject *object)
{
    GtkComboBox *combo_box;
    GtkListStore *list_store;
    GtkCellLayout *cell_layout;
    GtkCellRenderer *cell_renderer;

    /* Chain up to parent's constructed() method. */
    G_OBJECT_CLASS (e_auth_combo_box_parent_class)->constructed (object);

    list_store = gtk_list_store_new (
        NUM_COLUMNS,
        G_TYPE_STRING,      /* COLUMN_MECHANISM */
        G_TYPE_STRING,      /* COLUMN_DISPLAY_NAME */
        G_TYPE_BOOLEAN,     /* COLUMN_STRIKETHROUGH */
        G_TYPE_POINTER);    /* COLUMN_AUTHTYPE */

    combo_box = GTK_COMBO_BOX (object);
    gtk_combo_box_set_model (combo_box, GTK_TREE_MODEL (list_store));
    gtk_combo_box_set_id_column (combo_box, COLUMN_MECHANISM);
    g_object_unref (list_store);

    cell_layout = GTK_CELL_LAYOUT (object);
    cell_renderer = gtk_cell_renderer_text_new ();
    gtk_cell_layout_pack_start (cell_layout, cell_renderer, TRUE);

    gtk_cell_layout_set_attributes (
        cell_layout, cell_renderer,
        "text", COLUMN_DISPLAY_NAME,
        "strikethrough", COLUMN_STRIKETHROUGH,
        NULL);
}

static void
e_auth_combo_box_class_init (EAuthComboBoxClass *class)
{
    GObjectClass *object_class;

    g_type_class_add_private (class, sizeof (EAuthComboBoxPrivate));

    object_class = G_OBJECT_CLASS (class);
    object_class->set_property = auth_combo_box_set_property;
    object_class->get_property = auth_combo_box_get_property;
    object_class->constructed = auth_combo_box_constructed;

    g_object_class_install_property (
        object_class,
        PROP_PROVIDER,
        g_param_spec_pointer (
            "provider",
            "Provider",
            "The provider to query for auth mechanisms",
            G_PARAM_READWRITE |
            G_PARAM_STATIC_STRINGS));
}

static void
e_auth_combo_box_init (EAuthComboBox *combo_box)
{
    combo_box->priv = E_AUTH_COMBO_BOX_GET_PRIVATE (combo_box);
}

GtkWidget *
e_auth_combo_box_new (void)
{
    return g_object_new (E_TYPE_AUTH_COMBO_BOX, NULL);
}

CamelProvider *
e_auth_combo_box_get_provider (EAuthComboBox *combo_box)
{
    g_return_val_if_fail (E_IS_AUTH_COMBO_BOX (combo_box), NULL);

    return combo_box->priv->provider;
}

void
e_auth_combo_box_set_provider (EAuthComboBox *combo_box,
                               CamelProvider *provider)
{
    g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box));

    if (provider == combo_box->priv->provider)
        return;

    combo_box->priv->provider = provider;

    g_object_notify (G_OBJECT (combo_box), "provider");

    auth_combo_box_rebuild_model (combo_box);
}

void
e_auth_combo_box_update_available (EAuthComboBox *combo_box,
                                   GList *available_authtypes)
{
    GtkComboBox *gtk_combo_box;
    GtkTreeModel *model;
    GtkTreeIter iter;
    gint active_index;
    gint available_index = -1;
    gint index = 0;
    gboolean iter_set;

    g_return_if_fail (E_IS_AUTH_COMBO_BOX (combo_box));

    gtk_combo_box = GTK_COMBO_BOX (combo_box);
    model = gtk_combo_box_get_model (gtk_combo_box);
    active_index = gtk_combo_box_get_active (gtk_combo_box);

    iter_set = gtk_tree_model_get_iter_first (model, &iter);

    while (iter_set) {
        CamelServiceAuthType *authtype;
        gboolean available;

        gtk_tree_model_get (
            model, &iter, COLUMN_AUTHTYPE, &authtype, -1);

        available = (g_list_find (
            available_authtypes, authtype) != NULL);

        gtk_list_store_set (
            GTK_LIST_STORE (model), &iter,
            COLUMN_STRIKETHROUGH, !available, -1);

        if (index == active_index && !available)
            active_index = -1;

        if (available && available_index == -1)
            available_index = index;

        iter_set = gtk_tree_model_iter_next (model, &iter);
        index++;
    }

    /* If the active combo_box item turned out to be unavailable
     * (or there was no active item), select the first available. */
    if (active_index == -1 && available_index != -1)
        gtk_combo_box_set_active (gtk_combo_box, available_index);
}