aboutsummaryrefslogblamecommitdiffstats
path: root/src/appearance-prefs.c
blob: 0cb928cdf335b8f8bdaebded337f4858f7d94bf3 (plain) (tree)




















































































































































































                                                                                                                  




                                                   
                                                                      











































































































































































































































































                                                                                        
/*
 *  Copyright (C) 2002 Marco Pesenti Gritti
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  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 General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "appearance-prefs.h"
#include "ephy-shell.h"
#include "ephy-prefs.h"
#include "ephy-embed-prefs.h"
#include "eel-gconf-extensions.h"

#include <string.h>
#include <gtk/gtkcombo.h>
#include <gtk/gtkspinbutton.h>
#include <gtk/gtkeditable.h>
#include <gtk/gtkoptionmenu.h>

static void appearance_prefs_class_init (AppearancePrefsClass *klass);
static void appearance_prefs_init (AppearancePrefs *dialog);
static void appearance_prefs_finalize (GObject *object);

/* Glade callbacks */
void
fonts_language_optionmenu_changed_cb (GtkWidget *optionmenu, EphyDialog *dialog);

static GObjectClass *parent_class = NULL;

struct AppearancePrefsPrivate
{
    int language;
    gboolean switching;
};

enum
{
    SERIF_PROP,
    SANSSERIF_PROP,
    MONOSPACE_PROP,
    FIXED_SIZE_PROP,
    VARIABLE_SIZE_PROP,
    MIN_SIZE_PROP,
    PROPORTIONAL_PROP,
    BACKGROUND_PROP,
    TEXT_PROP,
    UNVISITED_PROP,
    VISITED_PROP,
    USE_SYSCOLORS_PROP,
    USE_COLORS_PROP,
    USE_FONTS_PROP,
};

static const
EphyDialogProperty properties [] =
{
    { SERIF_PROP, "serif_combo", NULL, PT_NORMAL, NULL },
    { SANSSERIF_PROP, "sansserif_combo", NULL, PT_NORMAL, NULL },
    { MONOSPACE_PROP, "monospace_combo", NULL, PT_NORMAL, NULL },
    { FIXED_SIZE_PROP, "fixed_size_spinbutton", NULL, PT_NORMAL, NULL },
    { VARIABLE_SIZE_PROP, "variable_size_spinbutton", NULL, PT_NORMAL, NULL },
    { MIN_SIZE_PROP, "min_size_spinbutton", NULL, PT_NORMAL, NULL },
    { PROPORTIONAL_PROP, "proportional_optionmenu", CONF_RENDERING_DEFAULT_FONT, PT_AUTOAPPLY, NULL },
    { BACKGROUND_PROP, "background_cpick", CONF_RENDERING_BG_COLOR, PT_AUTOAPPLY, NULL },
    { TEXT_PROP, "text_cpick", CONF_RENDERING_TEXT_COLOR, PT_AUTOAPPLY, NULL },
    { UNVISITED_PROP, "unvisited_cpick", CONF_RENDERING_UNVISITED_LINKS, PT_AUTOAPPLY, NULL },
    { VISITED_PROP, "visited_cpick", CONF_RENDERING_VISITED_LINKS, PT_AUTOAPPLY, NULL },
    { USE_SYSCOLORS_PROP, "use_syscolors_checkbutton", CONF_RENDERING_USE_SYSTEM_COLORS, PT_AUTOAPPLY, NULL },
    { USE_COLORS_PROP, "use_colors_checkbutton", CONF_RENDERING_USE_OWN_COLORS, PT_AUTOAPPLY, NULL },
    { USE_FONTS_PROP, "use_fonts_checkbutton", CONF_RENDERING_USE_OWN_FONTS, PT_AUTOAPPLY, NULL },

    { -1, NULL, NULL }
};

/* FIXME duped in mozilla/ */
const
char *lang_encode[] =
{
        "x-western",
        "x-central-euro",
        "ja",
        "zh-TW",
        "zh-CN",
        "ko",
        "x-cyrillic",
        "x-baltic",
        "el",
        "tr",
        "x-unicode",
        "th",
        "he",
        "ar"
};

enum
{
    FONT_TYPE_SERIF,
    FONT_TYPE_SANSSERIF,
    FONT_TYPE_MONOSPACE
};

const
char *fonts_types[] =
{
    "serif",
    "sans-serif",
    "monospace"
};

enum
{
    FONT_SIZE_FIXED,
    FONT_SIZE_VAR,
    FONT_SIZE_MIN
};

