[epiphany] EphyEncodingDialog: Rework.



commit 050f095c0fefc5213002df88039188115dfa0fd5
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Thu Dec 10 12:18:07 2015 +0100

    EphyEncodingDialog: Rework.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=759164

 src/Makefile.am                  |    5 +-
 src/ephy-encoding-dialog.c       |  336 +++++++++++++++++-----------
 src/ephy-encoding-menu.c         |  454 --------------------------------------
 src/ephy-encoding-menu.h         |   61 -----
 src/ephy-encoding-row.c          |  153 +++++++++++++
 src/ephy-encoding-row.h          |   40 ++++
 src/ephy-window.c                |   12 +-
 src/epiphany.gresource.xml       |    1 +
 src/resources/encoding-dialog.ui |   91 +++++++-
 src/resources/encoding-row.ui    |   27 +++
 src/resources/epiphany-ui.xml    |    4 +-
 src/window-commands.c            |   12 +
 src/window-commands.h            |    2 +
 13 files changed, 528 insertions(+), 670 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 7eb82ef..a6c14cf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,7 +19,7 @@ NOINST_H_FILES = \
        ephy-action-helper.h                    \
        ephy-combined-stop-reload-action.h      \
        ephy-encoding-dialog.h                  \
-       ephy-encoding-menu.h                    \
+       ephy-encoding-row.h                     \
        ephy-history-window.h                   \
        ephy-home-action.h                      \
        ephy-link-action.h                      \
@@ -53,7 +53,7 @@ libephymain_la_SOURCES = \
        ephy-completion-model.h                 \
        ephy-combined-stop-reload-action.c      \
        ephy-encoding-dialog.c                  \
-       ephy-encoding-menu.c                    \
+       ephy-encoding-row.c                     \
        ephy-home-action.c                      \
        ephy-history-window.c                   \
        ephy-link.c                             \
@@ -108,6 +108,7 @@ RESOURCE_FILES = \
        resources/clear-data-dialog.ui            \
        resources/cookies-dialog.ui               \
        resources/encoding-dialog.ui              \
+       resources/encoding-row.ui                 \
        resources/epiphany-application-menu.ui    \
        resources/epiphany-bookmark-editor-ui.xml \
        resources/epiphany-ui.xml                 \
diff --git a/src/ephy-encoding-dialog.c b/src/ephy-encoding-dialog.c
index 8348b24..5ea7185 100644
--- a/src/ephy-encoding-dialog.c
+++ b/src/ephy-encoding-dialog.c
@@ -27,8 +27,7 @@
 #include "ephy-embed-utils.h"
 #include "ephy-embed.h"
 #include "ephy-encodings.h"
-#include "ephy-file-helpers.h"
-#include "ephy-gui.h"
+#include "ephy-encoding-row.h"
 #include "ephy-shell.h"
 
 #include <glib/gi18n.h>
@@ -43,12 +42,18 @@ struct _EphyEncodingDialog
        EphyWindow *window;
        EphyEmbed *embed;
        GtkWidget *enc_view;
-       gboolean update_tag;
+       gboolean update_embed_tag;
+       gboolean update_view_tag;
        char *selected_encoding;
 
        /* from the UI file */
