2 * Copyright © 2000, 2001, 2002, 2003 Marco Pesenti Gritti
3 * Copyright © 2003, 2004 Christian Persch
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "ephy-encoding-dialog.h"
25 #include "ephy-encodings.h"
26 #include "ephy-embed.h"
27 #include "ephy-embed-shell.h"
28 #include "ephy-file-helpers.h"
29 #include "ephy-shell.h"
30 #include "ephy-node.h"
31 #include "ephy-node-view.h"
32 #include "ephy-debug.h"
35 #include <gtk/gtklabel.h>
36 #include <gtk/gtkbutton.h>
37 #include <gtk/gtktreeview.h>
38 #include <gtk/gtktreeselection.h>
39 #include <gtk/gtktogglebutton.h>
40 #include <gtk/gtkdialog.h>
41 #include <glib/gi18n.h>
53 EphyDialogProperty properties [] =
55 { "encoding_dialog", NULL, PT_NORMAL, 0 },
56 { "scrolled_window", NULL, PT_NORMAL, 0 },
57 { "automatic_button", NULL, PT_NORMAL, 0 },
58 { "manual_button", NULL, PT_NORMAL, 0 },
63 #define EPHY_ENCODING_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_ENCODING_DIALOG, EphyEncodingDialogPrivate))
65 struct _EphyEncodingDialogPrivate
67 EphyEncodings *encodings;
71 EphyNodeFilter *filter;
72 EphyNode *selected_node;
76 static void ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass);
77 static void ephy_encoding_dialog_init (EphyEncodingDialog *ge);
79 static GObjectClass *parent_class = NULL;
82 ephy_encoding_dialog_get_type (void)
84 static GType type = 0;
86 if (G_UNLIKELY (type == 0))
88 const GTypeInfo our_info =
90 sizeof (EphyEncodingDialogClass),
92 NULL, /* base_finalize */
93 (GClassInitFunc) ephy_encoding_dialog_class_init,
95 NULL, /* class_data */
96 sizeof (EphyEncodingDialog),
98 (GInstanceInitFunc) ephy_encoding_dialog_init
101 type = g_type_register_static (EPHY_TYPE_EMBED_DIALOG,
102 "EphyEncodingDialog",
110 sync_encoding_against_embed (EphyEncodingDialog *dialog)
114 GtkTreeSelection *selection;
119 gboolean is_automatic;
121 dialog->priv->update_tag = TRUE;
123 embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog));
124 g_return_if_fail (EPHY_IS_EMBED (embed));
126 encoding = ephy_embed_get_encoding (embed);
127 if (encoding == NULL) return;
129 node = ephy_encodings_get_node (dialog->priv->encodings, encoding, TRUE);
130 g_assert (EPHY_IS_NODE (node));
132 /* select the current encoding in the list view */
133 ephy_node_view_select_node (EPHY_NODE_VIEW (dialog->priv->enc_view),
136 /* scroll the view so the active encoding is visible */
137 selection = gtk_tree_view_get_selection
138 (GTK_TREE_VIEW (dialog->priv->enc_view));
139 model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->priv->enc_view));
140 rows = gtk_tree_selection_get_selected_rows (selection, &model);
143 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (dialog->priv->enc_view),
144 (GtkTreePath *) rows->data,
149 g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
153 is_automatic = ephy_embed_has_automatic_encoding (embed);
155 button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[AUTOMATIC_PROP].id);
156 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), is_automatic);
160 dialog->priv->update_tag = FALSE;
165 embed_net_stop_cb (EphyEmbed *embed, EphyEncodingDialog *dialog)
167 sync_encoding_against_embed (dialog);
171 sync_embed_cb (EphyEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy)
174 embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog));
176 if (dialog->priv->embed != NULL)
178 g_signal_handlers_disconnect_by_func (dialog->priv->embed,
179 G_CALLBACK (embed_net_stop_cb),
183 g_signal_connect (G_OBJECT (embed), "net_stop",
184 G_CALLBACK (embed_net_stop_cb), dialog);
185 dialog->priv->embed = embed;
187 sync_encoding_against_embed (dialog);
191 sync_active_tab (EphyWindow *window, GParamSpec *pspec, EphyEncodingDialog *dialog)
195 embed = ephy_window_get_active_embed (dialog->priv->window);
197 g_object_set (G_OBJECT (dialog), "embed", embed, NULL);
201 sync_parent_window_cb (EphyEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy)
204 GValue value = { 0, };
206 g_return_if_fail (dialog->priv->window == NULL);
208 g_value_init (&value, GTK_TYPE_WIDGET);
209 g_object_get_property (G_OBJECT (dialog), "parent-window", &value);
210 window = EPHY_WINDOW (g_value_get_object (&value));
211 g_value_unset (&value);
213 g_return_if_fail (EPHY_IS_WINDOW (window));
215 dialog->priv->window = window;
217 sync_active_tab (window, NULL, dialog);
218 g_signal_connect (G_OBJECT (window), "notify::active-tab",
219 G_CALLBACK (sync_active_tab), dialog);
223 activate_choice (EphyEncodingDialog *dialog)
227 gboolean is_automatic;
229 embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog));
230 g_return_if_fail (EPHY_IS_EMBED (embed));
232 button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[AUTOMATIC_PROP].id);
233 is_automatic = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
237 ephy_embed_set_encoding (embed, "");
239 else if (dialog->priv->selected_node != NULL)
243 code = ephy_node_get_property_string (dialog->priv->selected_node,
244 EPHY_NODE_ENCODING_PROP_ENCODING);
246 ephy_embed_set_encoding (embed, code);
248 ephy_encodings_add_recent (dialog->priv->encodings, code);
253 ephy_encoding_dialog_response_cb (GtkWidget *widget,
255 EphyEncodingDialog *dialog)
257 if (response == GTK_RESPONSE_HELP)
259 ephy_gui_help (GTK_WINDOW (widget), "epiphany", "text-encoding");
263 g_object_unref (dialog);
267 view_node_selected_cb (EphyNodeView *view,
269 EphyEncodingDialog *dialog)
273 dialog->priv->selected_node = node;
275 if (dialog->priv->update_tag) return;
277 button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[MANUAL_PROP].id);
278 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
280 activate_choice (dialog);
284 view_node_activated_cb (GtkWidget *view,
286 EphyEncodingDialog *dialog)
290 dialog->priv->selected_node = node;
292 if (dialog->priv->update_tag) return;
294 button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[MANUAL_PROP].id);
295 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
297 activate_choice (dialog);
299 g_object_unref (dialog);
303 automatic_toggled_cb (GtkToggleButton *button, EphyEncodingDialog *dialog)
305 if (gtk_toggle_button_get_active (button)
306 && dialog->priv->update_tag == FALSE)
308 activate_choice (dialog);
313 ephy_encoding_dialog_init (EphyEncodingDialog *dialog)
315 GtkWidget *treeview, *scroller, *button, *window;
316 GtkTreeSelection *selection;
319 dialog->priv = EPHY_ENCODING_DIALOG_GET_PRIVATE (dialog);
321 dialog->priv->encodings =
322 EPHY_ENCODINGS (ephy_embed_shell_get_encodings
323 (EPHY_EMBED_SHELL (ephy_shell)));
325 ephy_dialog_construct (EPHY_DIALOG (dialog),
327 ephy_file ("epiphany.glade"),
331 window = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[WINDOW_PROP].id);
332 g_signal_connect (window, "response",
333 G_CALLBACK (ephy_encoding_dialog_response_cb), dialog);
335 dialog->priv->filter = ephy_node_filter_new ();
337 node = ephy_encodings_get_all (dialog->priv->encodings);
338 treeview = ephy_node_view_new (node, dialog->priv->filter);
340 ephy_node_view_add_column (EPHY_NODE_VIEW (treeview), _("Encodings"),
342 EPHY_NODE_ENCODING_PROP_TITLE_ELIDED,
343 EPHY_NODE_VIEW_SEARCHABLE,
346 ephy_node_view_set_sort (EPHY_NODE_VIEW (treeview), G_TYPE_STRING,
347 EPHY_NODE_ENCODING_PROP_TITLE_ELIDED,
350 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
351 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
352 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), FALSE);
354 g_signal_connect (G_OBJECT (treeview),
356 G_CALLBACK (view_node_selected_cb),
358 g_signal_connect (G_OBJECT (treeview),
360 G_CALLBACK (view_node_activated_cb),
363 gtk_widget_show (treeview);
365 scroller = ephy_dialog_get_control
366 (EPHY_DIALOG (dialog), properties[SCROLLED_WINDOW_PROP].id);
367 gtk_container_add (GTK_CONTAINER (scroller), treeview);
369 button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[AUTOMATIC_PROP].id);
370 gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (button)->child), TRUE);
371 g_signal_connect (button, "toggled",
372 G_CALLBACK (automatic_toggled_cb), dialog);
374 button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[MANUAL_PROP].id);
375 gtk_label_set_use_markup (GTK_LABEL (GTK_BIN (button)->child), TRUE);
377 dialog->priv->enc_view = treeview;
379 g_signal_connect (G_OBJECT (dialog), "notify::parent-window",
380 G_CALLBACK (sync_parent_window_cb), NULL);
381 g_signal_connect (G_OBJECT (dialog), "notify::embed",
382 G_CALLBACK (sync_embed_cb), NULL);
386 ephy_encoding_dialog_finalize (GObject *object)
388 EphyEncodingDialog *dialog = EPHY_ENCODING_DIALOG (object);
390 if (dialog->priv->window != NULL)
392 g_signal_handlers_disconnect_by_func (dialog->priv->window,
393 G_CALLBACK (sync_active_tab),
397 if (dialog->priv->embed)
399 g_signal_handlers_disconnect_by_func (dialog->priv->embed,
400 G_CALLBACK (embed_net_stop_cb),
404 g_object_unref (dialog->priv->filter);
406 G_OBJECT_CLASS (parent_class)->finalize (object);
410 ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass)
412 GObjectClass *object_class = G_OBJECT_CLASS (klass);
414 parent_class = g_type_class_peek_parent (klass);
416 object_class->finalize = ephy_encoding_dialog_finalize;
418 g_type_class_add_private (object_class, sizeof(EphyEncodingDialogPrivate));
422 ephy_encoding_dialog_new (EphyWindow *parent)
424 return g_object_new (EPHY_TYPE_ENCODING_DIALOG,
425 "parent-window", parent,
426 "default-width", 350,
427 "default-height", 420,