const
char *size_prefs[] =
{
    CONF_RENDERING_FONT_FIXED_SIZE,
    CONF_RENDERING_FONT_VAR_SIZE,
    CONF_RENDERING_FONT_MIN_SIZE
};

GType
appearance_prefs_get_type (void)
{
        static GType appearance_prefs_type = 0;

        if (appearance_prefs_type == 0)
        {
                static const GTypeInfo our_info =
                {
                        sizeof (AppearancePrefsClass),
                        NULL, /* base_init */
                        NULL, /* base_finalize */
                        (GClassInitFunc) appearance_prefs_class_init,
                        NULL,
                        NULL, /* class_data */
                        sizeof (AppearancePrefs),
                        0, /* n_preallocs */
                        (GInstanceInitFunc) appearance_prefs_init
                };

                appearance_prefs_type = g_type_register_static (EPHY_DIALOG_TYPE,
                                      "AppearancePrefs",
                                      &our_info, 0);
        }

        return appearance_prefs_type;

}

static void
appearance_prefs_class_init (AppearancePrefsClass *klass)
{
        GObjectClass *object_class = G_OBJECT_CLASS (klass);

        parent_class = g_type_class_peek_parent (klass);

        object_class->finalize = appearance_prefs_finalize;
}

static void
setup_font_menu (AppearancePrefs *dialog,
         const char *type,
         GtkWidget *combo)
{
    char *default_font;
    GList *fonts;
    const char *name;
    char key[255];
    int pos;
    GtkWidget *entry = GTK_COMBO(combo)->entry;

    ephy_embed_shell_get_font_list (EPHY_EMBED_SHELL (ephy_shell),
                    lang_encode[dialog->priv->language],
                    type, &fonts, &default_font);

    /* Get the default font */
    sprintf (key, "%s_%s_%s", CONF_RENDERING_FONT, type,
         lang_encode[dialog->priv->language]);
    name = eel_gconf_get_string (key);
    if (name == NULL)
    {
        name = default_font;
    }

    /* put the default font at the top in the list */
    if (name != NULL)
    {
        fonts = g_list_prepend (fonts,
                    (gpointer)g_strdup(name));
    }

    /* set popdown doesnt like NULL */
    if (fonts == NULL)
    {
        fonts = g_list_alloc ();
    }

    gtk_combo_set_popdown_strings (GTK_COMBO(combo), fonts);

    /* set the default value */
    if (name != NULL)
    {
        gtk_editable_delete_text (GTK_EDITABLE(entry), 0, -1);
        gtk_editable_insert_text (GTK_EDITABLE(entry),
                      name, g_utf8_strlen (name, -1),
                      &pos);
    }

    g_free (default_font);

    /* FIXME free the list */
}

static void
save_font_menu (AppearancePrefs *dialog,
        int type,
        GtkWidget *entry)
{
    char *name;
    char key[255];

    name = gtk_editable_get_chars
        (GTK_EDITABLE(entry), 0, -1);

    /* do not save empty fonts */
    if (!name || *name == '\0')
    {
        g_free (name);
        return;
    }

    sprintf (key, "%s_%s_%s", CONF_RENDERING_FONT,
         fonts_types[type],
         lang_encode[dialog->priv->language]);
    eel_gconf_set_string (key, name);
    g_free (name);
}

static void
font_entry_changed_cb (GtkWidget *entry, AppearancePrefs *dialog)
{
    int type;

    if (dialog->priv->switching) return;

    type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(entry),
                            "type"));
    save_font_menu (dialog, type, entry);
}

static void
attach_font_signal (AppearancePrefs *dialog, int prop,
            gpointer type)
{
    GtkWidget *combo;
    GtkWidget *entry;

    combo = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                       prop);
    entry = GTK_COMBO(combo)->entry;
    g_object_set_data (G_OBJECT(entry), "type", type);
    g_signal_connect (entry, "changed",
              G_CALLBACK(font_entry_changed_cb),
              dialog);
}

static void
attach_fonts_signals (AppearancePrefs *dialog)
{
    attach_font_signal (dialog, SERIF_PROP,
                GINT_TO_POINTER(FONT_TYPE_SERIF));
    attach_font_signal (dialog, SANSSERIF_PROP,
                GINT_TO_POINTER(FONT_TYPE_SANSSERIF));
    attach_font_signal (dialog, MONOSPACE_PROP,
                GINT_TO_POINTER(FONT_TYPE_MONOSPACE));
}