-       GtkSwitch         *default_switch;
-       GtkScrolledWindow *scrolled_window;
+       GtkStack *type_stack;
+       GtkSwitch *default_switch;
+       GtkListBox *list_box;
+       GtkListBox *recent_list_box;
+       GtkListBox *related_list_box;
+       GtkGrid *recent_grid;
+       GtkGrid *related_grid;
 };
 
 enum {
@@ -66,40 +71,36 @@ enum
 G_DEFINE_TYPE (EphyEncodingDialog, ephy_encoding_dialog, GTK_TYPE_DIALOG)
 
 static void
-select_encoding_row (GtkTreeView *view, EphyEncoding *encoding)
+select_encoding_row (GtkListBox   *list_box,
+                     EphyEncoding *encoding)
 {
-       GtkTreeIter iter;
-       GtkTreeModel *model;
-       gboolean valid_iter = FALSE;
        const char *target_encoding;
-
-       model = gtk_tree_view_get_model (view);
-       valid_iter = gtk_tree_model_get_iter_first (model, &iter);
+       GList *rows, *r;
 
        target_encoding = ephy_encoding_get_encoding (encoding);
+       rows = gtk_container_get_children (GTK_CONTAINER (list_box));
 
-       while (valid_iter)
+       for (r = rows; r != NULL; r = r->next)
        {
-               char *encoding_string = NULL;
+               EphyEncodingRow *ephy_encoding_row;
+               EphyEncoding *ephy_encoding;
+               const char *encoding_string = NULL;
 
-               gtk_tree_model_get (model, &iter,
-                                   COL_ENCODING, &encoding_string, -1);
+               ephy_encoding_row = EPHY_ENCODING_ROW (gtk_bin_get_child (GTK_BIN (r->data)));
+               ephy_encoding = ephy_encoding_row_get_encoding (ephy_encoding_row);
+               encoding_string = ephy_encoding_get_encoding (ephy_encoding);
 
-               if (g_str_equal (encoding_string,
-                                target_encoding))
+               if (g_strcmp0 (encoding_string, target_encoding) == 0)
                {
-                       GtkTreeSelection *selection;
+                       ephy_encoding_row_set_selected (ephy_encoding_row, TRUE);
 
-                       selection = gtk_tree_view_get_selection (view);
-                       gtk_tree_selection_select_iter (selection, &iter);
-                       g_free (encoding_string);
+                       gtk_list_box_select_row (list_box, GTK_LIST_BOX_ROW (r->data));
+                       /* TODO scroll to row */
 
-                       return;
+                       break;
                }
-
-               g_free (encoding_string);
-               valid_iter = gtk_tree_model_iter_next (model, &iter);
        }
+       g_list_free (rows);
 }
 
 static void
@@ -109,7 +110,7 @@ sync_encoding_against_embed (EphyEncodingDialog *dialog)
        gboolean is_automatic = FALSE;
        WebKitWebView *view;
 
-       dialog->update_tag = TRUE;
+       dialog->update_embed_tag = TRUE;
 
        g_return_if_fail (EPHY_IS_EMBED (dialog->embed));
        view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (dialog->embed);
@@ -120,38 +121,22 @@ sync_encoding_against_embed (EphyEncodingDialog *dialog)
        if (!is_automatic)
        {
                EphyEncoding *node;
-               GtkTreeSelection *selection;
-               GtkTreeModel *model;
-               GList *rows;
 
                node = ephy_encodings_get_encoding (dialog->encodings, encoding, TRUE);
                g_assert (EPHY_IS_ENCODING (node));
 
-               /* Select the current encoding in the list view. */
-               select_encoding_row (GTK_TREE_VIEW (dialog->enc_view), node);
-
-               /* scroll the view so the active encoding is visible */
-               selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->enc_view));
-               model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->enc_view));
-               rows = gtk_tree_selection_get_selected_rows (selection, &model);
+               /* Select the current encoding in the lists. */
+               select_encoding_row (dialog->list_box, node);
+               select_encoding_row (dialog->recent_list_box, node);
+               select_encoding_row (dialog->related_list_box, node);
 
-               if (rows != NULL)
-               {
-                       gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (dialog->enc_view),
-                                                     (GtkTreePath *) rows->data,
-                                                     NULL, /* column */
-                                                     TRUE,
-                                                     0.5,
-                                                     0.0);
-                       g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
-                       g_list_free (rows);
-               }
+               /* TODO scroll the view so the active encoding is visible */
        }
        gtk_switch_set_active (dialog->default_switch, is_automatic);
        gtk_switch_set_state (dialog->default_switch, is_automatic);
-       gtk_widget_set_sensitive (GTK_WIDGET (dialog->scrolled_window), !is_automatic);
+       gtk_widget_set_sensitive (GTK_WIDGET (dialog->type_stack), !is_automatic);
 
-       dialog->update_tag = FALSE;
+       dialog->update_embed_tag = FALSE;
 }
 
 static void
@@ -195,8 +180,6 @@ ephy_encoding_dialog_attach_embed (EphyEncodingDialog *dialog)
        embedptr = &dialog->embed;
        g_object_add_weak_pointer (G_OBJECT (dialog->embed),
                                   (gpointer *) embedptr);
-
-       sync_encoding_against_embed (dialog);
 }
 
 static void
