Initial import of ephy (rev# 7126) from svn
[ephy-soc.git] / src / .svn / text-base / ephy-encoding-dialog.c.svn-base
blob18788f5501ba61eb524ed90f2fcf1f3412d0e817
1 /*
2  *  Copyright © 2000, 2001, 2002, 2003 Marco Pesenti Gritti
3  *  Copyright © 2003, 2004 Christian Persch
4  *
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)
8  *  any later version.
9  *
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.
14  *
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.
18  *
19  *  $Id$
20  */
22 #include "config.h"
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"
33 #include "ephy-gui.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>
42 #include <string.h>
44 enum
46         WINDOW_PROP,
47         SCROLLED_WINDOW_PROP,
48         AUTOMATIC_PROP,
49         MANUAL_PROP
52 static const
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 },
60         { NULL }
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;
68         EphyWindow *window;
69         EphyEmbed *embed;
70         GtkWidget *enc_view;
71         EphyNodeFilter *filter;
72         EphyNode *selected_node;
73         gboolean update_tag;
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;
81 GType
82 ephy_encoding_dialog_get_type (void)
84         static GType type = 0;
86         if (G_UNLIKELY (type == 0))
87         {
88                 const GTypeInfo our_info =
89                 {
90                         sizeof (EphyEncodingDialogClass),
91                         NULL, /* base_init */
92                         NULL, /* base_finalize */
93                         (GClassInitFunc) ephy_encoding_dialog_class_init,
94                         NULL,
95                         NULL, /* class_data */
96                         sizeof (EphyEncodingDialog),
97                         0, /* n_preallocs */
98                         (GInstanceInitFunc) ephy_encoding_dialog_init
99                 };
101                 type = g_type_register_static (EPHY_TYPE_EMBED_DIALOG,
102                                                "EphyEncodingDialog",
103                                                &our_info, 0);
104         }
106         return type;
109 static void
110 sync_encoding_against_embed (EphyEncodingDialog *dialog)
112         EphyEmbed *embed;
113         EphyNode *node;
114         GtkTreeSelection *selection;
115         GtkTreeModel *model;
116         GList *rows;
117         GtkWidget *button;
118         char *encoding;
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),
134                                     node);
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);
141         if (rows != NULL)
142         {
143                 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (dialog->priv->enc_view),
144                                               (GtkTreePath *) rows->data,
145                                               NULL, /* column */
146                                               TRUE,
147                                               0.5,
148                                               0.0);
149                 g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
150                 g_list_free (rows);
151         }
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);
158         g_free (encoding);
160         dialog->priv->update_tag = FALSE;
164 static void
165 embed_net_stop_cb (EphyEmbed *embed, EphyEncodingDialog *dialog)
167         sync_encoding_against_embed (dialog);
170 static void
171 sync_embed_cb (EphyEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy)
173         EphyEmbed *embed;
174         embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG (dialog));
176         if (dialog->priv->embed != NULL)
177         {
178                 g_signal_handlers_disconnect_by_func (dialog->priv->embed,
179                                                       G_CALLBACK (embed_net_stop_cb),
180                                                       dialog);
181         }
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);
190 static void
191 sync_active_tab (EphyWindow *window, GParamSpec *pspec, EphyEncodingDialog *dialog)
193         EphyEmbed *embed;
195         embed = ephy_window_get_active_embed (dialog->priv->window);
197         g_object_set (G_OBJECT (dialog), "embed", embed, NULL);
200 static void
201 sync_parent_window_cb (EphyEncodingDialog *dialog, GParamSpec *pspec, gpointer dummy)
203         EphyWindow *window;
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);
222 static void
223 activate_choice (EphyEncodingDialog *dialog)
225         EphyEmbed *embed;
226         GtkWidget *button;
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));
235         if (is_automatic)
236         {
237                 ephy_embed_set_encoding (embed, "");
238         }
239         else if (dialog->priv->selected_node != NULL)
240         {
241                 const char *code;
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);
249         }
252 static void
253 ephy_encoding_dialog_response_cb (GtkWidget *widget,
254                                   int response,
255                                   EphyEncodingDialog *dialog)
257         if (response == GTK_RESPONSE_HELP)
258         {
259                 ephy_gui_help (GTK_WINDOW (widget), "epiphany", "text-encoding");
260                 return;
261         }
263         g_object_unref (dialog);
266 static void
267 view_node_selected_cb (EphyNodeView *view,
268                        EphyNode *node,
269                        EphyEncodingDialog *dialog)
271         GtkWidget *button;
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);
283 static void
284 view_node_activated_cb (GtkWidget *view,
285                         EphyNode *node,
286                         EphyEncodingDialog *dialog)
288         GtkWidget *button;
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);
302 static void
303 automatic_toggled_cb (GtkToggleButton *button, EphyEncodingDialog *dialog)
305         if (gtk_toggle_button_get_active (button)
306             && dialog->priv->update_tag == FALSE)
307         {
308                 activate_choice (dialog);
309         }
312 static void
313 ephy_encoding_dialog_init (EphyEncodingDialog *dialog)
315         GtkWidget *treeview, *scroller, *button, *window;
316         GtkTreeSelection *selection;
317         EphyNode *node;
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),
326                                properties,
327                                ephy_file ("epiphany.glade"),
328                                "encoding_dialog",
329                                NULL);
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"),
341                                    G_TYPE_STRING,
342                                    EPHY_NODE_ENCODING_PROP_TITLE_ELIDED,
343                                    EPHY_NODE_VIEW_SEARCHABLE,
344                                    NULL, NULL);
346         ephy_node_view_set_sort (EPHY_NODE_VIEW (treeview), G_TYPE_STRING,
347                                  EPHY_NODE_ENCODING_PROP_TITLE_ELIDED,
348                                  GTK_SORT_ASCENDING);
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),
355                           "node_selected",
356                           G_CALLBACK (view_node_selected_cb),
357                           dialog);
358         g_signal_connect (G_OBJECT (treeview),
359                           "node_activated",
360                           G_CALLBACK (view_node_activated_cb),
361                           dialog);
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);
385 static void
386 ephy_encoding_dialog_finalize (GObject *object)
388         EphyEncodingDialog *dialog = EPHY_ENCODING_DIALOG (object);
390         if (dialog->priv->window != NULL)
391         {
392                 g_signal_handlers_disconnect_by_func (dialog->priv->window,
393                                                       G_CALLBACK (sync_active_tab),
394                                                       dialog);
395         }
397         if (dialog->priv->embed)
398         {
399                 g_signal_handlers_disconnect_by_func (dialog->priv->embed,
400                                                       G_CALLBACK (embed_net_stop_cb),
401                                                       dialog);
402         }
404         g_object_unref (dialog->priv->filter);
406         G_OBJECT_CLASS (parent_class)->finalize (object);
409 static void
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));
420                 
421 EphyEncodingDialog *
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,
428                              NULL);