diff options
author | Christian Persch <chpe@cvs.gnome.org> | 2003-10-18 06:40:17 +0800 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2003-10-18 06:40:17 +0800 |
commit | 0e078cd9825b89e128d0501d4a7b5885670c2347 (patch) | |
tree | 932814c057bd8d2c6cdee449dc6b267091cef6c5 /src | |
parent | 4d9d732ba340aae6430bd687f0cf3252bff2217d (diff) | |
download | gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.tar gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.tar.gz gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.tar.bz2 gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.tar.lz gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.tar.xz gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.tar.zst gsoc2013-epiphany-0e078cd9825b89e128d0501d4a7b5885670c2347.zip |
Encoding menu improvements, Part 4: The Rewrite.
2003-10-18 Christian Persch <chpe@cvs.gnome.org>
Encoding menu improvements, Part 4:
The Rewrite.
* data/glade/epiphany.glade:
* data/ui/epiphany-ui.xml:
* data/ui/nautilus-epiphany-view.xml.in:
* embed/Makefile.am:
* embed/ephy-embed-shell.c: (ephy_embed_shell_init),
(ephy_embed_shell_finalize), (ephy_embed_shell_new),
(ephy_embed_shell_get_encodings):
* embed/ephy-embed-shell.h:
* embed/ephy-embed-utils.c: (ephy_embed_utils_save):
* embed/ephy-embed-utils.h:
* embed/ephy-embed.c: (ephy_embed_get_encoding_info):
* embed/ephy-embed.h:
* embed/ephy-encodings.c: (ephy_encodings_get_type),
(ephy_encodings_finalize), (ephy_encodings_class_init),
(ephy_encodings_get_node), (ephy_encodings_get_encodings),
(ephy_encodings_get_detectors), (ephy_encodings_get_all),
(ephy_encodings_get_categories), (ephy_encodings_add_recent),
(ephy_encodings_get_recent), (ephy_encodings_init),
(ephy_encoding_info_free), (ephy_encodings_new):
* embed/ephy-encodings.h:
* embed/mozilla/EphyWrapper.cpp:
* embed/mozilla/EphyWrapper.h:
* embed/mozilla/Makefile.am:
* embed/mozilla/mozilla-embed.cpp:
* embed/mozilla/mozilla-notifiers.cpp:
* lib/Makefile.am:
* lib/ephy-encodings.c:
* lib/ephy-encodings.h:
* lib/ephy-langs.c: (ephy_font_languages), (ephy_font_n_languages):
* lib/ephy-langs.h:
* src/Makefile.am:
* src/ephy-encoding-dialog.c: (ephy_encoding_dialog_get_type),
(setup_filter), (sync_embed_cb), (sync_active_tab),
(ephy_encoding_dialog_set_window), (activate_choice),
(activate_automatic), (ephy_encoding_dialog_response_cb),
(category_node_selected_cb), (view_node_selected_cb),
(view_node_activated_cb), (ephy_encoding_dialog_init),
(ephy_encoding_dialog_finalize),
(ephy_encoding_dialog_set_property),
(ephy_encoding_dialog_get_property),
(ephy_encoding_dialog_class_init), (ephy_encoding_dialog_new):
* src/ephy-encoding-dialog.h:
* src/ephy-encoding-menu.c: (ephy_encoding_menu_init),
(sort_encodings), (add_menu_item), (update_encoding_menu_cb),
(encoding_activate_cb), (add_action),
(ephy_encoding_menu_view_dialog_cb),
(ephy_encoding_menu_automatic_cb), (ephy_encoding_menu_set_window),
(ephy_encoding_menu_finalize), (ephy_encoding_menu_class_init),
(ephy_encoding_menu_new):
* src/ephy-nautilus-view.c: (gnv_bonobo_control_activate_cb),
(gnv_cmd_select_encoding), (gnv_cmd_edit_find):
* src/ephy-window.c: (ephy_window_set_active_tab),
(setup_notebook), (ephy_window_set_property),
(ephy_window_get_property), (ephy_window_class_init):
* src/language-editor.h:
* src/pdm-dialog.c: (setup_passwords_treeview),
(setup_cookies_treeview):
* src/prefs-dialog.c: (prefs_dialog_finalize),
(get_current_language_code), (fonts_language_info_cmp),
(create_fonts_language_menu), (find_encoding_in_list_cmp),
(sort_encodings), (create_optionmenu), (prefs_dialog_init):
Made encodings menu dynamic, containing recently used items + items
related to the currently active encoding. Split encodings out as a
embed shell service, port all users over to that. Harvest all encoding
info we can get from mozilla.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/ephy-encoding-dialog.c | 489 | ||||
-rw-r--r-- | src/ephy-encoding-dialog.h | 61 | ||||
-rw-r--r-- | src/ephy-encoding-menu.c | 462 | ||||
-rw-r--r-- | src/ephy-nautilus-view.c | 46 | ||||
-rw-r--r-- | src/ephy-window.c | 94 | ||||
-rw-r--r-- | src/language-editor.h | 1 | ||||
-rwxr-xr-x | src/pdm-dialog.c | 2 | ||||
-rw-r--r-- | src/prefs-dialog.c | 282 |
9 files changed, 1062 insertions, 377 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f1cc2ad3a..7703b6b4c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,6 +50,7 @@ header_DATA = $(INST_H_FILES) NOINST_H_FILES = \ ephy-automation.h \ + ephy-encoding-dialog.h \ ephy-encoding-menu.h \ ephy-favicon-action.h \ ephy-favorites-menu.h \ @@ -83,6 +84,7 @@ epiphany_bin_SOURCES = \ ephy-automation.c \ ephy-completion-model.c \ ephy-completion-model.h \ + ephy-encoding-dialog.c \ ephy-encoding-menu.c \ ephy-favicon-action.c \ ephy-favorites-menu.c \ diff --git a/src/ephy-encoding-dialog.c b/src/ephy-encoding-dialog.c new file mode 100644 index 000000000..5f7e653a1 --- /dev/null +++ b/src/ephy-encoding-dialog.c @@ -0,0 +1,489 @@ +/* + * Copyright (C) 2000, 2001, 2002, 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch + * + * 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 "ephy-encoding-dialog.h" +#include "ephy-encodings.h" +#include "ephy-embed.h" +#include "ephy-embed-shell.h" +#include "ephy-shell.h" +#include "ephy-gui.h" +#include "ephy-node.h" +#include "ephy-node-view.h" +#include "ephy-debug.h" + +#include <gtk/gtklabel.h> +#include <gtk/gtkbutton.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtktreeselection.h> +#include <bonobo/bonobo-i18n.h> +#include <string.h> + +enum +{ + CATEGORIES_SCROLLER_PROP, + LIST_SCROLLER_PROP +}; + +static const +EphyDialogProperty properties [] = +{ + { CATEGORIES_SCROLLER_PROP, "categories_scroller", NULL, PT_NORMAL, NULL }, + { LIST_SCROLLER_PROP, "list_scroller", NULL, PT_NORMAL, NULL }, + + { -1, NULL, NULL } +}; + +#define EPHY_ENCODING_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_ENCODING_DIALOG, EphyEncodingDialogPrivate)) + +struct EphyEncodingDialogPrivate +{ + EphyEncodings *encodings; + EphyWindow *window; + EphyEmbed *embed; + GtkWidget *cat_view; + GtkWidget *enc_view; + EphyNodeFilter *filter; + EphyNode *selected_node; + gboolean update_tag; +}; + +static void ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass); +static void ephy_encoding_dialog_init (EphyEncodingDialog *ge); +void ephy_encoding_dialog_response_cb (GtkWidget *widget, + gint response, + EphyEncodingDialog *dialog); + +enum +{ + PROP_0, + PROP_WINDOW +}; + +static GObjectClass *parent_class = NULL; + +GType +ephy_encoding_dialog_get_type (void) +{ + static GType ephy_type_encoding_dialog = 0; + + if (ephy_type_encoding_dialog == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEncodingDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_encoding_dialog_class_init, + NULL, + NULL, /* class_data */ + sizeof (EphyEncodingDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_encoding_dialog_init + }; + + ephy_type_encoding_dialog = g_type_register_static (EPHY_TYPE_EMBED_DIALOG, + "EphyEncodingDialog", + &our_info, 0); + } + + return ephy_type_encoding_dialog; +} + +static void +setup_filter (EphyEncodingDialog *dialog, EphyNode *category) +{ + ephy_node_filter_empty (dialog->priv->filter); + + ephy_node_filter_add_expression (dialog->priv->filter, + ephy_node_filter_expression_new (EPHY_NODE_FILTER_EXPRESSION_HAS_PARENT, + category), + 0); + + ephy_node_filter_done_changing (dialog->priv->filter); +} + +static void +sync_embed_cb (EphyEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy) +{ + EphyEmbed *embed; + EphyEncodingInfo *info; + EphyNode *node, *categories; + gresult result; + GtkTreeSelection *selection; + GtkTreeModel *model; + GList *rows; + GPtrArray *children; + int i; + + dialog->priv->update_tag = TRUE; + + embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog)); + g_return_if_fail (EPHY_IS_EMBED (embed)); + + result = ephy_embed_get_encoding_info (embed, &info); + if (result != G_OK || info == NULL) return; + + node = ephy_encodings_get_node (dialog->priv->encodings, info->encoding); + g_return_if_fail (EPHY_IS_NODE (node)); + + /* select the correct category in the left pane ... */ + categories = ephy_encodings_get_categories (dialog->priv->encodings); + + children = ephy_node_get_children (categories); + for (i = 0; i < children->len; i++) + { + EphyNode *kid; + + kid = g_ptr_array_index (children, i); + if (ephy_node_has_child (kid, node)) + { + ephy_node_view_select_node (EPHY_NODE_VIEW (dialog->priv->cat_view), + kid); + break; + } + } + ephy_node_thaw (categories); + + /* ... and the active encoding in the right pane */ + ephy_node_view_select_node (EPHY_NODE_VIEW (dialog->priv->enc_view), + node); + + /* scroll the view so the active encoding is visible */ + selection = gtk_tree_view_get_selection + (GTK_TREE_VIEW (dialog->priv->enc_view)); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->enc_view)); + rows = gtk_tree_selection_get_selected_rows (selection, &model); + if (rows != NULL) + { + gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->priv->enc_view), + (GtkTreePath *)rows->data, + NULL, FALSE); + g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL); + g_list_free (rows); + } + + ephy_encoding_info_free (info); + + dialog->priv->update_tag = FALSE; +} + +static void +sync_active_tab (EphyWindow *window, GParamSpec *pspec, EphyEncodingDialog *dialog) +{ + EphyEmbed *embed; + + embed = ephy_window_get_active_embed (dialog->priv->window); + + g_object_set (G_OBJECT (dialog), "embed", embed, NULL); +} + +static void +ephy_encoding_dialog_set_window (EphyEncodingDialog *dialog, EphyWindow *window) +{ + g_return_if_fail (EPHY_IS_WINDOW (window)); + + dialog->priv->window = window; + + sync_active_tab (window, NULL, dialog); + g_signal_connect (G_OBJECT (window), "notify::active-tab", + G_CALLBACK (sync_active_tab), dialog); +} + +static void +activate_choice (EphyEncodingDialog *dialog) +{ + EphyEmbed *embed; + EphyEncodingInfo *info; + gresult result; + + LOG ("going manual") + + embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog)); + g_return_if_fail (EPHY_IS_EMBED (embed)); + + result = ephy_embed_get_encoding_info (embed, &info); + if (result != G_OK || info == NULL) return; + + if (dialog->priv->selected_node != NULL) + { + const char *code; + + code = ephy_node_get_property_string (dialog->priv->selected_node, + EPHY_NODE_ENCODING_PROP_ENCODING); + + /* only force it if it's different from active */ + if (info->encoding && strcmp (info->encoding, code) != 0) + { + ephy_embed_set_encoding (embed, code); + + ephy_encodings_add_recent (dialog->priv->encodings, code); + } + } + + ephy_encoding_info_free (info); +} + +static void +activate_automatic (EphyEncodingDialog *dialog) +{ + EphyEmbed *embed; + EphyEncodingInfo *info; + gresult result; + + LOG ("going automatic") + + embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog)); + g_return_if_fail (EPHY_IS_EMBED (embed)); + + result = ephy_embed_get_encoding_info (embed, &info); + if (result != G_OK || info == NULL) return; + + if ((info->forced_encoding != NULL && info->forced_encoding[0] != '\0') + || info->encoding_source >= EMBED_ENCODING_PARENT_FORCED) + { + /* clear forced encoding */ + ephy_embed_set_encoding (embed, ""); + } + + ephy_encoding_info_free (info); +} + +void +ephy_encoding_dialog_response_cb (GtkWidget *widget, + gint response, + EphyEncodingDialog *dialog) +{ + switch (response) + { + case GTK_RESPONSE_OK: + activate_choice (dialog); + break; + case -11: /* Automatic */ + activate_automatic (dialog); + break; + default: + break; + } + + g_object_unref (dialog); +} + +static void +category_node_selected_cb (EphyNodeView *view, + EphyNode *node, + EphyEncodingDialog *dialog) +{ + setup_filter (dialog, node); +} + +static void +view_node_selected_cb (EphyNodeView *view, + EphyNode *node, + EphyEncodingDialog *dialog) +{ + dialog->priv->selected_node = node; +} + +static void +view_node_activated_cb (GtkWidget *view, + EphyNode *node, + EphyEncodingDialog *dialog) +{ + dialog->priv->selected_node = node; + + if (dialog->priv->update_tag == FALSE) + { + activate_choice (dialog); + + g_object_unref (dialog); + } +} + +static void +ephy_encoding_dialog_init (EphyEncodingDialog *dialog) +{ + GtkWidget *treeview, *scroller; + GtkTreeSelection *selection; + EphyNode *node; + + dialog->priv = EPHY_ENCODING_DIALOG_GET_PRIVATE (dialog); + + dialog->priv->encodings = + EPHY_ENCODINGS (ephy_embed_shell_get_encodings + (EPHY_EMBED_SHELL (ephy_shell))); + + dialog->priv->update_tag = FALSE; + dialog->priv->selected_node = NULL; + + ephy_dialog_construct (EPHY_DIALOG (dialog), + properties, + "epiphany.glade", + "encoding_dialog"); + + node = ephy_encodings_get_categories (dialog->priv->encodings); + treeview = ephy_node_view_new (node, dialog->priv->filter); + + ephy_node_view_add_column (EPHY_NODE_VIEW (treeview), _("Location"), + G_TYPE_STRING, + EPHY_NODE_ENCODING_PROP_TITLE, + -1, + EPHY_NODE_VIEW_AUTO_SORT | + EPHY_NODE_VIEW_SEARCHABLE, + NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + + g_signal_connect (G_OBJECT (treeview), + "node_selected", + G_CALLBACK (category_node_selected_cb), + dialog); + + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), FALSE); + gtk_widget_show (treeview); + + scroller = ephy_dialog_get_control + (EPHY_DIALOG (dialog), CATEGORIES_SCROLLER_PROP); + gtk_container_add (GTK_CONTAINER (scroller), treeview); + + dialog->priv->cat_view = treeview; + + dialog->priv->filter = ephy_node_filter_new (); + + node = ephy_encodings_get_all (dialog->priv->encodings); + treeview = ephy_node_view_new (node, dialog->priv->filter); + + ephy_node_view_add_column (EPHY_NODE_VIEW (treeview), _("Encodings"), + G_TYPE_STRING, + EPHY_NODE_ENCODING_PROP_TITLE_ELIDED, + -1, + EPHY_NODE_VIEW_AUTO_SORT | + EPHY_NODE_VIEW_SEARCHABLE, + NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), FALSE); + + g_signal_connect (G_OBJECT (treeview), + "node_selected", + G_CALLBACK (view_node_selected_cb), + dialog); + g_signal_connect (G_OBJECT (treeview), + "node_activated", + G_CALLBACK (view_node_activated_cb), + dialog); + + gtk_widget_show (treeview); + + scroller = ephy_dialog_get_control + (EPHY_DIALOG (dialog), LIST_SCROLLER_PROP); + gtk_container_add (GTK_CONTAINER (scroller), treeview); + + dialog->priv->enc_view = treeview; + + g_signal_connect (G_OBJECT (dialog), "notify::embed", + G_CALLBACK (sync_embed_cb), NULL); +} + +static void +ephy_encoding_dialog_finalize (GObject *object) +{ + EphyEncodingDialog *dialog = EPHY_ENCODING_DIALOG (object); + + if (dialog->priv->window != NULL) + { + g_signal_handlers_disconnect_by_func (dialog->priv->window, + G_CALLBACK (sync_active_tab), + dialog); + } + + g_object_unref (dialog->priv->filter); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_encoding_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEncodingDialog *dialog = EPHY_ENCODING_DIALOG (object); + + switch (prop_id) + { + case PROP_WINDOW: + ephy_encoding_dialog_set_window (dialog, g_value_get_object (value)); + break; + } +} + +static void +ephy_encoding_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEncodingDialog *dialog = EPHY_ENCODING_DIALOG (object); + + switch (prop_id) + { + case PROP_WINDOW: + g_value_set_object (value, dialog->priv->window); + break; + } +} + +static void +ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_encoding_dialog_finalize; + object_class->get_property = ephy_encoding_dialog_get_property; + object_class->set_property = ephy_encoding_dialog_set_property; + + g_object_class_install_property (object_class, + PROP_WINDOW, + g_param_spec_object ("window", + "Window", + "Parent window", + EPHY_TYPE_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (object_class, sizeof(EphyEncodingDialogPrivate)); +} + +EphyEncodingDialog * +ephy_encoding_dialog_new (EphyWindow *parent) +{ + return g_object_new (EPHY_TYPE_ENCODING_DIALOG, + "window", parent, + NULL); +} diff --git a/src/ephy-encoding-dialog.h b/src/ephy-encoding-dialog.h new file mode 100644 index 000000000..b95b783a3 --- /dev/null +++ b/src/ephy-encoding-dialog.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2000, 2001, 2002, 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch + * + * 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$ + */ + +#ifndef EPHY_ENCODING_DIALOG_H +#define EPHY_ENCODING_DIALOG_H + +#include "ephy-embed-dialog.h" +#include "ephy-window.h" + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_ENCODING_DIALOG (ephy_encoding_dialog_get_type ()) +#define EPHY_ENCODING_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_ENCODING_DIALOG, EphyEncodingDialog)) +#define EPHY_ENCODING_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_ENCODING_DIALOG, EphyEncodingDialogClass)) +#define EPHY_IS_ENCODING_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_ENCODING_DIALOG)) +#define EPHY_IS_ENCODING_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_ENCODING_DIALOG)) +#define EPHY_ENCODING_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_ENCODING_DIALOG, EphyEncodingDialogClass)) + +typedef struct EphyEncodingDialog EphyEncodingDialog; +typedef struct EphyEncodingDialogClass EphyEncodingDialogClass; +typedef struct EphyEncodingDialogPrivate EphyEncodingDialogPrivate; + +struct EphyEncodingDialog +{ + EphyEmbedDialog parent; + EphyEncodingDialogPrivate *priv; +}; + +struct EphyEncodingDialogClass +{ + EphyEmbedDialogClass parent_class; +}; + +GType ephy_encoding_dialog_get_type (void); + +EphyEncodingDialog *ephy_encoding_dialog_new (EphyWindow *window); + +G_END_DECLS + +#endif diff --git a/src/ephy-encoding-menu.c b/src/ephy-encoding-menu.c index 0773a9fc5..312ba5a2f 100644 --- a/src/ephy-encoding-menu.c +++ b/src/ephy-encoding-menu.c @@ -25,35 +25,39 @@ #endif #include "ephy-encoding-menu.h" -#include "ephy-langs.h" +#include "ephy-encoding-dialog.h" #include "ephy-encodings.h" +#include "ephy-embed.h" +#include "ephy-embed-shell.h" +#include "ephy-shell.h" #include "ephy-string.h" #include "ephy-debug.h" -#include <bonobo/bonobo-i18n.h> #include <gtk/gtkaction.h> #include <gtk/gtktoggleaction.h> #include <gtk/gtkradioaction.h> #include <gtk/gtkuimanager.h> +#include <bonobo/bonobo-i18n.h> #include <string.h> #define EPHY_ENCODING_MENU_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_ENCODING_MENU, EphyEncodingMenuPrivate)) struct _EphyEncodingMenuPrivate { + EphyEncodings *encodings; EphyWindow *window; GtkUIManager *manager; GtkActionGroup *action_group; gboolean update_tag; guint merge_id; + GSList *encodings_radio_group; + EphyEncodingDialog *dialog; }; -#define ENCODING_PLACEHOLDER_PATH "/menubar/ViewMenu/ViewEncodingsPlaceholder" -#define ENCODING_MENU_PATH "/menubar/ViewMenu/ViewEncodingsPlaceholder/ViewEncodingMenu" +#define ENCODING_PLACEHOLDER_PATH "/menubar/ViewMenu/ViewEncodingMenu/ViewEncodingPlaceholder" -static void ephy_encoding_menu_class_init (EphyEncodingMenuClass *klass); -static void ephy_encoding_menu_init (EphyEncodingMenu *menu); -static void ephy_encoding_menu_rebuild (EphyEncodingMenu *menu); +static void ephy_encoding_menu_class_init (EphyEncodingMenuClass *klass); +static void ephy_encoding_menu_init (EphyEncodingMenu *menu); enum { @@ -92,93 +96,314 @@ ephy_encoding_menu_get_type (void) } static void -ephy_encoding_menu_verb_cb (GtkAction *action, - EphyEncodingMenu *menu) +ephy_encoding_menu_init (EphyEncodingMenu *menu) +{ + menu->priv = EPHY_ENCODING_MENU_GET_PRIVATE (menu); + + menu->priv->encodings = + EPHY_ENCODINGS (ephy_embed_shell_get_encodings + (EPHY_EMBED_SHELL (ephy_shell))); + + menu->priv->update_tag = FALSE; + menu->priv->action_group = NULL; + menu->priv->merge_id = 0; + menu->priv->encodings_radio_group = NULL; + menu->priv->dialog = NULL; +} + +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 void +add_menu_item (EphyNode *node, EphyEncodingMenu *menu) +{ + const char *code; + char action[128], name[128]; + + code = ephy_node_get_property_string + (node, EPHY_NODE_ENCODING_PROP_ENCODING); + + g_snprintf (action, sizeof (action), "Encoding%s", code); + g_snprintf (name, sizeof (name), "%sItem", action); + + gtk_ui_manager_add_ui (menu->priv->manager, menu->priv->merge_id, + ENCODING_PLACEHOLDER_PATH, + name, action, + GTK_UI_MANAGER_MENUITEM, FALSE); +} + +static void +update_encoding_menu_cb (GtkAction *dummy, EphyEncodingMenu *menu) { + EphyEncodingMenuPrivate *p = menu->priv; EphyEmbed *embed; + GtkAction *action; + EphyEncodingInfo *info = NULL; + char name[128]; const char *encoding; - const char *action_name; + EphyNode *enc_node; + GList *recent, *related = NULL, *l; + EphyLanguageGroup groups; + gboolean is_automatic; + gresult result; - /* do nothing if this action was _de_activated, or if we're updating - * the menu, i.e. setting the active encoding from the document + START_PROFILER ("Rebuilding encoding menu") + + /* FIXME: block the "activate" signal on the actions instead; needs to + * wait until g_signal_handlers_block_matched supports blocking + * by signal id alone. */ - if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) == FALSE - || menu->priv->update_tag) + menu->priv->update_tag = TRUE; + + /* get most recently used encodings */ + recent = ephy_encodings_get_recent (p->encodings); + + embed = ephy_window_get_active_embed (p->window); + result = ephy_embed_get_encoding_info (embed, &info); + if (result != G_OK || info == NULL) goto build_menu; + + LOG ("encoding information\n enc='%s' default='%s' hint='%s' " + "prev_doc='%s' forced='%s' parent='%s' source=%d " + "hint_source=%d parent_source=%d", info->encoding, + info->default_encoding, info->hint_encoding, + info->prev_doc_encoding, info->forced_encoding, + info->parent_encoding, info->encoding_source, + info->hint_encoding_source, info->parent_encoding_source) + + encoding = info->encoding; + + enc_node = ephy_encodings_get_node (p->encodings, encoding); + if (!EPHY_IS_NODE (enc_node)) { - return; + g_warning ("Encountered unknown encoding '%s'" + ". Please file a bug at http://bugzilla.gnome.o" + "rg/enter_bug.cgi?product=epiphany\n", + encoding); + + goto build_menu; } - embed = ephy_window_get_active_embed (menu->priv->window); - g_return_if_fail (embed != NULL); + /* set the encodings group's active member */ + g_snprintf (name, sizeof (name), "Encoding%s", encoding); + action = gtk_action_group_get_action (p->action_group, name); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); + + /* check if encoding was overridden */ + is_automatic = (info->encoding_source < EMBED_ENCODING_PARENT_FORCED); - action_name = gtk_action_get_name (action); + action = gtk_action_group_get_action (p->action_group, + "ViewEncodingAutomatic"); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), is_automatic); + g_object_set (G_OBJECT (action), "sensitive", !is_automatic, NULL); - if (strncmp (action_name, "Encoding", 8) == 0) + /* get encodings related to the current encoding */ + groups = ephy_node_get_property_int + (enc_node, EPHY_NODE_ENCODING_PROP_LANGUAGE_GROUPS); + + related = ephy_encodings_get_encodings (p->encodings, groups); + related = g_list_sort (related, (GCompareFunc) sort_encodings); + + /* add the current encoding to the list of + * things to display, making sure we don't add it more than once + */ + if (g_list_find (related, enc_node) == NULL + && g_list_find (recent, enc_node) == NULL) + { + recent = g_list_prepend (recent, enc_node); + } + + /* make sure related and recent are disjoint so we don't display twice */ + for (l = related; l != NULL; l = l->next) { - encoding = action_name + 8; + recent = g_list_remove (recent, l->data); + } - LOG ("Switching to encoding %s", encoding) + recent = g_list_sort (recent, (GCompareFunc) sort_encodings); - ephy_embed_set_encoding (embed, encoding); +build_menu: + /* clear the menu */ + if (p->merge_id > 0) + { + gtk_ui_manager_remove_ui (p->manager, p->merge_id); + gtk_ui_manager_ensure_update (p->manager); } -} -static void -ephy_encoding_menu_init (EphyEncodingMenu *menu) -{ - menu->priv = EPHY_ENCODING_MENU_GET_PRIVATE (menu); + /* build the new menu */ + p->merge_id = gtk_ui_manager_new_merge_id (p->manager); + + gtk_ui_manager_add_ui (p->manager, p->merge_id, + ENCODING_PLACEHOLDER_PATH, + "ViewEncodingAutomaticItem", + "ViewEncodingAutomatic", + GTK_UI_MANAGER_MENUITEM, FALSE); + + gtk_ui_manager_add_ui (p->manager, p->merge_id, + ENCODING_PLACEHOLDER_PATH, + "Sep1Item", "Sep1", + GTK_UI_MANAGER_SEPARATOR, FALSE); + + g_list_foreach (recent, (GFunc) add_menu_item, menu); + + gtk_ui_manager_add_ui (p->manager, p->merge_id, + ENCODING_PLACEHOLDER_PATH, + "Sep2Item", "Sep2", + GTK_UI_MANAGER_SEPARATOR, FALSE); + + g_list_foreach (related, (GFunc) add_menu_item, menu); + + gtk_ui_manager_add_ui (p->manager, p->merge_id, + ENCODING_PLACEHOLDER_PATH, + "Sep3Item", "Sep3", + GTK_UI_MANAGER_SEPARATOR, FALSE); + + gtk_ui_manager_add_ui (p->manager, p->merge_id, + ENCODING_PLACEHOLDER_PATH, + "ViewEncodingOtherItem", + "ViewEncodingOther", + GTK_UI_MANAGER_MENUITEM, FALSE); + + /* cleanup */ + g_list_free (related); + g_list_free (recent); + + ephy_encoding_info_free (info); menu->priv->update_tag = FALSE; - menu->priv->action_group = NULL; - menu->priv->merge_id = 0; + + STOP_PROFILER ("Rebuilding encoding menu") } static void -update_encoding_menu_cb (GtkAction *dummy, EphyEncodingMenu *menu) +encoding_activate_cb (GtkAction *action, EphyEncodingMenu *menu) { EphyEmbed *embed; - GtkAction *action = NULL; - char *encoding; + EphyEncodingInfo *info; + const char *name, *encoding; + gresult result; + + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) == FALSE + || menu->priv->update_tag) + { + return; + } + + name = gtk_action_get_name (GTK_ACTION (action)); + encoding = name + strlen("Encoding"); embed = ephy_window_get_active_embed (menu->priv->window); - g_return_if_fail (embed != NULL); - ephy_embed_get_encoding (embed, &encoding); + result = ephy_embed_get_encoding_info (embed, &info); + if (result != G_OK || info == NULL) return; - if (encoding != NULL) + /* Force only when different from current encoding */ + if (info->encoding && strcmp (info->encoding, encoding) != 0) { - char name[32]; - - g_snprintf (name, 32, "Encoding%s", encoding); - action = gtk_action_group_get_action (menu->priv->action_group, - name); + ephy_embed_set_encoding (embed, encoding); } - if (action != NULL) + ephy_encoding_info_free (info); + + ephy_encodings_add_recent (menu->priv->encodings, encoding); +} + +static void +add_action (EphyNode *node, EphyEncodingMenu *menu) +{ + GtkAction *action; + char name[128]; + const char *encoding, *title; + + encoding = ephy_node_get_property_string + (node, EPHY_NODE_ENCODING_PROP_ENCODING); + title = ephy_node_get_property_string + (node, EPHY_NODE_ENCODING_PROP_TITLE); + + g_snprintf (name, sizeof (name), "Encoding%s", encoding); + + action = g_object_new (GTK_TYPE_RADIO_ACTION, + "name", name, + "label", title, + NULL); + + gtk_radio_action_set_group (GTK_RADIO_ACTION (action), + menu->priv->encodings_radio_group); + menu->priv->encodings_radio_group = gtk_radio_action_get_group + (GTK_RADIO_ACTION (action)); + + g_signal_connect (action, "activate", + G_CALLBACK (encoding_activate_cb), + menu); + + gtk_action_group_add_action (menu->priv->action_group, action); + g_object_unref (action); +} + +static void +ephy_encoding_menu_view_dialog_cb (GtkAction *action, EphyEncodingMenu *menu) +{ + if (menu->priv->dialog == NULL) { - /* FIXME: block the "activate" signal instead; needs to wait - * until g_signal_handlers_block_matched supports blocking - * by signal id alone. - */ - menu->priv->update_tag = TRUE; - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); - menu->priv->update_tag = FALSE; + menu->priv->dialog = ephy_encoding_dialog_new + (menu->priv->window); + + g_object_add_weak_pointer(G_OBJECT (menu->priv->dialog), + (gpointer *) &menu->priv->dialog); } - else + + ephy_dialog_show (EPHY_DIALOG (menu->priv->dialog)); +} + +static void +ephy_encoding_menu_automatic_cb (GtkAction *action, EphyEncodingMenu *menu) +{ + EphyEmbed *embed; + + if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) == FALSE + || menu->priv->update_tag) { - g_warning ("Could not find action for encoding '%s'!\n", encoding); + return; } - g_free (encoding); + embed = ephy_window_get_active_embed (menu->priv->window); + + /* setting "" will clear the forced encoding */ + ephy_embed_set_encoding (embed, ""); } +static GtkActionEntry menu_entries [] = +{ + { "ViewEncodingOther", NULL, N_("_Other..."), NULL, + N_("Other encodings"), + G_CALLBACK (ephy_encoding_menu_view_dialog_cb) } +}; +static guint n_menu_entries = G_N_ELEMENTS (menu_entries); + +static GtkToggleActionEntry toggle_menu_entries [] = +{ + { "ViewEncodingAutomatic", NULL, N_("_Automatic"), NULL, + N_("Use the encoding specified by the document"), + G_CALLBACK (ephy_encoding_menu_automatic_cb), FALSE } +}; +static const guint n_toggle_menu_entries = G_N_ELEMENTS (toggle_menu_entries); + static void ephy_encoding_menu_set_window (EphyEncodingMenu *menu, EphyWindow *window) { GtkActionGroup *action_group; GtkAction *action; - GList *encodings, *groups, *l; - GSList *radio_group = NULL; + GList *encodings; g_return_if_fail (EPHY_IS_WINDOW (window)); @@ -186,52 +411,17 @@ ephy_encoding_menu_set_window (EphyEncodingMenu *menu, EphyWindow *window) menu->priv->manager = GTK_UI_MANAGER (window->ui_merge); action_group = gtk_action_group_new ("EncodingActions"); + gtk_action_group_set_translation_domain (action_group, NULL); menu->priv->action_group = action_group; - encodings = ephy_encodings_get_list (LG_ALL, FALSE); - for (l = encodings; l != NULL; l = l->next) - { - const EphyEncodingInfo *info = (EphyEncodingInfo *) l->data; - char name[32]; - - g_snprintf (name, 32, "Encoding%s", info->encoding); - action = g_object_new (GTK_TYPE_RADIO_ACTION, - "name", name, - "label", info->title, - NULL); - - gtk_radio_action_set_group (GTK_RADIO_ACTION (action), radio_group); - radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (action)); - - g_signal_connect (action, "activate", - G_CALLBACK (ephy_encoding_menu_verb_cb), - menu); - - gtk_action_group_add_action (menu->priv->action_group, action); - g_object_unref (action); - } - - g_list_foreach (encodings, (GFunc) ephy_encoding_info_free, NULL); - g_list_free (encodings); + gtk_action_group_add_actions (action_group, menu_entries, + n_menu_entries, menu); + gtk_action_group_add_toggle_actions (action_group, toggle_menu_entries, + n_toggle_menu_entries, menu); - groups = ephy_lang_get_group_list (); - for (l = groups; l != NULL; l = l->next) - { - const EphyLanguageGroupInfo *info = (EphyLanguageGroupInfo *) l->data; - char name[32]; - - g_snprintf (name, 32, "EncodingGroup%d", info->group); - - action = g_object_new (GTK_TYPE_ACTION, - "name", name, - "label", info->title, - NULL); - gtk_action_group_add_action (menu->priv->action_group, action); - g_object_unref (action); - } - - g_list_foreach (groups, (GFunc) ephy_lang_group_info_free, NULL); - g_list_free (groups); + encodings = ephy_encodings_get_encodings (menu->priv->encodings, LG_ALL); + g_list_foreach (encodings, (GFunc) add_action, menu); + g_list_free (encodings); gtk_ui_manager_insert_action_group (menu->priv->manager, action_group, 0); @@ -239,14 +429,9 @@ ephy_encoding_menu_set_window (EphyEncodingMenu *menu, EphyWindow *window) action = gtk_ui_manager_get_action (menu->priv->manager, "/menubar/ViewMenu"); - if (action != NULL) - { - g_signal_connect_object (action, "activate", - G_CALLBACK (update_encoding_menu_cb), - menu, 0); - } - - ephy_encoding_menu_rebuild (menu); + g_signal_connect_object (action, "activate", + G_CALLBACK (update_encoding_menu_cb), + menu, 0); } static void @@ -282,12 +467,26 @@ ephy_encoding_menu_get_property (GObject *object, } static void +ephy_encoding_menu_finalize (GObject *object) +{ + EphyEncodingMenu *menu = EPHY_ENCODING_MENU (object); + + if (menu->priv->dialog) + { + g_object_unref (menu->priv->dialog); + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void ephy_encoding_menu_class_init (EphyEncodingMenuClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); + object_class->finalize = ephy_encoding_menu_finalize; object_class->set_property = ephy_encoding_menu_set_property; object_class->get_property = ephy_encoding_menu_get_property; @@ -310,58 +509,3 @@ ephy_encoding_menu_new (EphyWindow *window) "window", window, NULL); } - -static void -ephy_encoding_menu_rebuild (EphyEncodingMenu *menu) -{ - EphyEncodingMenuPrivate *p = menu->priv; - GList *groups, *l; - - if (p->merge_id > 0) - { - gtk_ui_manager_remove_ui (p->manager, p->merge_id); - gtk_ui_manager_ensure_update (p->manager); - } - - p->merge_id = gtk_ui_manager_new_merge_id (p->manager); - - gtk_ui_manager_add_ui (p->manager, p->merge_id, ENCODING_PLACEHOLDER_PATH, - "ViewEncodingMenu", "ViewEncoding", - GTK_UI_MANAGER_MENU, FALSE); - - groups = ephy_lang_get_group_list (); - for (l = groups; l != NULL; l = l->next) - { - const EphyLanguageGroupInfo *info = (EphyLanguageGroupInfo *) l->data; - char name[32], action[36], path[128]; - GList *encodings, *enc; - - g_snprintf (action, 32, "EncodingGroup%d", info->group); - g_snprintf (name, 36, "%sMenu", action); - g_snprintf (path, 128, "%s/%s", ENCODING_MENU_PATH, name); - - gtk_ui_manager_add_ui (p->manager, p->merge_id, - ENCODING_MENU_PATH, - name, action, - GTK_UI_MANAGER_MENU, FALSE); - - encodings = ephy_encodings_get_list (info->group, FALSE); - for (enc = encodings; enc != NULL; enc = enc->next) - { - const EphyEncodingInfo *info = (EphyEncodingInfo *) enc->data; - - g_snprintf (action, 32, "Encoding%s", info->encoding); - g_snprintf (name, 36, "%sItem", action); - - gtk_ui_manager_add_ui (p->manager, p->merge_id, path, - name, action, - GTK_UI_MANAGER_MENUITEM, FALSE); - } - - g_list_foreach (encodings, (GFunc) ephy_encoding_info_free, NULL); - g_list_free (encodings); - } - - g_list_foreach (groups, (GFunc) ephy_lang_group_info_free, NULL); - g_list_free (groups); -} diff --git a/src/ephy-nautilus-view.c b/src/ephy-nautilus-view.c index 6c60be01a..fd2ec0a2d 100644 --- a/src/ephy-nautilus-view.c +++ b/src/ephy-nautilus-view.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2001, 2002 Ricardo Fernández Pascual + * Copyright (C) 2003 Marco Pesenti Gritti + * Copyright (C) 2003 Christian Persch * * 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 @@ -31,6 +33,7 @@ #include "ephy-embed-utils.h" #include "find-dialog.h" #include "print-dialog.h" +#include "ephy-encoding-dialog.h" #include "ephy-zoom.h" #include "ephy-debug.h" @@ -79,16 +82,15 @@ static void gnv_zoomable_zoom_to_fit_cb (BonoboZoomable *zoomable, static void gnv_zoomable_zoom_to_default_cb (BonoboZoomable *zoomable, EphyNautilusView *view); /* commands */ -static void gnv_cmd_set_encoding (BonoboUIComponent *uic, - EphyNautilusView *view, - const char* verbname); static void gnv_cmd_file_print (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname); static void gnv_cmd_edit_find (BonoboUIComponent *uic, EphyNautilusView *view, const char* verbname); - +static void gnv_cmd_select_encoding (BonoboUIComponent *uic, + EphyNautilusView *view, + const char* verbname); /* popups */ static EphyNautilusView *gnv_view_from_popup (EphyEmbedPopupControl*popup); @@ -131,12 +133,10 @@ static BonoboUIVerb ephy_popup_verbs [] = { BonoboUIVerb ephy_verbs [] = { BONOBO_UI_VERB ("FilePrint", (BonoboUIVerbFn) gnv_cmd_file_print), BONOBO_UI_VERB ("EditFind", (BonoboUIVerbFn) gnv_cmd_edit_find), + BONOBO_UI_VERB ("ViewEncoding", (BonoboUIVerbFn) gnv_cmd_select_encoding), BONOBO_UI_VERB_END }; -#define ENCODING_MENU_PATH "/menu/View/Encoding" - - BONOBO_CLASS_BOILERPLATE (EphyNautilusView, ephy_nautilus_view, NautilusView, NAUTILUS_TYPE_VIEW) @@ -434,11 +434,6 @@ gnv_bonobo_control_activate_cb (BonoboControl *control, gboolean state, EphyNaut p->ui = nautilus_view_set_up_ui (NAUTILUS_VIEW (view), SHARE_DIR, "nautilus-epiphany-view.xml", "EphyNautilusView"); g_return_if_fail (BONOBO_IS_UI_COMPONENT (p->ui)); - - ephy_embed_utils_build_encodings_submenu (p->ui, - ENCODING_MENU_PATH, - (BonoboUIVerbFn) gnv_cmd_set_encoding, - view); bonobo_ui_component_add_verb_list_with_data (p->ui, ephy_verbs, view); } @@ -509,23 +504,19 @@ gnv_popup_cmd_frame_in_new_window (BonoboUIComponent *uic, g_free (location); } -void -gnv_cmd_set_encoding (BonoboUIComponent *uic, - EphyNautilusView *view, - const char* verbname) +static void +gnv_cmd_select_encoding (BonoboUIComponent *uic, + EphyNautilusView *view, + const char* verbname) { - const char *encoding; - - g_return_if_fail (EPHY_IS_NAUTILUS_VIEW (view)); - - if (strncmp (verbname, "Encoding", 8) == 0) - { - encoding = verbname + 8; - - LOG ("Set encoding %s", encoding) + EphyDialog *dialog; + + dialog = EPHY_DIALOG (g_object_new (EPHY_TYPE_ENCODING_DIALOG, + "embed", view->priv->embed, + NULL)); - ephy_embed_set_encoding (view->priv->embed, encoding); - } + ephy_dialog_set_modal (dialog, TRUE); + ephy_dialog_show (dialog); } static void @@ -558,7 +549,6 @@ gnv_cmd_edit_find (BonoboUIComponent *uic, ephy_dialog_show (p->find_dialog); } - /* zoomable */ static void gnv_zoomable_set_zoom_level_cb (BonoboZoomable *zoomable, diff --git a/src/ephy-window.c b/src/ephy-window.c index 5462ae72e..c36a1c541 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * Copyright (C) 2000, 2001, 2002, 2003 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 @@ -19,7 +19,7 @@ */ #ifdef HAVE_CONFIG_H -#include <config.h> +#include "config.h" #endif #include "ephy-window.h" @@ -139,7 +139,9 @@ static GtkActionEntry ephy_menu_entries [] = { { "ViewZoomNormal", GTK_STOCK_ZOOM_100, N_("_Normal Size"), NULL, N_("Use the normal text size"), G_CALLBACK (window_cmd_view_zoom_normal) }, - { "ViewEncoding", NULL, N_("_Encoding") }, + { "ViewEncoding", NULL, N_("Text _Encoding"), NULL, + N_("Change the text encoding"), + NULL }, { "ViewPageSource", EPHY_STOCK_VIEWSOURCE, N_("_Page Source"), "<control>U", N_("View the source code of the page"), G_CALLBACK (window_cmd_view_page_source) }, @@ -304,6 +306,12 @@ ephy_window_notebook_switch_page_cb (GtkNotebook *notebook, guint page_num, EphyWindow *window); +enum +{ + PROP_0, + PROP_ACTIVE_TAB +}; + static GObjectClass *parent_class = NULL; GType @@ -368,24 +376,6 @@ ephy_window_destroy (GtkObject *gtkobject) } static void -ephy_window_class_init (EphyWindowClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ephy_window_finalize; - - widget_class->show = ephy_window_show; - - gtkobject_class->destroy = ephy_window_destroy; - - g_type_class_add_private (object_class, sizeof(EphyWindowPrivate)); -} - -static void ephy_window_selection_received_cb (GtkWidget *widget, GtkSelectionData *selection_data, guint time, EphyWindow *window) @@ -1184,6 +1174,8 @@ ephy_window_set_active_tab (EphyWindow *window, EphyTab *new_tab) action = GTK_TOGGLE_ACTION (ephy_tab_get_action (new_tab)); gtk_toggle_action_set_active (action, TRUE); + + g_object_notify (G_OBJECT (window), "active-tab"); } } @@ -1312,6 +1304,66 @@ setup_notebook (EphyWindow *window) } static void +ephy_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyWindow *window = EPHY_WINDOW (object); + + switch (prop_id) + { + case PROP_ACTIVE_TAB: + ephy_window_set_active_tab (window, g_value_get_object (value)); + break; + } +} + +static void +ephy_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyWindow *window = EPHY_WINDOW (object); + + switch (prop_id) + { + case PROP_ACTIVE_TAB: + g_value_set_object (value, window->priv->active_tab); + break; + } +} + +static void +ephy_window_class_init (EphyWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_window_finalize; + object_class->get_property = ephy_window_get_property; + object_class->set_property = ephy_window_set_property; + + gtkobject_class->destroy = ephy_window_destroy; + + widget_class->show = ephy_window_show; + + g_object_class_install_property (object_class, + PROP_ACTIVE_TAB, + g_param_spec_object ("active-tab", + "active-tab", + "Active tab", + EPHY_TYPE_TAB, + G_PARAM_READWRITE)); + + g_type_class_add_private (object_class, sizeof(EphyWindowPrivate)); +} + +static void ephy_window_init (EphyWindow *window) { Session *session; diff --git a/src/language-editor.h b/src/language-editor.h index 536d16eb8..61e22347a 100644 --- a/src/language-editor.h +++ b/src/language-editor.h @@ -20,7 +20,6 @@ #define LANGUAGE_EDITOR_H #include "ephy-dialog.h" -#include "language-editor.h" #include <gtk/gtkwidget.h> #include <glib-object.h> diff --git a/src/pdm-dialog.c b/src/pdm-dialog.c index b57cde4d4..3becb2d84 100755 --- a/src/pdm-dialog.c +++ b/src/pdm-dialog.c @@ -249,6 +249,7 @@ setup_passwords_treeview (PdmDialog *dialog) gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore), COL_PASSWORDS_HOST, GTK_SORT_ASCENDING); + g_object_unref (liststore); renderer = gtk_cell_renderer_text_new (); @@ -305,6 +306,7 @@ setup_cookies_treeview (PdmDialog *dialog) gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore), COL_COOKIES_HOST, GTK_SORT_ASCENDING); + g_object_unref (liststore); g_signal_connect (selection, "changed", G_CALLBACK(cookies_treeview_selection_changed_cb), diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c index 1b0999956..0b297374f 100644 --- a/src/prefs-dialog.c +++ b/src/prefs-dialog.c @@ -25,6 +25,8 @@ #include "prefs-dialog.h" #include "ephy-dialog.h" #include "ephy-prefs.h" +#include "ephy-embed-shell.h" +#include "ephy-shell.h" #include "ephy-embed-prefs.h" #include "ephy-embed-single.h" #include "ephy-shell.h" @@ -33,6 +35,7 @@ #include "language-editor.h" #include "ephy-langs.h" #include "ephy-encodings.h" +#include "ephy-debug.h" #include <bonobo/bonobo-i18n.h> #include <gtk/gtkframe.h> @@ -148,27 +151,6 @@ languages [] = }; static guint n_languages = G_N_ELEMENTS (languages); -typedef struct -{ - gchar *title; - gchar *name; -} EncodingAutodetectorInfo; - -static EncodingAutodetectorInfo encoding_autodetector[] = -{ - { N_("Off"), "" }, - { N_("Chinese"), "zh_parallel_state_machine" }, - { N_("East Asian"), "cjk_parallel_state_machine" }, - { N_("Japanese"), "ja_parallel_state_machine" }, - { N_("Korean"), "ko_parallel_state_machine" }, - { N_("Russian"), "ruprob" }, - { N_("Simplified Chinese"), "zhcn_parallel_state_machine" }, - { N_("Traditional Chinese"), "zhtw_parallel_state_machine" }, - { N_("Universal"), "universal_charset_detector" }, - { N_("Ukrainian"), "ukprob" } -}; -static guint n_encoding_autodetectors = G_N_ELEMENTS (encoding_autodetector); - static const char *cookies_accept_enum [] = { @@ -267,8 +249,8 @@ EphyDialogProperty properties [] = { DISK_CACHE_PROP, "disk_cache_spin", CONF_NETWORK_CACHE_SIZE, PT_AUTOAPPLY, NULL }, /* Languages */ - { AUTO_ENCODING_PROP, "auto_encoding_optionmenu", NULL, PT_NORMAL, NULL }, - { DEFAULT_ENCODING_PROP, "default_encoding_optionmenu", NULL, PT_NORMAL, NULL }, + { 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 }, @@ -301,8 +283,6 @@ struct PrefsDialogPrivate GtkWidget *window; GList *langs; - GList *encodings; - GList *autodetectors; GList *fonts_languages; guint language; @@ -383,12 +363,6 @@ prefs_dialog_finalize (GObject *object) g_list_foreach (pd->priv->langs, (GFunc) free_lang_item, NULL); g_list_free (pd->priv->langs); - g_list_foreach (pd->priv->encodings, (GFunc) ephy_encoding_info_free, NULL); - g_list_free (pd->priv->encodings); - - g_list_foreach (pd->priv->autodetectors, (GFunc) g_free, NULL); - g_list_free (pd->priv->autodetectors); - g_list_foreach (pd->priv->fonts_languages, (GFunc) g_free, NULL); g_list_free (pd->priv->fonts_languages); @@ -415,15 +389,15 @@ prefs_dialog_show_help (PrefsDialog *pd) ephy_gui_help (GTK_WINDOW (pd->priv->window), "epiphany", help_preferences[id]); } -static const gchar * +static const char * get_current_language_code (PrefsDialog *dialog) { GList *lang; - const FontsLanguageInfo *info; + const EphyFontsLanguageInfo *info; lang = g_list_nth (dialog->priv->fonts_languages, dialog->priv->language); g_assert (lang != NULL); - info = (FontsLanguageInfo *) lang->data; + info = (EphyFontsLanguageInfo *) lang->data; return info->code; } @@ -648,24 +622,47 @@ setup_fonts (PrefsDialog *dialog) 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 *l = NULL; - guint n_fonts_languages, i = 0; + 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 (); - dialog->priv->fonts_languages = ephy_font_langs_get_list (); - n_fonts_languages = g_list_length (dialog->priv->fonts_languages); + 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) { - FontsLanguageInfo *info = (FontsLanguageInfo *) l->data; + EphyFontsLanguageInfo *info = (EphyFontsLanguageInfo *) l->data; GtkWidget *item; item = gtk_menu_item_new_with_label (info->title); @@ -676,12 +673,12 @@ create_fonts_language_menu (PrefsDialog *dialog) gtk_option_menu_set_menu (GTK_OPTION_MENU(optionmenu), menu); lang_codes = g_new0 (char *, n_fonts_languages); - for (l = dialog->priv->fonts_languages; l != NULL; l = l->next) + for (l = dialog->priv->fonts_languages, i=0; l != NULL; l = l->next) { - FontsLanguageInfo *info = (FontsLanguageInfo *) l->data; + EphyFontsLanguageInfo *info = (EphyFontsLanguageInfo *) l->data; lang_codes[i] = info->code; - + i++; } ephy_dialog_add_enum (EPHY_DIALOG (dialog), FONTS_LANGUAGE_PROP, @@ -697,160 +694,97 @@ create_fonts_language_menu (PrefsDialog *dialog) dialog); } -static void -default_encoding_menu_changed_cb (GtkOptionMenu *option_menu, - PrefsDialog *dialog) +static int +find_encoding_in_list_cmp (gconstpointer info, const char *encoding) { - GList *encoding; - gint i; - const EphyEncodingInfo *info; + EphyNode *node = (EphyNode *) info; + const char *code; - i = gtk_option_menu_get_history (option_menu); - encoding = g_list_nth (dialog->priv->encodings, i); - g_assert (encoding != NULL); + code = ephy_node_get_property_string + (node, EPHY_NODE_ENCODING_PROP_ENCODING); - info = (EphyEncodingInfo *) encoding->data; - eel_gconf_set_string (CONF_LANGUAGE_DEFAULT_ENCODING, info->encoding); + return strcmp (code, encoding); } -static gint -find_encoding_in_list_cmp (const EphyEncodingInfo *info, const char *encoding) +static int +sort_encodings (gconstpointer a, gconstpointer b) { - return strcmp (info->encoding, encoding); + 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 void -create_default_encoding_menu (PrefsDialog *dialog) +create_optionmenu (PrefsDialog *dialog, + int property, + GList *list, + const char *key, + const char *default_value) { - GList *l; + GList *element, *l; GtkWidget *menu, *optionmenu; - gchar *encoding; + char *value; + char **codes; + guint pos, i, num; menu = gtk_menu_new (); optionmenu = ephy_dialog_get_control (EPHY_DIALOG (dialog), - DEFAULT_ENCODING_PROP); - - dialog->priv->encodings = ephy_encodings_get_list (LG_ALL, TRUE); - for (l = dialog->priv->encodings; l != NULL; l = l->next) - { - const EphyEncodingInfo *info = (EphyEncodingInfo *) 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); - } + property); - gtk_option_menu_set_menu (GTK_OPTION_MENU(optionmenu), menu); + list = g_list_sort (list, (GCompareFunc) sort_encodings); - /* init value */ - encoding = eel_gconf_get_string (CONF_LANGUAGE_DEFAULT_ENCODING); - /* fallback */ - if (encoding == NULL) encoding = g_strdup ("ISO-8859-1"); + num = g_list_length (list); + codes = g_new0 (char *, num); - l = g_list_find_custom (dialog->priv->encodings, encoding, - (GCompareFunc) find_encoding_in_list_cmp); - gtk_option_menu_set_history (GTK_OPTION_MENU(optionmenu), - g_list_position (dialog->priv->encodings, l)); - g_free (encoding); - - g_signal_connect (optionmenu, "changed", - G_CALLBACK (default_encoding_menu_changed_cb), - dialog); -} - -static void -autodetect_encoding_menu_changed_cb (GtkOptionMenu *option_menu, gpointer data) -{ - GList *l; - guint i; - EncodingAutodetectorInfo *info; - - g_return_if_fail (EPHY_IS_PREFS_DIALOG (data)); - - i = gtk_option_menu_get_history (option_menu); - - l = g_list_nth (EPHY_PREFS_DIALOG (data)->priv->autodetectors, i); - - if (l) - { - info = (EncodingAutodetectorInfo *) l->data; - - eel_gconf_set_string (CONF_LANGUAGE_AUTODETECT_ENCODING, info->name); - } -} - -static gint -autodetector_info_cmp (const EncodingAutodetectorInfo *i1, const EncodingAutodetectorInfo *i2) -{ - return g_utf8_collate (i1->title, i2->title); -} - -static gint -find_autodetector_info (const EncodingAutodetectorInfo *info, const gchar *name) -{ - return strcmp (info->name, name); -} - -static void -create_encoding_autodetectors_menu (PrefsDialog *dialog) -{ - GtkWidget *optionmenu, *menu, *item; - gint i, position = 0; - GList *l, *list = NULL; - gchar *detector = NULL; - EncodingAutodetectorInfo *info; - - optionmenu = ephy_dialog_get_control (EPHY_DIALOG (dialog), - AUTO_ENCODING_PROP); - - for (i = 0; i < n_encoding_autodetectors; i++) + for (l = list, i=0; l != NULL; l = l->next, i++) { - info = g_new0 (EncodingAutodetectorInfo, 1); - - info->title = _(encoding_autodetector[i].title); - info->name = encoding_autodetector[i].name; - - list = g_list_prepend (list, info); - } - - list = g_list_sort (list, (GCompareFunc) autodetector_info_cmp); - dialog->priv->autodetectors = list; - - menu = gtk_menu_new (); + EphyNode *node = (EphyNode *) l->data; + const char *title, *code; + GtkWidget *item; - for (l = list; l != NULL; l = l->next) - { - info = (EncodingAutodetectorInfo *) l->data; + title = ephy_node_get_property_string + (node, EPHY_NODE_ENCODING_PROP_TITLE_ELIDED); - item = gtk_menu_item_new_with_label (info->title); + item = gtk_menu_item_new_with_label (title); gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); gtk_widget_show (item); - g_object_set_data (G_OBJECT (item), "desc", info->title); + + 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 */ - detector = eel_gconf_get_string (CONF_LANGUAGE_AUTODETECT_ENCODING); - if (detector == NULL) detector = g_strdup (""); - - l = g_list_find_custom (list, detector, - (GCompareFunc) find_autodetector_info); - - g_free (detector); - - if (l) + value = eel_gconf_get_string (key); + /* fallback */ + if (value == NULL || value[0] == '\0') { - position = g_list_position (list, l); + g_free (value); + value = g_strdup (default_value); } - gtk_option_menu_set_history (GTK_OPTION_MENU(optionmenu), position); + element = g_list_find_custom (list, value, + (GCompareFunc) find_encoding_in_list_cmp); + g_free (value); + pos = g_list_position (list, element); - g_signal_connect (optionmenu, "changed", - G_CALLBACK (autodetect_encoding_menu_changed_cb), - dialog); + 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 @@ -1033,7 +967,9 @@ 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); @@ -1051,8 +987,6 @@ prefs_dialog_init (PrefsDialog *pd) 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->encodings = NULL; - pd->priv->autodetectors = NULL; pd->priv->fonts_languages = NULL; icon = gtk_widget_render_icon (pd->priv->window, @@ -1067,8 +1001,20 @@ prefs_dialog_init (PrefsDialog *pd) attach_fonts_signals (pd); attach_size_controls_signals (pd); create_languages_list (pd); - create_default_encoding_menu (pd); - create_encoding_autodetectors_menu (pd); + + encodings = EPHY_ENCODINGS (ephy_embed_shell_get_encodings + (EPHY_EMBED_SHELL (ephy_shell))); + + list = ephy_encodings_get_encodings (encodings, LG_ALL); + create_optionmenu (pd, DEFAULT_ENCODING_PROP, list, + CONF_LANGUAGE_DEFAULT_ENCODING, "ISO-8859-1"); + g_list_free (list); + + list = ephy_encodings_get_detectors (encodings); + create_optionmenu (pd, AUTO_ENCODING_PROP, list, + CONF_LANGUAGE_AUTODETECT_ENCODING, ""); + g_list_free (list); + create_language_menu (pd); } |