@@ -204,6 +187,7 @@ ephy_encoding_dialog_sync_embed (EphyWindow *window, GParamSpec *pspec, EphyEnco
 {
        ephy_encoding_dialog_detach_embed (dialog);
        ephy_encoding_dialog_attach_embed (dialog);
+       sync_encoding_against_embed (dialog);
 }
 
 static void
@@ -239,29 +223,56 @@ ephy_encoding_dialog_response_cb (GtkWidget *widget,
 }
 
 static void
-view_row_activated_cb (GtkTreeView *treeview,
-                      GtkTreePath *path,
-                      GtkTreeViewColumn *column,
-                      EphyEncodingDialog *dialog)
+clean_selected_row (gpointer row, gpointer null_pointer)
 {
-       GtkTreeIter iter;
-       char *encoding;
-       GtkTreeModel *model;
+       EphyEncodingRow *ephy_encoding_row;
+       ephy_encoding_row = EPHY_ENCODING_ROW (gtk_bin_get_child (GTK_BIN (row)));
+       ephy_encoding_row_set_selected (ephy_encoding_row, FALSE);
+}
 
-       model = gtk_tree_view_get_model (treeview);
+static void
+clean_selected_list_box (GtkListBox *list_box)
+{
+       GList *rows;
+       rows = gtk_container_get_children (GTK_CONTAINER (list_box));
+       g_list_foreach (rows, (GFunc)clean_selected_row, NULL);
+       g_list_free (rows);
+}
 
-       gtk_tree_model_get_iter (model, &iter, path);
-       gtk_tree_model_get (model, &iter,
-                           COL_ENCODING, &encoding,
-                           -1);
+static void
+clean_selected (EphyEncodingDialog *dialog)
+{
+       clean_selected_list_box (dialog->list_box);
+       clean_selected_list_box (dialog->recent_list_box);
+       clean_selected_list_box (dialog->related_list_box);
+}
 
-       g_free (dialog->selected_encoding);
-       dialog->selected_encoding = encoding;
+static void
+row_activated_cb (GtkListBox         *box,
+                  GtkListBoxRow      *row,
+                  EphyEncodingDialog *dialog)
+{
+       EphyEncodingRow *ephy_encoding_row;
+       EphyEncoding *ephy_encoding;
+       const char *selected_encoding;
 
-       if (dialog->update_tag)
+       if (dialog->update_embed_tag || dialog->update_view_tag)
                return;
 
+       dialog->update_view_tag = TRUE;
+
+       ephy_encoding_row = EPHY_ENCODING_ROW (gtk_bin_get_child (GTK_BIN (row)));
+       ephy_encoding = ephy_encoding_row_get_encoding (ephy_encoding_row);
+       selected_encoding = ephy_encoding_get_encoding (ephy_encoding);
+
+       dialog->selected_encoding = selected_encoding;
+
+       clean_selected (dialog);
+       ephy_encoding_row_set_selected (ephy_encoding_row, TRUE);
+
        activate_choice (dialog);
+
+       dialog->update_view_tag = FALSE;
 }
 
 static gboolean
@@ -269,93 +280,151 @@ default_switch_toggled_cb (GtkSwitch          *default_switch,
                            gboolean            state,
                            EphyEncodingDialog *dialog)
 {
-       if (dialog->update_tag)
+       if (dialog->update_embed_tag || dialog->update_view_tag)
        {
-               gtk_switch_set_state (default_switch, !state);
+               gtk_switch_set_state (default_switch, !state);  // cancel switch change
+               return TRUE;
        }
-       else if (state)
-       {
-               gtk_switch_set_state (default_switch, TRUE);
 
-               if (dialog->selected_encoding != NULL)
-               {
-                       g_free (dialog->selected_encoding);
-                       dialog->selected_encoding = NULL;
-               }
-               activate_choice (dialog);
-       }
-       else
-       {
-               gtk_switch_set_state (default_switch, FALSE);
+       dialog->update_view_tag = TRUE;
+
+       gtk_switch_set_active (default_switch, state);
+       gtk_switch_set_state (default_switch, state);
+
+       // TODO if state == false && selected_encoding == NULL, select safe default in list, or find another 
solution
+       if (state)
+               clean_selected (dialog);
+       activate_choice (dialog);
+
+       dialog->update_view_tag = FALSE;
 
-               // TODO select safe default in list, or find another solution
-       }
        return TRUE;
 }
 
 static void
+show_all_button_clicked_cb (GtkButton          *show_all_button,
+                            EphyEncodingDialog *dialog)
+{
+       gtk_stack_set_visible_child_name (dialog->type_stack, "scrolled-window");
+}
+
+static gint
+sort_list_store (gconstpointer a,
+                 gconstpointer b,
+                 gpointer user_data)
+{
+       const char *encoding1 = ephy_encoding_get_title_elided (EPHY_ENCODING (a));
+       const char *encoding2 = ephy_encoding_get_title_elided (EPHY_ENCODING (b));
+
+       return g_strcmp0 (encoding1, encoding2);
+}
+
+static GtkWidget *
+create_list_box_row (gpointer object,
+                     gpointer user_data)
+{
+       return GTK_WIDGET (ephy_encoding_row_new (EPHY_ENCODING (object)));
+}
+
+static void
+add_list_item (EphyEncoding *encoding, GtkListBox* list_box)
+{
+       gtk_container_add (GTK_CONTAINER (list_box), GTK_WIDGET (ephy_encoding_row_new (encoding)));
+}
+
+static int
+sort_encodings (gconstpointer a, gconstpointer b)
+{
+       EphyEncoding *enc1 = (EphyEncoding *)a;
+       EphyEncoding *enc2 = (EphyEncoding *)b;
+       const char *key1, *key2;
+
+       key1 = ephy_encoding_get_collation_key (enc1);
+       key2 = ephy_encoding_get_collation_key (enc2);
+
+       return strcmp (key1, key2);
+}
+
+static void
 ephy_encoding_dialog_init (EphyEncodingDialog *dialog)
 {
-       GtkWidget *treeview;
-       GtkTreeSelection *selection;
        GList *encodings, *p;
-       GtkListStore *store;
-       GtkTreeIter iter;
-       GtkCellRenderer *renderer;
+       GListStore *store;
 
        gtk_widget_init_template (GTK_WIDGET (dialog));
 
-       dialog->selected_encoding = NULL;
+       dialog->update_embed_tag = FALSE;
+       dialog->update_view_tag = FALSE;
+
        dialog->encodings =
                EPHY_ENCODINGS (ephy_embed_shell_get_encodings
                                (EPHY_EMBED_SHELL (ephy_shell_get_default ())));
 
        encodings = ephy_encodings_get_all (dialog->encodings);
-       store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING);
-       for (p = encodings; p; p = p->next) 
+
+       store = g_list_store_new (EPHY_TYPE_ENCODING);
+       for (p = encodings; p; p = p->next)
        {
                EphyEncoding *encoding = EPHY_ENCODING (p->data);
-
-               gtk_list_store_append (store, &iter);
-               gtk_list_store_set (store, &iter,
-                                   COL_TITLE_ELIDED, 
-                                   ephy_encoding_get_title_elided (encoding),
-                                   -1);
-               gtk_list_store_set (store, &iter,
-                                   COL_ENCODING, 
-                                   ephy_encoding_get_encoding (encoding),
-                                   -1);
+               g_list_store_insert_sorted (store, encoding, sort_list_store, NULL);
        }
        g_list_free (encodings);
 
-       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COL_TITLE_ELIDED,
-                                             GTK_SORT_ASCENDING);
+       gtk_list_box_bind_model (dialog->list_box, G_LIST_MODEL (store),
+                                create_list_box_row,
+                                NULL, NULL);
+}
+
+static void
+ephy_encoding_dialog_constructed (GObject *object)
+{
+       EphyEncodingDialog *dialog;
+       WebKitWebView *view;
+       EphyEncoding *enc_node;
+       EphyLanguageGroup groups;
+       GList *recent;
+       GList *related = NULL;
+
+       /* selected encoding */
+       dialog = EPHY_ENCODING_DIALOG (object);
 
-       treeview = gtk_tree_view_new ();
-       renderer = gtk_cell_renderer_text_new ();
+       g_return_if_fail (EPHY_IS_EMBED (dialog->embed));
+       view = EPHY_GET_WEBKIT_WEB_VIEW_FROM_EMBED (dialog->embed);
 
-       gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-                                                    -1,
-                                                    _("Encodings"),
-                                                    renderer,
-                                                    "text", COL_TITLE_ELIDED,
-                                                    NULL);
-       gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store));
+       dialog->selected_encoding = webkit_web_view_get_custom_charset (view);
 
