aboutsummaryrefslogtreecommitdiffstats
path: root/src/ephy-encoding-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ephy-encoding-dialog.c')
-rw-r--r--src/ephy-encoding-dialog.c489
1 files changed, 489 insertions, 0 deletions
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);
+}