static void
size_spinbutton_changed_cb (GtkWidget *spin, AppearancePrefs *dialog)
{
    int type;
    char key[255];

    if (dialog->priv->switching) return;

    type = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(spin), "type"));

    sprintf (key, "%s_%s",
         size_prefs[type],
         lang_encode[dialog->priv->language]);
    eel_gconf_set_integer (key, gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin)));
}

static void
attach_size_controls_signals (AppearancePrefs *dialog)
{
    GtkWidget *spin;

    spin = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                      FIXED_SIZE_PROP);
    g_object_set_data (G_OBJECT(spin), "type",
               GINT_TO_POINTER(FONT_SIZE_FIXED));
    g_signal_connect (spin, "value_changed",
              G_CALLBACK(size_spinbutton_changed_cb),
              dialog);

    spin = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                      VARIABLE_SIZE_PROP);
    g_object_set_data (G_OBJECT(spin), "type",
               GINT_TO_POINTER(FONT_SIZE_VAR));
    g_signal_connect (spin, "value_changed",
              G_CALLBACK(size_spinbutton_changed_cb),
              dialog);

    spin = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                      MIN_SIZE_PROP);
    g_object_set_data (G_OBJECT(spin), "type",
               GINT_TO_POINTER(FONT_SIZE_MIN));
    g_signal_connect (spin, "value_changed",
              G_CALLBACK(size_spinbutton_changed_cb),
              dialog);
}

static void
setup_size_control (AppearancePrefs *dialog,
            const char *pref,
            int default_size,
            GtkWidget *spin)
{
    char key[255];
    int size;

    sprintf (key, "%s_%s", pref,
         lang_encode[dialog->priv->language]);
    size = eel_gconf_get_integer (key);

    if (size == 0) size = default_size;

    gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin), size);
}

static void
setup_size_controls (AppearancePrefs *dialog)
{
    GtkWidget *spin;

    spin = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                      FIXED_SIZE_PROP);
    setup_size_control (dialog, CONF_RENDERING_FONT_FIXED_SIZE, 12, spin);

    spin = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                      VARIABLE_SIZE_PROP);
    setup_size_control (dialog, CONF_RENDERING_FONT_VAR_SIZE, 16, spin);

    spin = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                      MIN_SIZE_PROP);
    setup_size_control (dialog, CONF_RENDERING_FONT_MIN_SIZE, 0, spin);
}

static void
setup_fonts (AppearancePrefs *dialog)
{
    GtkWidget *combo;

    dialog->priv->switching = TRUE;

    combo = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                     SERIF_PROP);
    setup_font_menu (dialog, "serif", combo);

    combo = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                     SANSSERIF_PROP);
    setup_font_menu (dialog, "sans-serif", combo);

    combo = ephy_dialog_get_control (EPHY_DIALOG(dialog),
                     MONOSPACE_PROP);
    setup_font_menu (dialog, "monospace", combo);

    dialog->priv->switching = FALSE;
}

static void
appearance_prefs_init (AppearancePrefs *dialog)
{
    dialog->priv = g_new0 (AppearancePrefsPrivate, 1);
    dialog->priv->switching = FALSE;

    ephy_dialog_construct (EPHY_DIALOG(dialog),
                   properties,
                   "prefs-dialog.glade",
                   "appearance_page_box");

    setup_fonts (dialog);
    setup_size_controls (dialog);
    attach_fonts_signals (dialog);
    attach_size_controls_signals (dialog);
}

static void
appearance_prefs_finalize (GObject *object)
{
    AppearancePrefs *dialog;

        g_return_if_fail (object != NULL);
        g_return_if_fail (IS_appearance_PREFS (object));

    dialog = appearance_PREFS (object);

        g_return_if_fail (dialog->priv != NULL);

        g_free (dialog->priv);

        G_OBJECT_CLASS (parent_class)->finalize (object);
}

EphyDialog *
appearance_prefs_new (void)
{
    AppearancePrefs *dialog;

    dialog = appearance_PREFS (g_object_new (appearance_PREFS_TYPE,
                                  NULL));

    return EPHY_DIALOG(dialog);
}

void
fonts_language_optionmenu_changed_cb (GtkWidget *optionmenu,
                      EphyDialog *dialog)
{
    int i;

    i = gtk_option_menu_get_history
        (GTK_OPTION_MENU (optionmenu));

    appearance_PREFS(dialog)->priv->language = i;

    setup_fonts (appearance_PREFS(dialog));
    setup_size_controls (appearance_PREFS(dialog));
}