-       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);
-       gtk_tree_view_set_activate_on_single_click (GTK_TREE_VIEW (treeview), TRUE);
+       /* recent */
+       recent = ephy_encodings_get_recent (dialog->encodings);
+       if (recent != NULL)
+       {
+               recent = g_list_sort (recent, (GCompareFunc)sort_encodings);
+               g_list_foreach (recent, (GFunc)add_list_item, dialog->recent_list_box);
+       }
+       else
+               gtk_widget_hide (GTK_WIDGET (dialog->recent_grid));
 
-       g_signal_connect (treeview, "row-activated",
-                         G_CALLBACK (view_row_activated_cb),
-                         dialog);
+       /* related */
+       if (dialog->selected_encoding != NULL)
+       {
+               enc_node = ephy_encodings_get_encoding (dialog->encodings, dialog->selected_encoding, TRUE);
+               g_assert (EPHY_IS_ENCODING (enc_node));
+               groups = ephy_encoding_get_language_groups (enc_node);
 
-       gtk_widget_show (treeview);
+               related = ephy_encodings_get_encodings (dialog->encodings, groups);
+       }
+       if (related != NULL)
+       {
+               related = g_list_sort (related, (GCompareFunc)sort_encodings);
+               g_list_foreach (related, (GFunc)add_list_item, dialog->related_list_box);
+       }
+       else
+               gtk_widget_hide (GTK_WIDGET (dialog->related_grid));
 
