diff options
-rw-r--r-- | embed/Makefile.am | 2 | ||||
-rw-r--r-- | embed/ephy-encoding.c | 233 | ||||
-rw-r--r-- | embed/ephy-encoding.h | 99 | ||||
-rw-r--r-- | embed/ephy-encodings.c | 223 | ||||
-rw-r--r-- | embed/ephy-encodings.h | 33 | ||||
-rw-r--r-- | src/ephy-encoding-dialog.c | 171 | ||||
-rw-r--r-- | src/ephy-encoding-menu.c | 74 | ||||
-rw-r--r-- | src/prefs-dialog.c | 66 |
8 files changed, 642 insertions, 259 deletions
diff --git a/embed/Makefile.am b/embed/Makefile.am index 63e15fded..f2e7ddcd4 100644 --- a/embed/Makefile.am +++ b/embed/Makefile.am @@ -11,6 +11,7 @@ NOINST_H_FILES = \ ephy-about-handler.h \ ephy-embed-dialog.h \ ephy-embed-private.h \ + ephy-encoding.h \ ephy-encodings.h \ ephy-file-monitor.h \ ephy-request-about.h @@ -46,6 +47,7 @@ libephyembed_la_SOURCES = \ ephy-embed-single.c \ ephy-embed-shell.c \ ephy-embed-utils.c \ + ephy-encoding.c \ ephy-encodings.c \ ephy-file-monitor.c \ ephy-permission-manager.c \ diff --git a/embed/ephy-encoding.c b/embed/ephy-encoding.c new file mode 100644 index 000000000..ad5614002 --- /dev/null +++ b/embed/ephy-encoding.c @@ -0,0 +1,233 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Copyright © 2012 Igalia S.L. + * + * 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.h" + +G_DEFINE_TYPE (EphyEncoding, ephy_encoding, G_TYPE_OBJECT) + +#define EPHY_ENCODING_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_ENCODING, EphyEncodingPrivate)) + +enum { + PROP_0, + + PROP_TITLE, + PROP_TITLE_ELIDED, + PROP_COLLATION_KEY, + PROP_ENCODING, + PROP_LANGUAGE_GROUPS +}; + +struct _EphyEncodingPrivate { + char *title; + char *title_elided; + char *collation_key; + char *encoding; + int language_groups; +}; + +static void +ephy_encoding_finalize (GObject *object) +{ + EphyEncodingPrivate *priv = EPHY_ENCODING (object)->priv; + + g_free (priv->title); + g_free (priv->title_elided); + g_free (priv->collation_key); + g_free (priv->encoding); + + G_OBJECT_CLASS (ephy_encoding_parent_class)->finalize (object); +} + +static void +ephy_encoding_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEncodingPrivate *priv = EPHY_ENCODING (object)->priv; + + switch (prop_id) { + case PROP_TITLE: + g_value_set_string (value, priv->title); + break; + case PROP_TITLE_ELIDED: + g_value_set_string (value, priv->title_elided); + break; + case PROP_COLLATION_KEY: + g_value_set_string (value, priv->collation_key); + break; + case PROP_ENCODING: + g_value_set_string (value, priv->encoding); + break; + case PROP_LANGUAGE_GROUPS: + g_value_set_int (value, priv->language_groups); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_encoding_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEncodingPrivate *priv = EPHY_ENCODING (object)->priv; + + switch (prop_id) { + case PROP_TITLE: + g_free (priv->title); + priv->title = g_strdup (g_value_get_string (value)); + break; + case PROP_TITLE_ELIDED: + g_free (priv->title_elided); + priv->title_elided = g_strdup (g_value_get_string (value)); + break; + case PROP_COLLATION_KEY: + g_free (priv->collation_key); + priv->collation_key = g_strdup (g_value_get_string (value)); + break; + case PROP_ENCODING: + g_free (priv->encoding); + priv->encoding = g_strdup (g_value_get_string (value)); + break; + case PROP_LANGUAGE_GROUPS: + priv->language_groups = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_encoding_class_init (EphyEncodingClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = ephy_encoding_finalize; + gobject_class->get_property = ephy_encoding_get_property; + gobject_class->set_property = ephy_encoding_set_property; + + g_object_class_install_property (gobject_class, + PROP_TITLE, + g_param_spec_string ("title", + "Title", + "The encoding's title", + "", + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_TITLE_ELIDED, + g_param_spec_string ("title-elided", + "Title Elided", + "The encoding's elided title", + "", + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_COLLATION_KEY, + g_param_spec_string ("collation-key", + "Collation Key", + "The encoding's collation key", + "", + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (gobject_class, + PROP_ENCODING, + g_param_spec_string ("encoding", + "Encoding", + "The encoding's encoding", + "", + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + g_object_class_install_property (gobject_class, + PROP_LANGUAGE_GROUPS, + g_param_spec_int ("language-groups", + "Language Groups", + "The encoding's language groups", + LG_NONE, LG_ALL, + LG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (gobject_class, sizeof (EphyEncodingPrivate)); +} + +static void +ephy_encoding_init (EphyEncoding *encoding) +{ + encoding->priv = EPHY_ENCODING_GET_PRIVATE (encoding); +} + +const char * +ephy_encoding_get_title (EphyEncoding *encoding) +{ + g_return_val_if_fail (EPHY_IS_ENCODING (encoding), NULL); + + return encoding->priv->title; +} + +const char * +ephy_encoding_get_title_elided (EphyEncoding *encoding) +{ + g_return_val_if_fail (EPHY_IS_ENCODING (encoding), NULL); + + return encoding->priv->title_elided; +} + +const char * +ephy_encoding_get_collation_key (EphyEncoding *encoding) +{ + g_return_val_if_fail (EPHY_IS_ENCODING (encoding), NULL); + + return encoding->priv->collation_key; +} + +const char * +ephy_encoding_get_encoding (EphyEncoding *encoding) +{ + g_return_val_if_fail (EPHY_IS_ENCODING (encoding), NULL); + + return encoding->priv->encoding; +} + +int +ephy_encoding_get_language_groups (EphyEncoding *encoding) +{ + g_return_val_if_fail (EPHY_IS_ENCODING (encoding), LG_NONE); + + return encoding->priv->language_groups; +} + +EphyEncoding * +ephy_encoding_new (const char *encoding, const char *title, + const char *title_elided, const char *collation_key, + int language_groups) +{ + return g_object_new (EPHY_TYPE_ENCODING, + "encoding", encoding, + "title", title, + "title-elided", title_elided, + "collation-key", collation_key, + "language-groups", language_groups, + NULL); +} diff --git a/embed/ephy-encoding.h b/embed/ephy-encoding.h new file mode 100644 index 000000000..f27c132bb --- /dev/null +++ b/embed/ephy-encoding.h @@ -0,0 +1,99 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Copyright © 2012 Igalia S.L. + * + * 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. + * + */ + +#if !defined (__EPHY_EPIPHANY_H_INSIDE__) && !defined (EPIPHANY_COMPILATION) +#error "Only <epiphany/epiphany.h> can be included directly." +#endif + +#ifndef EPHY_ENCODING_H +#define EPHY_ENCODING_H + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_ENCODING (ephy_encoding_get_type ()) +#define EPHY_ENCODING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_ENCODING, EphyEncoding)) +#define EPHY_ENCODING_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_ENCODING, EphyEncodingClass)) +#define EPHY_IS_ENCODING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_ENCODING)) +#define EPHY_IS_ENCODING_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_ENCODING)) +#define EPHY_ENCODING_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_ENCODING, EphyEncodingClass)) + +typedef struct _EphyEncodingClass EphyEncodingClass; +typedef struct _EphyEncoding EphyEncoding; +typedef struct _EphyEncodingPrivate EphyEncodingPrivate; + +struct _EphyEncoding +{ + GObject parent; + + /*< private >*/ + EphyEncodingPrivate *priv; +}; + +struct _EphyEncodingClass +{ + GObjectClass parent_class; +}; + +typedef enum +{ + LG_NONE = 0, + LG_ARABIC = 1 << 0, + LG_BALTIC = 1 << 1, + LG_CAUCASIAN = 1 << 2, + LG_C_EUROPEAN = 1 << 3, + LG_CHINESE_TRAD = 1 << 4, + LG_CHINESE_SIMP = 1 << 5, + LG_CYRILLIC = 1 << 6, + LG_GREEK = 1 << 7, + LG_HEBREW = 1 << 8, + LG_INDIAN = 1 << 9, + LG_JAPANESE = 1 << 10, + LG_KOREAN = 1 << 12, + LG_NORDIC = 1 << 13, + LG_PERSIAN = 1 << 14, + LG_SE_EUROPEAN = 1 << 15, + LG_THAI = 1 << 16, + LG_TURKISH = 1 << 17, + LG_UKRAINIAN = 1 << 18, + LG_UNICODE = 1 << 19, + LG_VIETNAMESE = 1 << 20, + LG_WESTERN = 1 << 21, + LG_ALL = 0x3fffff, +} + EphyLanguageGroup; + +GType ephy_encoding_get_type (void); +EphyEncoding * ephy_encoding_new (const char *encoding, + const char *title, + const char *title_elided, + const char *collation_key, + int language_groups); +const char * ephy_encoding_get_title (EphyEncoding *encoding); +const char * ephy_encoding_get_title_elided (EphyEncoding *encoding); +const char * ephy_encoding_get_encoding (EphyEncoding *encoding); +const char * ephy_encoding_get_collation_key (EphyEncoding *encoding); +int ephy_encoding_get_language_groups (EphyEncoding *encoding); + +G_END_DECLS + +#endif diff --git a/embed/ephy-encodings.c b/embed/ephy-encodings.c index d980094ed..511efc42b 100644 --- a/embed/ephy-encodings.c +++ b/embed/ephy-encodings.c @@ -23,8 +23,6 @@ #include "ephy-encodings.h" #include "ephy-debug.h" -#include "ephy-file-helpers.h" -#include "ephy-node-db.h" #include "ephy-prefs.h" #include "ephy-settings.h" @@ -35,9 +33,6 @@ struct _EphyEncodingsPrivate { - EphyNodeDb *db; - EphyNode *root; - EphyNode *encodings; GHashTable *hash; GSList *recent; }; @@ -140,12 +135,6 @@ encoding_entries [] = { N_("Unicode (UTF-3_2 LE)"), "UTF-32LE", 0 }, }; -enum -{ - ALL_NODE_ID = 2, - ENCODINGS_NODE_ID = 3, -}; - #define RECENT_MAX 4 G_DEFINE_TYPE (EphyEncodings, ephy_encodings, G_TYPE_OBJECT) @@ -157,14 +146,9 @@ ephy_encodings_finalize (GObject *object) g_hash_table_destroy (encodings->priv->hash); - ephy_node_unref (encodings->priv->encodings); - ephy_node_unref (encodings->priv->root); - - g_slist_foreach (encodings->priv->recent, (GFunc) g_free, NULL); + g_slist_foreach (encodings->priv->recent, (GFunc)g_free, NULL); g_slist_free (encodings->priv->recent); - g_object_unref (encodings->priv->db); - LOG ("EphyEncodings finalised"); G_OBJECT_CLASS (ephy_encodings_parent_class)->finalize (object); @@ -177,6 +161,20 @@ ephy_encodings_class_init (EphyEncodingsClass *klass) object_class->finalize = ephy_encodings_finalize; + /** + * EphyEncodings::encoding-added: + * + * The ::encoding-added signal is emitted when @encodings receives a new encoding. + **/ + g_signal_new ("encoding-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, G_TYPE_OBJECT); + g_type_class_add_private (object_class, sizeof (EphyEncodingsPrivate)); } @@ -209,77 +207,80 @@ elide_underscores (const char *original) return result; } -static EphyNode * +static EphyEncoding * add_encoding (EphyEncodings *encodings, const char *title, const char *code, EphyLanguageGroup groups) { - EphyNode *node; - char *elided, *normalised; - GValue value = { 0, }; - - node = ephy_node_new (encodings->priv->db); - - ephy_node_set_property_string (node, EPHY_NODE_ENCODING_PROP_TITLE, - title); + EphyEncoding *encoding; + char *elided, *collate_key, *normalised; + /* Create node. */ elided = elide_underscores (title); normalised = g_utf8_normalize (elided, -1, G_NORMALIZE_DEFAULT); + collate_key = g_utf8_collate_key (normalised, -1); - g_value_init (&value, G_TYPE_STRING); - g_value_take_string (&value, g_utf8_collate_key (normalised, -1)); - ephy_node_set_property (node, EPHY_NODE_ENCODING_PROP_COLLATION_KEY, &value); - g_value_unset (&value); - - g_free (normalised); + encoding = ephy_encoding_new (code, title, + normalised, collate_key, + groups); + /* Add it. */ + g_hash_table_insert (encodings->priv->hash, g_strdup (code), encoding); - g_value_init (&value, G_TYPE_STRING); - g_value_take_string (&value, elided); - ephy_node_set_property (node, EPHY_NODE_ENCODING_PROP_TITLE_ELIDED, &value); - g_value_unset (&value); + g_signal_emit_by_name (encodings, "encoding-added", encoding); - ephy_node_set_property_string (node, EPHY_NODE_ENCODING_PROP_ENCODING, - code); - - ephy_node_set_property_int (node, - EPHY_NODE_ENCODING_PROP_LANGUAGE_GROUPS, - groups); - - /* now insert the node in our structure */ - ephy_node_add_child (encodings->priv->root, node); - g_hash_table_insert (encodings->priv->hash, g_strdup (code), node); - - ephy_node_add_child (encodings->priv->encodings, node); + g_free (collate_key); + g_free (normalised); + g_free (elided); - return node; + return encoding; } -EphyNode * -ephy_encodings_get_node (EphyEncodings *encodings, - const char *code, - gboolean add_if_not_found) +EphyEncoding * +ephy_encodings_get_encoding (EphyEncodings *encodings, + const char *code, + gboolean add_if_not_found) { - EphyNode *node; + EphyEncoding *encoding; g_return_val_if_fail (EPHY_IS_ENCODINGS (encodings), NULL); - node = g_hash_table_lookup (encodings->priv->hash, code); + encoding = g_hash_table_lookup (encodings->priv->hash, code); /* if it doesn't exist, add a node for it */ - if (!EPHY_IS_NODE (node) && add_if_not_found) + if (!EPHY_IS_ENCODING (encoding) && add_if_not_found) { char *title; - /* translators: this is the title that an unknown encoding will + /* Translators: this is the title that an unknown encoding will * be displayed as. */ title = g_strdup_printf (_("Unknown (%s)"), code); - node = add_encoding (encodings, title, code, 0); + encoding = add_encoding (encodings, title, code, 0); g_free (title); } - return node; + return encoding; +} + +typedef struct { + GList *list; + EphyLanguageGroup group_mask; +} GetEncodingsData; + +static void +get_encodings_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + GetEncodingsData *data = (GetEncodingsData*)user_data; + EphyLanguageGroup group; + + group = ephy_encoding_get_language_groups (EPHY_ENCODING (value)); + if ((group & data->group_mask) != 0) + { + data->list = g_list_prepend (data->list, value); + } } GList * @@ -287,35 +288,36 @@ ephy_encodings_get_encodings (EphyEncodings *encodings, EphyLanguageGroup group_mask) { GList *list = NULL; - GPtrArray *children; - int i, n_items; + GetEncodingsData data; - children = ephy_node_get_children (encodings->priv->encodings); - n_items = children->len; - for (i = 0; i < n_items; i++) - { - EphyNode *kid; - EphyLanguageGroup group; - - kid = g_ptr_array_index (children, i); - group = ephy_node_get_property_int - (kid, EPHY_NODE_ENCODING_PROP_LANGUAGE_GROUPS); - - if ((group & group_mask) != 0) - { - list = g_list_prepend (list, kid); - } - } + data.list = list; + data.group_mask = group_mask; + + g_hash_table_foreach (encodings->priv->hash, (GHFunc)get_encodings_foreach, &data); return list; } -EphyNode * +static void +get_all_encodings (gpointer key, + gpointer value, + gpointer user_data) +{ + GList **l = (GList**)user_data; + + *l = g_list_prepend (*l, value); +} + +GList * ephy_encodings_get_all (EphyEncodings *encodings) { + GList *l = NULL; + g_return_val_if_fail (EPHY_IS_ENCODINGS (encodings), NULL); - return encodings->priv->encodings; + g_hash_table_foreach (encodings->priv->hash, (GHFunc)get_all_encodings, &l); + + return l; } void @@ -324,39 +326,41 @@ ephy_encodings_add_recent (EphyEncodings *encodings, { GSList *element, *l; GVariantBuilder builder; + EphyEncodingsPrivate *priv = encodings->priv; g_return_if_fail (EPHY_IS_ENCODINGS (encodings)); g_return_if_fail (code != NULL); - if (ephy_encodings_get_node (encodings, code, FALSE) == NULL) return; + if (ephy_encodings_get_encoding (encodings, code, FALSE) == NULL) + return; - /* keep the list elements unique */ - element = g_slist_find_custom (encodings->priv->recent, code, - (GCompareFunc) strcmp); + /* Keep the list elements unique. */ + element = g_slist_find_custom (priv->recent, code, + (GCompareFunc)strcmp); if (element != NULL) { g_free (element->data); - encodings->priv->recent = - g_slist_remove_link (encodings->priv->recent, element); + priv->recent = + g_slist_remove_link (priv->recent, element); } - /* add the new code upfront */ - encodings->priv->recent = - g_slist_prepend (encodings->priv->recent, g_strdup (code)); + /* Add the new code upfront. */ + priv->recent = + g_slist_prepend (priv->recent, g_strdup (code)); - /* truncate the list if necessary; it's at most 1 element too much */ - if (g_slist_length (encodings->priv->recent) > RECENT_MAX) + /* Truncate the list if necessary; it's at most 1 element too much. */ + if (g_slist_length (priv->recent) > RECENT_MAX) { GSList *tail; - tail = g_slist_last (encodings->priv->recent); + tail = g_slist_last (priv->recent); g_free (tail->data); - encodings->priv->recent = - g_slist_remove_link (encodings->priv->recent, tail); + priv->recent = + g_slist_remove_link (priv->recent, tail); } g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); - for (l = encodings->priv->recent; l; l = l->next) + for (l = priv->recent; l; l = l->next) { g_variant_builder_add (&builder, "s", l->data); } @@ -372,14 +376,16 @@ ephy_encodings_get_recent (EphyEncodings *encodings) GSList *l; GList *list = NULL; + g_return_val_if_fail (EPHY_IS_ENCODINGS (encodings), NULL); + for (l = encodings->priv->recent; l != NULL; l = l->next) { - EphyNode *node; + EphyEncoding *encoding; - node = ephy_encodings_get_node (encodings, (char *) l->data, FALSE); - g_return_val_if_fail (EPHY_IS_NODE (node), NULL); + encoding = ephy_encodings_get_encoding (encodings, (char *)l->data, FALSE); + g_return_val_if_fail (EPHY_IS_ENCODING (encoding), NULL); - list = g_list_prepend (list, node); + list = g_list_prepend (list, encoding); } return list; @@ -388,7 +394,6 @@ ephy_encodings_get_recent (EphyEncodings *encodings) static void ephy_encodings_init (EphyEncodings *encodings) { - EphyNodeDb *db; char **list; int i; @@ -396,17 +401,11 @@ ephy_encodings_init (EphyEncodings *encodings) LOG ("EphyEncodings initialising"); - db = ephy_node_db_new ("EncodingsDB"); - encodings->priv->db = db; - encodings->priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - NULL); - - encodings->priv->root = ephy_node_new_with_id (db, ALL_NODE_ID); - encodings->priv->encodings = ephy_node_new_with_id (db, ENCODINGS_NODE_ID); + (GDestroyNotify)g_free, + (GDestroyNotify)g_object_unref); - /* now fill the db */ + /* Fill the db. */ for (i = 0; i < G_N_ELEMENTS (encoding_entries); i++) { add_encoding (encodings, @@ -415,12 +414,12 @@ ephy_encodings_init (EphyEncodings *encodings) encoding_entries[i].groups); } - /* get the list of recently used encodings */ + /* Get the list of recently used encodings. */ list = g_settings_get_strv (EPHY_SETTINGS_STATE, EPHY_PREFS_STATE_RECENT_ENCODINGS); - /* make sure the list has no duplicates (GtkUIManager goes - * crazy otherwise), and only valid entries + /* Make sure the list has no duplicates (GtkUIManager goes + * crazy otherwise), and only valid entries. */ encodings->priv->recent = NULL; for (i = 0; list[i]; i++) @@ -430,7 +429,7 @@ ephy_encodings_init (EphyEncodings *encodings) if (g_slist_find (encodings->priv->recent, item) == NULL && g_slist_length (encodings->priv->recent) < RECENT_MAX - && ephy_encodings_get_node (encodings, item, FALSE) != NULL) + && ephy_encodings_get_encoding (encodings, item, FALSE) != NULL) { encodings->priv->recent = g_slist_prepend (encodings->priv->recent, diff --git a/embed/ephy-encodings.h b/embed/ephy-encodings.h index 82b556c4a..d7e722156 100644 --- a/embed/ephy-encodings.h +++ b/embed/ephy-encodings.h @@ -27,6 +27,7 @@ #include <glib-object.h> #include <glib.h> +#include "ephy-encoding.h" #include "ephy-node.h" G_BEGIN_DECLS @@ -42,34 +43,6 @@ typedef struct _EphyEncodings EphyEncodings; typedef struct _EphyEncodingsPrivate EphyEncodingsPrivate; typedef struct _EphyEncodingsClass EphyEncodingsClass; -typedef enum -{ - LG_NONE = 0, - LG_ARABIC = 1 << 0, - LG_BALTIC = 1 << 1, - LG_CAUCASIAN = 1 << 2, - LG_C_EUROPEAN = 1 << 3, - LG_CHINESE_TRAD = 1 << 4, - LG_CHINESE_SIMP = 1 << 5, - LG_CYRILLIC = 1 << 6, - LG_GREEK = 1 << 7, - LG_HEBREW = 1 << 8, - LG_INDIAN = 1 << 9, - LG_JAPANESE = 1 << 10, - LG_KOREAN = 1 << 12, - LG_NORDIC = 1 << 13, - LG_PERSIAN = 1 << 14, - LG_SE_EUROPEAN = 1 << 15, - LG_THAI = 1 << 16, - LG_TURKISH = 1 << 17, - LG_UKRAINIAN = 1 << 18, - LG_UNICODE = 1 << 19, - LG_VIETNAMESE = 1 << 20, - LG_WESTERN = 1 << 21, - LG_ALL = 0x3fffff, -} -EphyLanguageGroup; - enum { EPHY_NODE_ENCODING_PROP_TITLE = 1, @@ -96,14 +69,14 @@ GType ephy_encodings_get_type (void); EphyEncodings *ephy_encodings_new (void); -EphyNode *ephy_encodings_get_node (EphyEncodings *encodings, +EphyEncoding *ephy_encodings_get_encoding (EphyEncodings *encodings, const char *code, gboolean add_if_not_found); GList *ephy_encodings_get_encodings (EphyEncodings *encodings, EphyLanguageGroup group_mask); -EphyNode *ephy_encodings_get_all (EphyEncodings *encodings); +GList *ephy_encodings_get_all (EphyEncodings *encodings); void ephy_encodings_add_recent (EphyEncodings *encodings, const char *code); diff --git a/src/ephy-encoding-dialog.c b/src/ephy-encoding-dialog.c index 95a0b070c..58e03f5c3 100644 --- a/src/ephy-encoding-dialog.c +++ b/src/ephy-encoding-dialog.c @@ -2,6 +2,7 @@ /* * Copyright © 2000, 2001, 2002, 2003 Marco Pesenti Gritti * Copyright © 2003, 2004 Christian Persch + * Copyright © 2012 Igalia S.L. * * 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 @@ -30,8 +31,6 @@ #include "ephy-encodings.h" #include "ephy-file-helpers.h" #include "ephy-gui.h" -#include "ephy-node-view.h" -#include "ephy-node.h" #include "ephy-shell.h" #include <glib/gi18n.h> @@ -50,21 +49,59 @@ struct _EphyEncodingDialogPrivate EphyWindow *window; EphyEmbed *embed; GtkWidget *enc_view; - EphyNodeFilter *filter; - EphyNode *selected_node; gboolean update_tag; + char *selected_encoding; }; -static void ephy_encoding_dialog_class_init (EphyEncodingDialogClass *klass); -static void ephy_encoding_dialog_init (EphyEncodingDialog *ge); - +enum { + COL_TITLE_ELIDED, + COL_ENCODING, + NUM_COLS +}; + G_DEFINE_TYPE (EphyEncodingDialog, ephy_encoding_dialog, EPHY_TYPE_EMBED_DIALOG) static void +select_encoding_row (GtkTreeView *view, 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); + + target_encoding = ephy_encoding_get_encoding (encoding); + + while (valid_iter) + { + char *encoding_string = NULL; + + gtk_tree_model_get (model, &iter, + COL_ENCODING, &encoding_string, -1); + + if (g_str_equal (encoding_string, + target_encoding)) + { + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (view); + gtk_tree_selection_select_iter (selection, &iter); + g_free (encoding_string); + + return; + } + + g_free (encoding_string); + valid_iter = gtk_tree_model_iter_next (model, &iter); + } +} + +static void sync_encoding_against_embed (EphyEncodingDialog *dialog) { EphyEmbed *embed; - EphyNode *node; GtkTreeSelection *selection; GtkTreeModel *model; GList *rows; @@ -72,6 +109,7 @@ sync_encoding_against_embed (EphyEncodingDialog *dialog) const char *encoding; gboolean is_automatic = FALSE; WebKitWebView *view; + EphyEncoding *node; dialog->priv->update_tag = TRUE; @@ -92,12 +130,11 @@ sync_encoding_against_embed (EphyEncodingDialog *dialog) } #endif - node = ephy_encodings_get_node (dialog->priv->encodings, encoding, TRUE); - g_assert (EPHY_IS_NODE (node)); + node = ephy_encodings_get_encoding (dialog->priv->encodings, encoding, TRUE); + g_assert (EPHY_IS_ENCODING (node)); - /* select the current encoding in the list view */ - ephy_node_view_select_node (EPHY_NODE_VIEW (dialog->priv->enc_view), - node); + /* Select the current encoding in the list view. */ + select_encoding_row (GTK_TREE_VIEW (dialog->priv->enc_view), node); /* scroll the view so the active encoding is visible */ selection = gtk_tree_view_get_selection @@ -210,12 +247,11 @@ activate_choice (EphyEncodingDialog *dialog) webkit_web_view_set_custom_encoding (view, NULL); #endif } - else if (dialog->priv->selected_node != NULL) + else if (dialog->priv->selected_encoding != NULL) { const char *code; - code = ephy_node_get_property_string (dialog->priv->selected_node, - EPHY_NODE_ENCODING_PROP_ENCODING); + code = dialog->priv->selected_encoding; #ifdef HAVE_WEBKIT2 webkit_web_view_set_custom_charset (view, code); @@ -242,15 +278,28 @@ ephy_encoding_dialog_response_cb (GtkWidget *widget, } static void -view_node_selected_cb (EphyNodeView *view, - EphyNode *node, - EphyEncodingDialog *dialog) +view_row_selected_cb (GtkTreeSelection *selection, + EphyEncodingDialog *dialog) { GtkWidget *button; + GtkTreeModel *model; + GtkTreeIter iter; + EphyEncodingDialogPrivate *priv = dialog->priv; - dialog->priv->selected_node = node; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + char *encoding; + + gtk_tree_model_get (model, &iter, + COL_ENCODING, &encoding, + -1); + + g_free (priv->selected_encoding); + priv->selected_encoding = encoding; + } - if (dialog->priv->update_tag) return; + if (dialog->priv->update_tag) + return; button = ephy_dialog_get_control (EPHY_DIALOG (dialog), "manual_button"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); @@ -259,15 +308,29 @@ view_node_selected_cb (EphyNodeView *view, } static void -view_node_activated_cb (GtkWidget *view, - EphyNode *node, - EphyEncodingDialog *dialog) +view_row_activated_cb (GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + EphyEncodingDialog *dialog) { GtkWidget *button; + GtkTreeIter iter; + char *encoding; + GtkTreeModel *model; + EphyEncodingDialogPrivate *priv = dialog->priv; - dialog->priv->selected_node = node; + model = gtk_tree_view_get_model (treeview); - if (dialog->priv->update_tag) return; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get (model, &iter, + COL_ENCODING, &encoding, + -1); + + g_free (priv->selected_encoding); + priv->selected_encoding = encoding; + + if (dialog->priv->update_tag) + return; button = ephy_dialog_get_control (EPHY_DIALOG (dialog), "manual_button"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); @@ -292,7 +355,10 @@ ephy_encoding_dialog_init (EphyEncodingDialog *dialog) { GtkWidget *treeview, *scroller, *button, *window, *child; GtkTreeSelection *selection; - EphyNode *node; + GList *encodings, *p; + GtkListStore *store; + GtkTreeIter iter; + GtkCellRenderer *renderer; dialog->priv = EPHY_ENCODING_DIALOG_GET_PRIVATE (dialog); @@ -310,32 +376,47 @@ ephy_encoding_dialog_init (EphyEncodingDialog *dialog) g_signal_connect (window, "response", G_CALLBACK (ephy_encoding_dialog_response_cb), dialog); - dialog->priv->filter = ephy_node_filter_new (); + encodings = ephy_encodings_get_all (dialog->priv->encodings); + store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING); + 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_free (encodings); - node = ephy_encodings_get_all (dialog->priv->encodings); - treeview = ephy_node_view_new (node, dialog->priv->filter); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COL_TITLE_ELIDED, + GTK_SORT_ASCENDING); - ephy_node_view_add_column (EPHY_NODE_VIEW (treeview), _("Encodings"), - G_TYPE_STRING, - EPHY_NODE_ENCODING_PROP_TITLE_ELIDED, - EPHY_NODE_VIEW_SEARCHABLE, - NULL, NULL); + treeview = gtk_tree_view_new (); + renderer = gtk_cell_renderer_text_new (); - ephy_node_view_set_sort (EPHY_NODE_VIEW (treeview), G_TYPE_STRING, - EPHY_NODE_ENCODING_PROP_TITLE_ELIDED, - GTK_SORT_ASCENDING); + 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)); 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), + g_signal_connect (selection, "changed", + G_CALLBACK (view_row_selected_cb), dialog); - g_signal_connect (G_OBJECT (treeview), - "node_activated", - G_CALLBACK (view_node_activated_cb), + g_signal_connect (treeview, "row-activated", + G_CALLBACK (view_row_activated_cb), dialog); gtk_widget_show (treeview); @@ -382,7 +463,7 @@ ephy_encoding_dialog_finalize (GObject *object) dialog); } - g_object_unref (dialog->priv->filter); + g_free (dialog->priv->selected_encoding); G_OBJECT_CLASS (ephy_encoding_dialog_parent_class)->finalize (object); } diff --git a/src/ephy-encoding-menu.c b/src/ephy-encoding-menu.c index 86fe2c293..e276f4a2c 100644 --- a/src/ephy-encoding-menu.c +++ b/src/ephy-encoding-menu.c @@ -81,26 +81,23 @@ ephy_encoding_menu_init (EphyEncodingMenu *menu) static int sort_encodings (gconstpointer a, gconstpointer b) { - EphyNode *node1 = (EphyNode *) a; - EphyNode *node2 = (EphyNode *) b; + EphyEncoding *enc1 = (EphyEncoding*)a; + EphyEncoding *enc2 = (EphyEncoding*)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); + key1 = ephy_encoding_get_collation_key (enc1); + key2 = ephy_encoding_get_collation_key (enc2); return strcmp (key1, key2); } static void -add_menu_item (EphyNode *node, EphyEncodingMenu *menu) +add_menu_item (EphyEncoding *encoding, EphyEncodingMenu *menu) { const char *code; char action[128], name[128]; - code = ephy_node_get_property_string - (node, EPHY_NODE_ENCODING_PROP_ENCODING); + code = ephy_encoding_get_encoding (encoding); g_snprintf (action, sizeof (action), "Encoding%s", code); g_snprintf (name, sizeof (name), "%sItem", action); @@ -119,7 +116,7 @@ update_encoding_menu_cb (GtkAction *dummy, EphyEncodingMenu *menu) GtkAction *action; char name[128]; const char *encoding; - EphyNode *enc_node; + EphyEncoding *enc_node; GList *recent, *related = NULL, *l; EphyLanguageGroup groups; gboolean is_automatic = FALSE; @@ -151,8 +148,8 @@ update_encoding_menu_cb (GtkAction *dummy, EphyEncodingMenu *menu) } #endif - enc_node = ephy_encodings_get_node (p->encodings, encoding, TRUE); - g_assert (EPHY_IS_NODE (enc_node)); + enc_node = ephy_encodings_get_encoding (p->encodings, encoding, TRUE); + g_assert (EPHY_IS_ENCODING (enc_node)); action = gtk_action_group_get_action (p->action_group, "ViewEncodingAutomatic"); @@ -165,11 +162,10 @@ update_encoding_menu_cb (GtkAction *dummy, EphyEncodingMenu *menu) gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE); /* get encodings related to the current encoding */ - groups = ephy_node_get_property_int - (enc_node, EPHY_NODE_ENCODING_PROP_LANGUAGE_GROUPS); + groups = ephy_encoding_get_language_groups (enc_node); related = ephy_encodings_get_encodings (p->encodings, groups); - related = g_list_sort (related, (GCompareFunc) sort_encodings); + 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 @@ -186,7 +182,7 @@ update_encoding_menu_cb (GtkAction *dummy, EphyEncodingMenu *menu) recent = g_list_remove (recent, l->data); } - recent = g_list_sort (recent, (GCompareFunc) sort_encodings); + recent = g_list_sort (recent, (GCompareFunc)sort_encodings); build_menu: /* clear the menu */ @@ -210,14 +206,14 @@ build_menu: "Sep1Item", "Sep1", GTK_UI_MANAGER_SEPARATOR, FALSE); - g_list_foreach (recent, (GFunc) add_menu_item, menu); + 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); + g_list_foreach (related, (GFunc)add_menu_item, menu); gtk_ui_manager_add_ui (p->manager, p->merge_id, ENCODING_PLACEHOLDER_PATH, @@ -268,20 +264,18 @@ encoding_activate_cb (GtkAction *action, EphyEncodingMenu *menu) } static void -add_action (EphyNode *encodings, EphyNode *node, EphyEncodingMenu *menu) +add_action (EphyEncodings *encodings, EphyEncoding *encoding, EphyEncodingMenu *menu) { GtkAction *action; - char name[128]; - const char *encoding, *title; + char name[128] = ""; + const char *encoding_str, *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); + encoding_str = ephy_encoding_get_encoding (encoding); + title = ephy_encoding_get_title (encoding); - LOG ("add_action for encoding '%s'", encoding); + LOG ("add_action for encoding '%s'", encoding_str); - g_snprintf (name, sizeof (name), "Encoding%s", encoding); + g_snprintf (name, sizeof (name), "Encoding%s", encoding_str); action = g_object_new (GTK_TYPE_RADIO_ACTION, "name", name, @@ -361,9 +355,7 @@ ephy_encoding_menu_set_window (EphyEncodingMenu *menu, EphyWindow *window) { GtkActionGroup *action_group; GtkAction *action; - EphyNode *encodings; - GPtrArray *children; - int i; + GList *encodings, *p; g_return_if_fail (EPHY_IS_WINDOW (window)); @@ -381,23 +373,21 @@ ephy_encoding_menu_set_window (EphyEncodingMenu *menu, EphyWindow *window) /* add actions for the existing encodings */ encodings = ephy_encodings_get_all (menu->priv->encodings); - children = ephy_node_get_children (encodings); - for (i = 0; i < children->len; i++) + for (p = encodings; p; p = p->next) { - EphyNode *encoding; + EphyEncoding *encoding; - encoding = (EphyNode *) g_ptr_array_index (children, i); - add_action (encodings, encoding, menu); + encoding = (EphyEncoding *)p->data; + add_action (menu->priv->encodings, encoding, menu); } + g_list_free (encodings); - /* when we encounter an unknown encoding, it is added to the database, - * so we need to listen to child_added on the encodings node to - * add an action for it + /* When we encounter an unknown encoding, it is added to the + * database, so we need to listen to child_added on the + * encodings node to add an action for it. */ - ephy_node_signal_connect_object (encodings, - EPHY_NODE_CHILD_ADDED, - (EphyNodeCallback) add_action, - G_OBJECT (menu)); + g_signal_connect (menu->priv->encodings, "encoding-added", + G_CALLBACK (add_action), menu); gtk_ui_manager_insert_action_group (menu->priv->manager, action_group, 0); diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c index c1e11a918..f95620031 100644 --- a/src/prefs-dialog.c +++ b/src/prefs-dialog.c @@ -39,8 +39,6 @@ #include "ephy-session.h" #include "ephy-settings.h" #include "ephy-shell.h" -#include "ephy-tree-model-node.h" -#include "ephy-tree-model-sort.h" #include "pdm-dialog.h" #include <glib/gi18n.h> @@ -75,6 +73,12 @@ struct PrefsDialogPrivate GHashTable *iso_3166_table; }; +enum { + COL_TITLE_ELIDED, + COL_ENCODING, + NUM_COLS +}; + G_DEFINE_TYPE (PrefsDialog, prefs_dialog, EPHY_TYPE_DIALOG) static void @@ -214,19 +218,17 @@ combo_set_mapping (const GValue *value, static void create_node_combo (EphyDialog *dialog, EphyEncodings *encodings, - EphyNode *node, const char *default_value) { - EphyTreeModelNode *nodemodel; - GtkTreeModel *sortmodel; GtkComboBox *combo; GtkCellRenderer *renderer; + GtkListStore *store; + GList *all_encodings, *p; char *code; - int title_col; code = g_settings_get_string (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_DEFAULT_ENCODING); - if (code == NULL || ephy_encodings_get_node (encodings, code, FALSE) == NULL) + if (code == NULL || ephy_encodings_get_encoding (encodings, code, FALSE) == NULL) { /* safe default */ g_settings_set_string (EPHY_SETTINGS_WEB, @@ -238,26 +240,34 @@ create_node_combo (EphyDialog *dialog, combo = GTK_COMBO_BOX (ephy_dialog_get_control (dialog, "default_encoding_combo")); - nodemodel = ephy_tree_model_node_new (node); - - title_col = ephy_tree_model_node_add_prop_column - (nodemodel, G_TYPE_STRING, EPHY_NODE_ENCODING_PROP_TITLE_ELIDED); - - ephy_tree_model_node_add_prop_column - (nodemodel, G_TYPE_STRING, EPHY_NODE_ENCODING_PROP_ENCODING); - - sortmodel = ephy_tree_model_sort_new (GTK_TREE_MODEL (nodemodel)); - - gtk_tree_sortable_set_sort_column_id - (GTK_TREE_SORTABLE (sortmodel), title_col, GTK_SORT_ASCENDING); + store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_STRING); + all_encodings = ephy_encodings_get_all (encodings); + for (p = all_encodings; p; p = p->next) + { + GtkTreeIter iter; + 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_free (all_encodings); - gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sortmodel)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), COL_TITLE_ELIDED, + GTK_SORT_ASCENDING); + gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, - "text", title_col, - NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, + "text", COL_TITLE_ELIDED, + NULL); g_settings_bind_with_mapping (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_DEFAULT_ENCODING, @@ -267,9 +277,6 @@ create_node_combo (EphyDialog *dialog, combo_set_mapping, combo, NULL); - - g_object_unref (nodemodel); - g_object_unref (sortmodel); } static void @@ -1082,8 +1089,7 @@ prefs_dialog_init (PrefsDialog *pd) encodings = EPHY_ENCODINGS (ephy_embed_shell_get_encodings (EPHY_EMBED_SHELL (ephy_shell))); - create_node_combo (dialog, encodings, - ephy_encodings_get_all (encodings), "ISO-8859-1"); + create_node_combo (dialog, encodings, "ISO-8859-1"); create_language_section (dialog); |