/* * Copyright (C) 2000, 2001, 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. * * $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "prefs-dialog.h" #include "ephy-dialog.h" #include "ephy-prefs.h" #include "ephy-embed-shell.h" #include "ephy-shell.h" #include "ephy-session.h" #include "ephy-embed-prefs.h" #include "ephy-embed-single.h" #include "ephy-shell.h" #include "ephy-gui.h" #include "eel-gconf-extensions.h" #include "language-editor.h" #include "ephy-langs.h" #include "ephy-encodings.h" #include "ephy-debug.h" #include "ephy-ellipsizing-label.h" #include "ephy-file-chooser.h" #include #include #include #include #include #include #include #include #include #include static void prefs_dialog_class_init (PrefsDialogClass *klass); static void prefs_dialog_init (PrefsDialog *pd); static void prefs_dialog_finalize (GObject *object); /* Glade callbacks */ void prefs_proxy_auto_url_reload_cb (GtkWidget *button, EphyDialog *dialog); void prefs_clear_cache_button_clicked_cb (GtkWidget *button, gpointer data); void prefs_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer data); void fonts_language_optionmenu_changed_cb (GtkWidget *optionmenu, EphyDialog *dialog); void prefs_homepage_current_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); void prefs_homepage_blank_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); void prefs_language_more_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); void prefs_download_path_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); static const struct { char *name; char *code; } languages [] = { /** * please translate like this: " (System setting)" * Examples: * "de" translation: "Deutsch (Systemeinstellung)" * "en_AU" translation: "English, Australia (System setting)" or * "Australian English (System setting)" */ { N_("System language"), "system" }, { N_("Afrikaans"), "ak" }, { N_("Albanian"), "sq" }, { N_("Arabic"), "ar" }, { N_("Azerbaijani"), "az" }, { N_("Basque"), "eu" }, { N_("Breton"), "br" }, { N_("Bulgarian"), "bg" }, { N_("Byelorussian"), "be" }, { N_("Catalan"), "ca" }, { N_("Simplified Chinese"), "zh-cn" }, { N_("Traditional Chinese"), "zh-tw" }, { N_("Chinese"), "zh" }, { N_("Croatian"), "hr" }, { N_("Czech"), "cs" }, { N_("Danish"), "da" }, { N_("Dutch"), "nl" }, { N_("English"), "en" }, { N_("Esperanto"), "eo" }, { N_("Estonian"), "et" }, { N_("Faeroese"), "fo" }, { N_("Finnish"), "fi" }, { N_("French"), "fr" }, { N_("Galician"), "gl" }, { N_("German"), "de" }, { N_("Greek"), "el" }, { N_("Hebrew"), "he" }, { N_("Hungarian"), "hu" }, { N_("Icelandic"), "is" }, { N_("Indonesian"), "id" }, { N_("Irish"), "ga" }, { N_("Italian"), "it" }, { N_("Japanese"), "ja" }, { N_("Korean"), "ko" }, { N_("Latvian"), "lv" }, { N_("Lithuanian"), "lt" }, { N_("Macedonian"), "mk" }, { N_("Malay"), "ms" }, { N_("Norwegian/Nynorsk"), "nn" }, { N_("Norwegian/Bokmal"), "nb" }, { N_("Norwegian"), "no" }, { N_("Polish"), "pl" }, { N_("Portuguese"), "pt" }, { N_("Portuguese of Brazil"), "pt-br" }, { N_("Romanian"), "ro" }, { N_("Russian"), "ru" }, { N_("Scottish"), "gd" }, { N_("Serbian"), "sr" }, { N_("Slovak"), "sk" }, { N_("Slovenian"), "sl" }, { N_("Spanish"), "es" }, { N_("Swedish"), "sv" }, { N_("Tamil"), "ta" }, { N_("Turkish"), "tr" }, { N_("Ukrainian"), "uk" }, { N_("Vietnamese"), "vi" }, { N_("Walloon"), "wa" } }; static guint n_languages = G_N_ELEMENTS (languages); static const char *cookies_accept_enum [] = { "anywhere", "current site", "nowhere" }; static guint n_cookies_accept_enum = G_N_ELEMENTS (cookies_accept_enum); enum { FONT_TYPE_VARIABLE, FONT_TYPE_MONOSPACE }; const char *fonts_types[] = { "variable", "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 }; enum { WINDOW_PROP, NOTEBOOK_PROP, /* General */ HOMEPAGE_ENTRY_PROP, AUTO_OPEN_PROP, DOWNLOAD_PATH_BUTTON_PROP, /* Fonts and Colors */ FONTS_LANGUAGE_PROP, VARIABLE_PROP, MONOSPACE_PROP, FIXED_SIZE_PROP, VARIABLE_SIZE_PROP, MIN_SIZE_PROP, USE_COLORS_PROP, USE_FONTS_PROP, /* Privacy */ ALLOW_POPUPS_PROP, ALLOW_JAVA_PROP, ALLOW_JS_PROP, ACCEPT_COOKIES_PROP, DISK_CACHE_PROP, /* Language */ AUTO_ENCODING_PROP, DEFAULT_ENCODING_PROP, LANGUAGE_PROP, LANGUAGE_LABEL_PROP, DEFAULT_ENCODING_LABEL_PROP, AUTO_ENCODING_LABEL_PROP }; #define CONF_FONTS_FOR_LANGUAGE "/apps/epiphany/dialogs/preferences_font_language" static const EphyDialogProperty properties [] = { { WINDOW_PROP, "prefs_dialog", NULL, PT_NORMAL, NULL }, { NOTEBOOK_PROP, "prefs_notebook", NULL, PT_NORMAL, NULL }, /* General */ { HOMEPAGE_ENTRY_PROP, "homepage_entry", CONF_GENERAL_HOMEPAGE, PT_AUTOAPPLY, NULL }, { AUTO_OPEN_PROP, "auto_open_downloads_checkbutton", CONF_AUTO_OPEN_DOWNLOADS, PT_AUTOAPPLY, NULL}, { DOWNLOAD_PATH_BUTTON_PROP, "download_path_button", NULL, PT_NORMAL, NULL }, /* Fonts and Colors */ { FONTS_LANGUAGE_PROP, "fonts_language_optionmenu", CONF_FONTS_FOR_LANGUAGE, PT_AUTOAPPLY, NULL }, { VARIABLE_PROP, "variable_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 }, { 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 }, /* Privacy */ { ALLOW_POPUPS_PROP, "popups_allow_checkbutton", CONF_SECURITY_ALLOW_POPUPS, PT_AUTOAPPLY, NULL }, { ALLOW_JAVA_PROP, "enable_java_checkbutton", CONF_SECURITY_JAVA_ENABLED, PT_AUTOAPPLY, NULL }, { ALLOW_JS_PROP, "enable_javascript_checkbutton", CONF_SECURITY_JAVASCRIPT_ENABLED, PT_AUTOAPPLY, NULL }, { ACCEPT_COOKIES_PROP, "cookies_radiobutton", CONF_SECURITY_COOKIES_ACCEPT, PT_AUTOAPPLY, NULL }, { DISK_CACHE_PROP, "disk_cache_spin", CONF_NETWORK_CACHE_SIZE, PT_AUTOAPPLY, NULL }, /* Languages */ { AUTO_ENCODING_PROP, "auto_encoding_optionmenu", CONF_LANGUAGE_AUTODETECT_ENCODING, PT_AUTOAPPLY, NULL }, { DEFAULT_ENCODING_PROP, "default_encoding_optionmenu", CONF_LANGUAGE_DEFAULT_ENCODING, PT_AUTOAPPLY, NULL }, { LANGUAGE_PROP, "language_optionmenu", NULL, PT_NORMAL, NULL }, { LANGUAGE_LABEL_PROP, "language_label", NULL, PT_NORMAL, NULL }, { DEFAULT_ENCODING_LABEL_PROP, "default_encoding_label", NULL, PT_NORMAL, NULL }, { AUTO_ENCODING_LABEL_PROP, "auto_encoding_label", NULL, PT_NORMAL, NULL }, { -1, NULL, NULL } }; static int lang_size_group [] = { LANGUAGE_LABEL_PROP, DEFAULT_ENCODING_LABEL_PROP, AUTO_ENCODING_LABEL_PROP }; static guint n_lang_size_group = G_N_ELEMENTS (lang_size_group); typedef struct { gchar *name; gchar *key; gchar *code; } EphyLangItem; #define EPHY_PREFS_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_PREFS_DIALOG, PrefsDialogPrivate)) struct PrefsDialogPrivate { GtkWidget *notebook; GtkWidget *window; GList *langs; GList *fonts_languages; guint language; gboolean switching; }; static GObjectClass *parent_class = NULL; GType prefs_dialog_get_type (void) { static GType prefs_dialog_type = 0; if (prefs_dialog_type == 0) { static const GTypeInfo our_info = { sizeof (PrefsDialogClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) prefs_dialog_class_init, NULL, NULL, /* class_data */ sizeof (PrefsDialog), 0, /* n_preallocs */ (GInstanceInitFunc) prefs_dialog_init }; prefs_dialog_type = g_type_register_static (EPHY_TYPE_DIALOG, "PrefsDialog", &our_info, 0); } return prefs_dialog_type; } EphyDialog * prefs_dialog_new (GtkWidget *parent) { EphyDialog *dialog; dialog = EPHY_DIALOG (g_object_new (EPHY_TYPE_PREFS_DIALOG, "ParentWindow", parent, NULL)); return dialog; } static void prefs_dialog_class_init (PrefsDialogClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = prefs_dialog_finalize; g_type_class_add_private (object_class, sizeof(PrefsDialogPrivate)); } static void free_lang_item (EphyLangItem *item, gpointer user_data) { if (item == NULL) return; g_free (item->name); g_free (item->key); g_free (item->code); g_free (item); } static void prefs_dialog_finalize (GObject *object) { PrefsDialog *pd = EPHY_PREFS_DIALOG (object); GtkWidget *button; /* Free the ellipsizing label in the button */ button = ephy_dialog_get_control (EPHY_DIALOG (pd), DOWNLOAD_PATH_BUTTON_PROP); gtk_widget_destroy (GTK_WIDGET (GTK_BIN (button)->child)); g_list_foreach (pd->priv->langs, (GFunc) free_lang_item, NULL); g_list_free (pd->priv->langs); g_list_foreach (pd->priv->fonts_languages, (GFunc) g_free, NULL); g_list_free (pd->priv->fonts_languages); G_OBJECT_CLASS (parent_class)->finalize (object); } static void prefs_dialog_show_help (PrefsDialog *pd) { gint id; /* FIXME: Once we actually have documentation we * should point these at the correct links. */ gchar *help_preferences[] = { "setting-preferences", "setting-preferences", "setting-preferences", "setting-preferences" }; id = gtk_notebook_get_current_page (GTK_NOTEBOOK (pd->priv->notebook)); ephy_gui_help (GTK_WINDOW (pd->priv->window), "epiphany", help_preferences[id]); } static const char * get_current_language_code (PrefsDialog *dialog) { GList *lang; const EphyFontsLanguageInfo *info; lang = g_list_nth (dialog->priv->fonts_languages, dialog->priv->language); g_assert (lang != NULL); info = (EphyFontsLanguageInfo *) lang->data; return info->code; } static void setup_font_menu (PrefsDialog *dialog, const char *type, GtkWidget *combo) { GList *fonts = NULL; gchar *name; char key[255]; GtkWidget *entry = GTK_COMBO(combo)->entry; EphyEmbedSingle *single; single = ephy_embed_shell_get_embed_single (EPHY_EMBED_SHELL (ephy_shell)); fonts = ephy_embed_single_get_font_list (single, get_current_language_code (dialog)); /* Get the default font */ g_snprintf (key, 255, "%s_%s_%s", CONF_RENDERING_FONT, type, get_current_language_code (dialog)); name = eel_gconf_get_string (key); if (name == NULL) { if (strcmp (type, "variable") == 0) { name = g_strdup ("sans-serif"); } else { name = g_strdup ("monospace"); } } /* 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) { int pos = 0; gtk_editable_delete_text (GTK_EDITABLE(entry), 0, -1); gtk_editable_insert_text (GTK_EDITABLE(entry), name, strlen (name), &pos); } g_free (name); g_list_foreach (fonts, (GFunc)g_free, NULL); g_list_free (fonts); } static void save_font_menu (PrefsDialog *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; } g_snprintf (key, 255, "%s_%s_%s", CONF_RENDERING_FONT, fonts_types[type], get_current_language_code (dialog)); eel_gconf_set_string (key, name); g_free (name); } static void font_entry_changed_cb (GtkWidget *entry, PrefsDialog *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 (PrefsDialog *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 (PrefsDialog *dialog) { attach_font_signal (dialog, VARIABLE_PROP, GINT_TO_POINTER(FONT_TYPE_VARIABLE)); attach_font_signal (dialog, MONOSPACE_PROP, GINT_TO_POINTER(FONT_TYPE_MONOSPACE)); } static void size_spinbutton_changed_cb (GtkWidget *spin, PrefsDialog *dialog) { int type; char key[255]; if (dialog->priv->switching) return; type = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(spin), "type")); g_snprintf (key, 255, "%s_%s", size_prefs[type], get_current_language_code (dialog)); eel_gconf_set_integer (key, gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin))); } static void attach_size_controls_signals (PrefsDialog *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 (PrefsDialog *dialog, const char *pref, int default_size, GtkWidget *spin) { char key[255]; int size; g_snprintf (key, 255, "%s_%s", pref, get_current_language_code (dialog)); 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 (PrefsDialog *dialog) { GtkWidget *spin; spin = ephy_dialog_get_control (EPHY_DIALOG(dialog), FIXED_SIZE_PROP); setup_size_control (dialog, CONF_RENDERING_FONT_FIXED_SIZE, 10, spin); spin = ephy_dialog_get_control (EPHY_DIALOG(dialog), VARIABLE_SIZE_PROP); setup_size_control (dialog, CONF_RENDERING_FONT_VAR_SIZE, 11, spin); spin = ephy_dialog_get_control (EPHY_DIALOG(dialog), MIN_SIZE_PROP); setup_size_control (dialog, CONF_RENDERING_FONT_MIN_SIZE, 7, spin); } static void setup_fonts (PrefsDialog *dialog) { GtkWidget *combo; dialog->priv->switching = TRUE; combo = ephy_dialog_get_control (EPHY_DIALOG(dialog), VARIABLE_PROP); setup_font_menu (dialog, "variable", combo); combo = ephy_dialog_get_control (EPHY_DIALOG(dialog), MONOSPACE_PROP); setup_font_menu (dialog, "monospace", combo); dialog->priv->switching = FALSE; } static int fonts_language_info_cmp (const EphyFontsLanguageInfo *i1, const EphyFontsLanguageInfo *i2) { return g_utf8_collate (i1->title, i2->title); } static void create_fonts_language_menu (PrefsDialog *dialog) { GtkWidget *optionmenu, *menu; GList *list = NULL, *l; guint n_fonts_languages, i; char **lang_codes; const EphyFontsLanguageInfo *fonts_languages; optionmenu = ephy_dialog_get_control (EPHY_DIALOG (dialog), FONTS_LANGUAGE_PROP); menu = gtk_menu_new (); fonts_languages = ephy_font_languages (); n_fonts_languages = ephy_font_n_languages (); for (i = 0; i < n_fonts_languages; i++) { EphyFontsLanguageInfo *info; info = g_new0 (EphyFontsLanguageInfo, 1); info->title = _(fonts_languages[i].title); info->code = fonts_languages[i].code; list = g_list_prepend (list, info); } dialog->priv->fonts_languages = g_list_sort (list, (GCompareFunc) fonts_language_info_cmp); for (l = dialog->priv->fonts_languages; l != NULL; l = l->next) { EphyFontsLanguageInfo *info = (EphyFontsLanguageInfo *) l->data; GtkWidget *item; item = gtk_menu_item_new_with_label (info->title); gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); gtk_widget_show (item); } gtk_option_menu_set_menu (GTK_OPTION_MENU(optionmenu), menu); lang_codes = g_new0 (char *, n_fonts_languages); for (l = dialog->priv->fonts_languages, i=0; l != NULL; l = l->next) { EphyFontsLanguageInfo *info = (EphyFontsLanguageInfo *) l->data; lang_codes[i] = info->code; i++; } ephy_dialog_add_enum (EPHY_DIALOG (dialog), FONTS_LANGUAGE_PROP, n_fonts_languages, (const char **) lang_codes); /* the entries themselves are const, so don't use g_strfreev here */ g_free (lang_codes); dialog->priv->language = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu)); g_signal_connect (optionmenu, "changed", G_CALLBACK (fonts_language_optionmenu_changed_cb), dialog); } static int find_encoding_in_list_cmp (gconstpointer info, const char *encoding) { EphyNode *node = (EphyNode *) info; const char *code; code = ephy_node_get_property_string (node, EPHY_NODE_ENCODING_PROP_ENCODING); return strcmp (code, encoding); } static int sort_encodings (gconstpointer a, gconstpointer b) { EphyNode *node1 = (EphyNode *) a; EphyNode *node2 = (EphyNode *) b; const char *key1, *key2; key1 = ephy_node_get_property_string (node1, EPHY_NODE_ENCODING_PROP_COLLATION_KEY); key2 = ephy_node_get_property_string (node2, EPHY_NODE_ENCODING_PROP_COLLATION_KEY); return strcmp (key1, key2); } static int sort_detectors (gconstpointer a, gconstpointer b) { EphyNode *node1 = (EphyNode *) a; EphyNode *node2 = (EphyNode *) b; const char *code1, *code2; code1 = ephy_node_get_property_string (node1, EPHY_NODE_ENCODING_PROP_ENCODING); code2 = ephy_node_get_property_string (node2, EPHY_NODE_ENCODING_PROP_ENCODING); /* "" is the code for No Autodetector; make sure it's first * in the list. */ if (strcmp (code1, "") == 0) { return -1; } if (strcmp (code2, "") == 0) { return 1; } return sort_encodings (a, b); } static void create_optionmenu (PrefsDialog *dialog, int property, GList *list, const char *key, const char *default_value) { GList *element, *l; GtkWidget *menu, *optionmenu; char *value; char **codes; guint pos, i, num; menu = gtk_menu_new (); optionmenu = ephy_dialog_get_control (EPHY_DIALOG (dialog), property); num = g_list_length (list); codes = g_new0 (char *, num); for (l = list, i=0; l != NULL; l = l->next, i++) { EphyNode *node = (EphyNode *) l->data; const char *title, *code; GtkWidget *item; title = ephy_node_get_property_string (node, EPHY_NODE_ENCODING_PROP_TITLE_ELIDED); item = gtk_menu_item_new_with_label (title); gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); gtk_widget_show (item); code = ephy_node_get_property_string (node, EPHY_NODE_ENCODING_PROP_ENCODING); codes[i] = (char *) code; } gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); /* init value */ value = eel_gconf_get_string (key); /* fallback */ if (value == NULL || value[0] == '\0') { g_free (value); value = g_strdup (default_value); } element = g_list_find_custom (list, value, (GCompareFunc) find_encoding_in_list_cmp); g_free (value); pos = g_list_position (list, element); ephy_dialog_add_enum (EPHY_DIALOG (dialog), property, num, (const char **) codes); gtk_option_menu_set_history (GTK_OPTION_MENU(optionmenu), pos); /* the entries themselves are const, so we don't use g_strfreev here */ g_free (codes); } static gint compare_lang_items (const EphyLangItem *i1, const EphyLangItem *i2) { return strcmp (i1->key, i2->key); } static gint find_lang_code (const EphyLangItem *i1, const gchar *code) { return strcmp (i1->code, code); } static void create_languages_list (PrefsDialog *dialog) { GList *list = NULL, *lang; GSList *pref_list, *l; EphyLangItem *item; const gchar *code; guint i; for (i = 0; i < n_languages; i++) { item = g_new0 (EphyLangItem, 1); item->name = g_strdup (_(languages[i].name)); item->key = g_utf8_collate_key (item->name, -1); item->code = g_strdup (languages[i].code); list = g_list_prepend (list, item); } /* add custom languages */ pref_list = eel_gconf_get_string_list (CONF_RENDERING_LANGUAGE); for (l = pref_list; l != NULL; l = l->next) { code = (const gchar*) l->data; lang = g_list_find_custom (list, code, (GCompareFunc) find_lang_code); if (lang == NULL) { /* not found in list */ item = g_new0 (EphyLangItem, 1); item->name = g_strdup_printf (_("Custom [%s]"), code); item->key = g_utf8_collate_key (item->name, -1); item->code = g_strdup (code); list = g_list_prepend (list, item); } } if (pref_list) { g_slist_foreach (pref_list, (GFunc) g_free, NULL); g_slist_free (pref_list); } list = g_list_sort (list, (GCompareFunc) compare_lang_items); dialog->priv->langs = list; } static GtkWidget * general_prefs_new_language_menu (PrefsDialog *dialog) { GList *l; GtkWidget *menu; EphyLangItem *li; menu = gtk_menu_new (); for (l = dialog->priv->langs; l != NULL; l = l->next) { GtkWidget *item; li = (EphyLangItem*) l->data; item = gtk_menu_item_new_with_label (li->name); gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); gtk_widget_show (item); g_object_set_data (G_OBJECT (item), "desc", li->name); } return menu; } static void language_menu_changed_cb (GtkOptionMenu *option_menu, gpointer data) { gint i; GSList *list = NULL; GList *lang = NULL; g_return_if_fail (EPHY_IS_PREFS_DIALOG (data)); list = eel_gconf_get_string_list (CONF_RENDERING_LANGUAGE); g_return_if_fail (list != NULL); /* Subst the first item according to the optionmenu */ i = gtk_option_menu_get_history (option_menu); lang = g_list_nth (EPHY_PREFS_DIALOG (data)->priv->langs, i); if (lang) { g_free (list->data); list->data = g_strdup (((EphyLangItem *) lang->data)->code); eel_gconf_set_string_list (CONF_RENDERING_LANGUAGE, list); } g_slist_foreach (list, (GFunc) g_free, NULL); g_slist_free (list); } static void create_language_menu (PrefsDialog *dialog) { GtkWidget *optionmenu; GtkWidget *menu; const gchar *code; gint i = 0; GSList *list; GList *lang; optionmenu = ephy_dialog_get_control (EPHY_DIALOG (dialog), LANGUAGE_PROP); menu = general_prefs_new_language_menu (dialog); gtk_option_menu_set_menu (GTK_OPTION_MENU(optionmenu), menu); /* init value from first element of the list */ list = eel_gconf_get_string_list (CONF_RENDERING_LANGUAGE); if (list) { code = (const gchar *) list->data; lang = g_list_find_custom (dialog->priv->langs, code, (GCompareFunc)find_lang_code); if (lang) { i = g_list_position (dialog->priv->langs, lang); } g_slist_foreach (list, (GFunc) g_free, NULL); g_slist_free (list); } gtk_option_menu_set_history (GTK_OPTION_MENU(optionmenu), i); g_signal_connect (optionmenu, "changed", G_CALLBACK (language_menu_changed_cb), dialog); } static void set_homepage_entry (EphyDialog *dialog, const char *new_location) { GtkWidget *entry; int pos = 0; entry = ephy_dialog_get_control (dialog, HOMEPAGE_ENTRY_PROP); gtk_editable_delete_text (GTK_EDITABLE (entry), 0, -1); gtk_editable_insert_text (GTK_EDITABLE (entry), new_location, strlen (new_location), &pos); } static char* get_download_button_label () { char *label, *key, *desktop_path, *tmp; key = eel_gconf_get_string (CONF_STATE_DOWNLOAD_DIR); tmp = g_build_filename (g_get_home_dir (), "Desktop", NULL); desktop_path = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL); g_free (tmp); if (!g_utf8_collate (key, desktop_path)) { g_free (key); label = g_strdup (_("Desktop")); } else { label = key; } g_free (desktop_path); return label; } static void create_download_path_label (PrefsDialog *pd) { char *dir; GtkWidget *button, *label; EphyDialog *dialog = EPHY_DIALOG (pd); button = ephy_dialog_get_control (dialog, DOWNLOAD_PATH_BUTTON_PROP); dir = get_download_button_label (); label = ephy_ellipsizing_label_new (dir); ephy_ellipsizing_label_set_mode ((EphyEllipsizingLabel*)label, EPHY_ELLIPSIZE_START); gtk_container_add (GTK_CONTAINER (button), label); g_free (dir); gtk_widget_show (label); } static void prefs_dialog_init (PrefsDialog *pd) { EphyDialog *dialog = EPHY_DIALOG (pd); EphyEncodings *encodings; GdkPixbuf *icon; GList *list; pd->priv = EPHY_PREFS_DIALOG_GET_PRIVATE (pd); ephy_dialog_construct (EPHY_DIALOG (pd), properties, "prefs-dialog.glade", "prefs_dialog"); ephy_dialog_add_enum (EPHY_DIALOG (pd), ACCEPT_COOKIES_PROP, n_cookies_accept_enum, cookies_accept_enum); ephy_dialog_set_size_group (EPHY_DIALOG (pd), lang_size_group, n_lang_size_group); pd->priv->window = ephy_dialog_get_control (dialog, WINDOW_PROP); pd->priv->notebook = ephy_dialog_get_control (dialog, NOTEBOOK_PROP); pd->priv->langs = NULL; pd->priv->fonts_languages = NULL; icon = gtk_widget_render_icon (pd->priv->window, GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU, "prefs_dialog"); gtk_window_set_icon (GTK_WINDOW (pd->priv->window), icon); g_object_unref(icon); pd->priv->switching = FALSE; create_fonts_language_menu (pd); attach_fonts_signals (pd); attach_size_controls_signals (pd); create_languages_list (pd); encodings = EPHY_ENCODINGS (ephy_embed_shell_get_encodings (EPHY_EMBED_SHELL (ephy_shell))); list = ephy_encodings_get_encodings (encodings, LG_ALL); list = g_list_sort (list, (GCompareFunc) sort_encodings); create_optionmenu (pd, DEFAULT_ENCODING_PROP, list, CONF_LANGUAGE_DEFAULT_ENCODING, "ISO-8859-1"); g_list_free (list); list = ephy_encodings_get_detectors (encodings); list = g_list_sort (list, (GCompareFunc) sort_detectors); create_optionmenu (pd, AUTO_ENCODING_PROP, list, CONF_LANGUAGE_AUTODETECT_ENCODING, ""); g_list_free (list); create_language_menu (pd); create_download_path_label (pd); } void prefs_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer data) { if (response_id == GTK_RESPONSE_CLOSE) { gtk_widget_destroy (GTK_WIDGET(dialog)); } else if (response_id == GTK_RESPONSE_HELP) { PrefsDialog *pd = (PrefsDialog *)data; prefs_dialog_show_help (pd); } } void prefs_clear_cache_button_clicked_cb (GtkWidget *button, gpointer data) { EphyEmbedSingle *single; single = ephy_embed_shell_get_embed_single (EPHY_EMBED_SHELL (ephy_shell)); ephy_embed_single_clear_cache (single); } void fonts_language_optionmenu_changed_cb (GtkWidget *optionmenu, EphyDialog *dialog) { guint i; PrefsDialog *pd = EPHY_PREFS_DIALOG (dialog); i = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu)); pd->priv->language = i; setup_fonts (pd); setup_size_controls (pd); } void prefs_homepage_current_button_clicked_cb (GtkWidget *button, EphyDialog *dialog) { EphySession *session; EphyWindow *window; EphyEmbed *embed; char *location; session = EPHY_SESSION (ephy_shell_get_session (ephy_shell)); window = ephy_session_get_active_window (session); g_return_if_fail (window != NULL); embed = ephy_window_get_active_embed (window); g_return_if_fail (embed != NULL); location = ephy_embed_get_location (embed, TRUE); set_homepage_entry (dialog, location); g_free (location); } void prefs_homepage_blank_button_clicked_cb (GtkWidget *button, EphyDialog *dialog) { set_homepage_entry (dialog, ""); } static void fill_language_editor (LanguageEditor *le, PrefsDialog *dialog) { GSList *strings; GSList *tmp; GList *lang; gint i; const gchar *code; EphyLangItem *li; strings = eel_gconf_get_string_list (CONF_RENDERING_LANGUAGE); g_return_if_fail (strings != NULL); for (tmp = strings; tmp != NULL; tmp = g_slist_next (tmp)) { code = (const gchar *) tmp->data; lang = g_list_find_custom (dialog->priv->langs, code, (GCompareFunc) find_lang_code); if (lang) { i = g_list_position (dialog->priv->langs, lang); li = (EphyLangItem *) lang->data; language_editor_add (le, li->name, i); } } g_slist_foreach (strings, (GFunc) g_free, NULL); g_slist_free (strings); } static void language_dialog_changed_cb (LanguageEditor *le, GSList *list, PrefsDialog *dialog) { GtkWidget *optionmenu; const GSList *l; GSList *langs = NULL; GList *lang; gint i; EphyLangItem *li; optionmenu = ephy_dialog_get_control (EPHY_DIALOG (dialog), LANGUAGE_PROP); gtk_option_menu_set_history (GTK_OPTION_MENU(optionmenu), GPOINTER_TO_INT(list->data)); for (l = list; l != NULL; l = l->next) { i = GPOINTER_TO_INT (l->data); lang = g_list_nth (dialog->priv->langs, i); if (lang) { li = (EphyLangItem *) lang->data; langs = g_slist_append (langs, li->code); } } eel_gconf_set_string_list (CONF_RENDERING_LANGUAGE, langs); g_slist_free (langs); } void prefs_language_more_button_clicked_cb (GtkWidget *button, EphyDialog *dialog) { LanguageEditor *editor; GtkWidget *menu; GtkWidget *toplevel; menu = general_prefs_new_language_menu (EPHY_PREFS_DIALOG (dialog)); toplevel = gtk_widget_get_toplevel (button); editor = language_editor_new (toplevel); language_editor_set_menu (editor, menu); fill_language_editor (editor, EPHY_PREFS_DIALOG (dialog)); ephy_dialog_set_modal (EPHY_DIALOG(editor), TRUE); g_signal_connect (editor, "changed", G_CALLBACK(language_dialog_changed_cb), dialog); ephy_dialog_show (EPHY_DIALOG(editor)); } static void download_path_response_cb (GtkDialog *fc, gint response, EphyDialog *dialog) { if (response == EPHY_RESPONSE_OPEN) { char *dir; dir = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (fc)); if (dir != NULL) { GtkWidget *button; char *label; eel_gconf_set_string (CONF_STATE_DOWNLOAD_DIR, dir); button = ephy_dialog_get_control (dialog, DOWNLOAD_PATH_BUTTON_PROP); label = get_download_button_label (); ephy_ellipsizing_label_set_text ((EphyEllipsizingLabel*)GTK_BIN (button)->child, label); g_free (dir); g_free (label); } } gtk_widget_destroy (GTK_WIDGET (fc)); } void prefs_download_path_button_clicked_cb (GtkWidget *button, EphyDialog *dialog) { GtkWidget *parent; EphyFileChooser *fc; parent = ephy_dialog_get_control (dialog, WINDOW_PROP); fc = ephy_file_chooser_new (_("Select a directory"), GTK_WIDGET (parent), GTK_FILE_CHOOSER_ACTION_OPEN, NULL); gtk_file_chooser_set_folder_mode (GTK_FILE_CHOOSER (fc), TRUE); g_signal_connect (GTK_DIALOG (fc), "response", G_CALLBACK (download_path_response_cb), dialog); gtk_widget_show (GTK_WIDGET (fc)); }