-       gtk_container_add (GTK_CONTAINER (dialog->scrolled_window), treeview);
+       /* update list_boxes */
+       sync_encoding_against_embed (dialog);
 
-       dialog->enc_view = treeview;
+       /* chaining */
+       G_OBJECT_CLASS (ephy_encoding_dialog_parent_class)->constructed (object);
 }
 
 static void
@@ -374,16 +443,6 @@ ephy_encoding_dialog_dispose (GObject *object)
 }
 
 static void
-ephy_encoding_dialog_finalize (GObject *object)
-{
-       EphyEncodingDialog *dialog = EPHY_ENCODING_DIALOG (object);
-
-       g_free (dialog->selected_encoding);
-
-       G_OBJECT_CLASS (ephy_encoding_dialog_parent_class)->finalize (object);
-}
-
-static void
 ephy_encoding_dialog_set_parent_window (EphyEncodingDialog *dialog,
                                         EphyWindow *window)
 {
@@ -439,7 +498,7 @@ ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass)
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
        /* class creation */
-       object_class->finalize = ephy_encoding_dialog_finalize;
+       object_class->constructed = ephy_encoding_dialog_constructed;
        object_class->set_property = ephy_encoding_dialog_set_property;
        object_class->get_property = ephy_encoding_dialog_get_property;
        object_class->dispose = ephy_encoding_dialog_dispose;
@@ -455,11 +514,18 @@ ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass)
        /* load from UI file */
        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/epiphany/encoding-dialog.ui");
 
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, type_stack);
        gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, default_switch);
-       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, scrolled_window);
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, list_box);
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, recent_list_box);
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, related_list_box);
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, recent_grid);
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingDialog, related_grid);
 
        gtk_widget_class_bind_template_callback (widget_class, default_switch_toggled_cb);
        gtk_widget_class_bind_template_callback (widget_class, ephy_encoding_dialog_response_cb);
+       gtk_widget_class_bind_template_callback (widget_class, row_activated_cb);
+       gtk_widget_class_bind_template_callback (widget_class, show_all_button_clicked_cb);
 }
 
 EphyEncodingDialog *
diff --git a/src/ephy-encoding-row.c b/src/ephy-encoding-row.c
new file mode 100644
index 0000000..72edf8d
--- /dev/null
+++ b/src/ephy-encoding-row.c
@@ -0,0 +1,153 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Copyright © 2015 Arnaud Bonatti
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "ephy-encoding-row.h"
+
+#include "ephy-encoding.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+struct _EphyEncodingRow
+{
+       GtkGrid parent_instance;
+
+       EphyEncoding *encoding;
+
+       /* from the UI file */
+       GtkLabel *encoding_label;
+       GtkImage *selected_image;
+};
+
+enum
+{
+       PROP_0,
+       PROP_ENCODING,
+       LAST_PROP
+};
+
+static GParamSpec *obj_properties[LAST_PROP];
+
+G_DEFINE_TYPE (EphyEncodingRow, ephy_encoding_row, GTK_TYPE_GRID)
+
+void
+ephy_encoding_row_set_selected (EphyEncodingRow *row,
+                                gboolean         selected)
+{
+       g_return_if_fail (EPHY_IS_ENCODING_ROW (row));
+
+       if (selected)
+               gtk_widget_show (GTK_WIDGET (row->selected_image));
+       else
+               gtk_widget_hide (GTK_WIDGET (row->selected_image));
+}
+
+static void
+ephy_encoding_row_init (EphyEncodingRow *self)
+{
+       gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+static void
+ephy_encoding_row_set_encoding (EphyEncodingRow *self,
+                                EphyEncoding    *encoding)
+{
+       g_return_if_fail (EPHY_IS_ENCODING (encoding));
+
+       self->encoding = encoding;
+       gtk_label_set_text (self->encoding_label,
+                           ephy_encoding_get_title_elided (encoding));
+}
+
+EphyEncoding *
+ephy_encoding_row_get_encoding (EphyEncodingRow *row)
+{
+       return row->encoding;
+}
+
+static void
+ephy_encoding_row_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+       switch (prop_id)
+       {
+       case PROP_ENCODING:
+               ephy_encoding_row_set_encoding (EPHY_ENCODING_ROW (object),
+                                               g_value_get_object (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+ephy_encoding_row_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+       switch (prop_id)
+       {
+       case PROP_ENCODING:
+               g_value_set_object (value, EPHY_ENCODING_ROW (object)->encoding);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+ephy_encoding_row_class_init (EphyEncodingRowClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+       /* class creation */
+       object_class->set_property = ephy_encoding_row_set_property;
+       object_class->get_property = ephy_encoding_row_get_property;
+
+       obj_properties[PROP_ENCODING] =
+               g_param_spec_object ("encoding",
+                                    "encoding",
+                                    "encoding",
+                                    EPHY_TYPE_ENCODING,
+                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+       g_object_class_install_properties (object_class, LAST_PROP, obj_properties);
+
+       /* load from UI file */
+       gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/epiphany/encoding-row.ui");
+
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingRow, encoding_label);
+       gtk_widget_class_bind_template_child (widget_class, EphyEncodingRow, selected_image);
+}
+
+EphyEncodingRow *
+ephy_encoding_row_new (EphyEncoding *encoding)
+{
+       return g_object_new (EPHY_TYPE_ENCODING_ROW,
+                            "encoding", encoding,
+                            NULL);
+}
diff --git a/src/ephy-encoding-row.h b/src/ephy-encoding-row.h
new file mode 100644
index 0000000..4b85361
--- /dev/null
+++ b/src/ephy-encoding-row.h
@@ -0,0 +1,40 @@
+/*
+ *  Copyright © 2015 Arnaud Bonatti
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef EPHY_ENCODING_ROW_H
+#define EPHY_ENCODING_ROW_H
+
+#include "ephy-encoding.h"
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_ENCODING_ROW (ephy_encoding_row_get_type ())
+G_DECLARE_FINAL_TYPE (EphyEncodingRow, ephy_encoding_row, EPHY, ENCODING_ROW, GtkGrid);
+
+EphyEncodingRow *ephy_encoding_row_new          (EphyEncoding    *encoding);
+
+EphyEncoding    *ephy_encoding_row_get_encoding (EphyEncodingRow *row);
+
+void             ephy_encoding_row_set_selected (EphyEncodingRow *row,
+                                                 gboolean         selected);
+
+G_END_DECLS
+
+#endif /* EPHY_ENCODING_ROW_H */
diff --git a/src/ephy-window.c b/src/ephy-window.c
index ec832cd..d52fa88 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -30,7 +30,6 @@
 #include "ephy-embed-shell.h"
 #include "ephy-embed-type-builtins.h"
 #include "ephy-embed-utils.h"
-#include "ephy-encoding-menu.h"
 #include "ephy-file-helpers.h"
 #include "ephy-find-toolbar.h"
 #include "ephy-gui.h"
@@ -154,7 +153,8 @@ static const GtkActionEntry ephy_menu_entries [] = {
          G_CALLBACK (window_cmd_view_zoom_out) },
        { "ViewZoomNormal", NULL, N_("_Normal Size"), "<control>0", NULL,
          G_CALLBACK (window_cmd_view_zoom_normal) },
-       { "ViewEncoding", NULL, N_("Text _Encoding"), NULL, NULL, NULL },
+       { "ViewEncoding", NULL, N_("Text _Encoding"), NULL, NULL,
+         G_CALLBACK (window_cmd_view_encoding) },
        { "ViewPageSource", NULL, N_("_Page Source"), "<control>U", NULL,
          G_CALLBACK (window_cmd_view_page_source) },
 
@@ -361,7 +361,6 @@ struct _EphyWindowPrivate
        GtkActionGroup *popups_action_group;
        GtkActionGroup *toolbar_action_group;
        GtkActionGroup *tab_accels_action_group;
-       EphyEncodingMenu *enc_menu;
        GtkNotebook *notebook;
        EphyEmbed *active_embed;
        EphyWindowChrome chrome;
@@ -1161,7 +1160,7 @@ setup_ui_manager (EphyWindow *window)
        g_object_set (action, "is_important", TRUE, NULL);
 
        action = gtk_action_group_get_action (action_group, "ViewEncoding");
-       g_object_set (action, "hide_if_empty", FALSE, NULL);
+       g_object_set (action, "short_label", _("Encodings…"), NULL);
        action = gtk_action_group_get_action (action_group, "ViewZoomIn");
        /* Translators: This refers to text size */
        g_object_set (action, "short-label", _("Larger"), NULL);
@@ -2972,9 +2971,6 @@ ephy_window_dispose (GObject *object)
                popups = gtk_ui_manager_get_toplevels (window->priv->manager, GTK_UI_MANAGER_POPUP);
                g_slist_foreach (popups, (GFunc) gtk_menu_shell_deactivate, NULL);
                g_slist_free (popups);
-       
-               g_object_unref (priv->enc_menu);
-               priv->enc_menu = NULL;
 
                priv->action_group = NULL;
                priv->popups_action_group = NULL;
@@ -3410,8 +3406,6 @@ ephy_window_constructor (GType type,
        g_object_unref (css_provider);
 
        /* Initialize the menus */
-       priv->enc_menu = ephy_encoding_menu_new (window);
-
        ephy_bookmarks_ui_attach_window (window);
 
        /* other notifiers */
diff --git a/src/epiphany.gresource.xml b/src/epiphany.gresource.xml
index 7dc6bfd..32e7d8f 100644
--- a/src/epiphany.gresource.xml
+++ b/src/epiphany.gresource.xml
@@ -4,6 +4,7 @@
     <file>incognito.png</file>
     <file preprocess="xml-stripblanks" compressed="true">bookmark-properties.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">encoding-dialog.ui</file>
+    <file preprocess="xml-stripblanks" compressed="true">encoding-row.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">prefs-dialog.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">prefs-lang-dialog.ui</file>
     <file preprocess="xml-stripblanks" compressed="true">clear-data-dialog.ui</file>
diff --git a/src/resources/encoding-dialog.ui b/src/resources/encoding-dialog.ui
index 5dcfb74..5170705 100644
--- a/src/resources/encoding-dialog.ui
+++ b/src/resources/encoding-dialog.ui
@@ -39,15 +39,94 @@
           </object>
         </child>
         <child>
-          <object class="GtkScrolledWindow" id="scrolled_window">
+          <object class="GtkStack" id="type_stack">
             <property name="visible">True</property>
-            <property name="expand">True</property>
-            <property name="hscrollbar_policy">never</property>
-            <property name="shadow_type">in</property>
-            <property name="min_content_height">300</property>
+            <property name="hhomogeneous">True</property>
+            <property name="interpolate-size">True</property>
+<!--            <property name="transition-type"></property> TODO -->
             <property name="sensitive" bind-source="default_switch" bind-property="active" 
bind-flags="invert-boolean"/>
+            <property name="visible-child">suggested_grid</property>
             <child>
-              <placeholder/>
+              <object class="GtkGrid" id="suggested_grid">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="row-spacing">16</property>
+                <child>
+                  <object class="GtkGrid" id="recent_grid">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <property name="row-spacing">8</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="halign">start</property>
+                        <property name="margin-start">8</property>
+                        <property name="use-markup">True</property>
+                        <property name="label" translatable="yes">&#60;b&#62;Recent 
encodings&#60;/b&#62;</property> <!-- TODO better -->
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBox" id="recent_list_box">
+                        <property name="visible">True</property>
+                        <property name="expand">True</property>
+                           <signal name="row-activated" handler="row_activated_cb"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkGrid" id="related_grid">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <property name="row-spacing">8</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="halign">start</property>
+                        <property name="margin-start">8</property>
+                        <property name="use-markup">True</property>
+                        <property name="label" translatable="yes">&#60;b&#62;Related 
encodings&#60;/b&#62;</property> <!-- TODO better -->
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkListBox" id="related_list_box">
+                        <property name="visible">True</property>
+                        <property name="expand">True</property>
+                           <signal name="row-activated" handler="row_activated_cb"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkButton">
+                    <property name="visible">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Show all…</property>
+                    <signal name="clicked" handler="show_all_button_clicked_cb"/>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow">
+                <property name="visible">True</property>
+                <property name="expand">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="shadow_type">in</property>
+                <property name="min_content_height">300</property>
+                <child>
+                  <object class="GtkListBox" id="list_box">
+                    <property name="visible">True</property>
+                    <property name="expand">True</property>
+<!--                    <property name="activate-on-single-click">True</property> TODO useful? -->
+                    <property name="selection-mode">browse</property>
+                    <signal name="row-activated" handler="row_activated_cb"/>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="name">scrolled-window</property>
+              </packing>
             </child>
           </object>
         </child>
diff --git a/src/resources/encoding-row.ui b/src/resources/encoding-row.ui
new file mode 100644
index 0000000..bb639b7
--- /dev/null
+++ b/src/resources/encoding-row.ui
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <template class="EphyEncodingRow" parent="GtkGrid">
+    <property name="visible">True</property> <!-- TODO remove when never called manually -->
+    <property name="halign">center</property>
+    <property name="height-request">30</property>
+    <child>
+      <object class="GtkGrid">
+        <property name="visible">True</property>
+        <property name="vexpand">True</property>
+        <property name="column-spacing">8</property>
+        <child>
+          <object class="GtkLabel" id="encoding_label">
+            <property name="visible">True</property>
+            <property name="vexpand">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkImage" id="selected_image">
+            <property name="icon-name">object-select-symbolic</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/resources/epiphany-ui.xml b/src/resources/epiphany-ui.xml
index 684d553..26e47ac 100644
--- a/src/resources/epiphany-ui.xml
+++ b/src/resources/epiphany-ui.xml
@@ -38,9 +38,7 @@
                        <separator name="BookmarksSep1"/>
                </menu>
                 <separator name="FileSep6"/>
-                <menu name="ViewEncodingMenu" action="ViewEncoding">
-                  <placeholder name="ViewEncodingPlaceholder"/>
-                </menu>
+                <menuitem name="ViewEncodingMenu" action="ViewEncoding"/>
                 <menuitem name="ViewPageSourceMenu" action="ViewPageSource"/>
                 <separator name="FileSep7"/>
                 <menuitem name="HelpContentsMenu" action="HelpContents"/>
diff --git a/src/window-commands.c b/src/window-commands.c
index efec82d..de5e9b9 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -30,6 +30,7 @@
 #include "ephy-embed-shell.h"
 #include "ephy-embed-utils.h"
 #include "ephy-embed.h"
+#include "ephy-encoding-dialog.h"
 #include "ephy-favicon-helpers.h"
 #include "ephy-file-chooser.h"
 #include "ephy-file-helpers.h"
@@ -1692,3 +1693,14 @@ window_cmd_browse_with_caret (GtkAction *action,
        g_settings_set_boolean (EPHY_SETTINGS_MAIN,
                                EPHY_PREFS_ENABLE_CARET_BROWSING, active);
 }
+
+void
+window_cmd_view_encoding (GtkAction *action,
+                          EphyWindow *window)
+{
+       EphyEncodingDialog *dialog;
+
+       dialog = ephy_encoding_dialog_new (window);
+       gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
+       gtk_dialog_run (GTK_DIALOG (dialog));
+}
diff --git a/src/window-commands.h b/src/window-commands.h
index 3c55b6e..d048314 100644
--- a/src/window-commands.h
+++ b/src/window-commands.h
@@ -72,6 +72,8 @@ void window_cmd_edit_find_next            (GtkAction  *action,
                                            EphyWindow *window);
 void window_cmd_edit_find_prev            (GtkAction  *action,
                                            EphyWindow *window);
+void window_cmd_view_encoding             (GtkAction  *action,
+                                           EphyWindow *window);
 void window_cmd_view_fullscreen           (GtkAction  *action,
                                            EphyWindow *window);
 void window_cmd_view_zoom_in              (GtkAction  *action,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]