Initial import of ephy (rev# 7126) from svn
[ephy-soc.git] / embed / .svn / text-base / ephy-encodings.c.svn-base
blob7172dad6436139129164bee9aa2959c5491bc8ff
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  *  Copyright © 2003 Marco Pesenti Gritti
4  *  Copyright © 2003 Christian Persch
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2, or (at your option)
9  *  any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  *  $Id$
21  */
23 #include "config.h"
25 #include "ephy-encodings.h"
26 #include "ephy-node-db.h"
27 #include "ephy-file-helpers.h"
28 #include "eel-gconf-extensions.h"
29 #include "ephy-debug.h"
31 #include <glib/gi18n.h>
32 #include <string.h>
34 #define EPHY_ENCODINGS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_ENCODINGS, EphyEncodingsPrivate))
36 struct _EphyEncodingsPrivate
38         EphyNodeDb *db;
39         EphyNode *root;
40         EphyNode *encodings;
41         EphyNode *detectors;
42         GHashTable *hash;
43         GSList *recent;
46 /**
47  * translatable encodings titles
48  * NOTE: if you add/remove/change encodings, please also update the schema in
49  * epiphany.schemas.in
50  */
51 static const 
52 struct
54         char *title;
55         char *code;
56         EphyLanguageGroup groups;
57         gboolean is_autodetector;
59 encoding_entries [] =
60
61         { N_("Arabic (_IBM-864)"),                  "IBM864",                LG_ARABIC,         FALSE },
62         { N_("Arabic (ISO-_8859-6)"),               "ISO-8859-6",            LG_ARABIC,         FALSE },
63         { N_("Arabic (_MacArabic)"),                "x-mac-arabic",          LG_ARABIC,         FALSE },
64         { N_("Arabic (_Windows-1256)"),             "windows-1256",          LG_ARABIC,         FALSE },
65         { N_("Baltic (_ISO-8859-13)"),              "ISO-8859-13",           LG_BALTIC,         FALSE },
66         { N_("Baltic (I_SO-8859-4)"),               "ISO-8859-4",            LG_BALTIC,         FALSE },
67         { N_("Baltic (_Windows-1257)"),             "windows-1257",          LG_BALTIC,         FALSE },
68         { N_("_Armenian (ARMSCII-8)"),              "armscii-8",             LG_CAUCASIAN,      FALSE },
69         { N_("_Georgian (GEOSTD8)"),                "geostd8",               LG_CAUCASIAN,      FALSE },
70         { N_("Central European (_IBM-852)"),        "IBM852",                LG_C_EUROPEAN,     FALSE },
71         { N_("Central European (I_SO-8859-2)"),     "ISO-8859-2",            LG_C_EUROPEAN,     FALSE },
72         { N_("Central European (_MacCE)"),          "x-mac-ce",              LG_C_EUROPEAN,     FALSE },
73         { N_("Central European (_Windows-1250)"),   "windows-1250",          LG_C_EUROPEAN,     FALSE },
74         { N_("Chinese Simplified (_GB18030)"),      "gb18030",               LG_CHINESE_SIMP,   FALSE },
75         { N_("Chinese Simplified (G_B2312)"),       "GB2312",                LG_CHINESE_SIMP,   FALSE },
76         { N_("Chinese Simplified (GB_K)"),          "x-gbk",                 LG_CHINESE_SIMP,   FALSE },
77         { N_("Chinese Simplified (_HZ)"),           "HZ-GB-2312",            LG_CHINESE_SIMP,   FALSE },
78         { N_("Chinese Simplified (_ISO-2022-CN)"),  "ISO-2022-CN",           LG_CHINESE_SIMP,   FALSE },
79         { N_("Chinese Traditional (Big_5)"),        "Big5",                  LG_CHINESE_TRAD,   FALSE },
80         { N_("Chinese Traditional (Big5-HK_SCS)"),  "Big5-HKSCS",            LG_CHINESE_TRAD,   FALSE },
81         { N_("Chinese Traditional (_EUC-TW)"),      "x-euc-tw",              LG_CHINESE_TRAD,   FALSE },
82         { N_("Cyrillic (_IBM-855)"),                "IBM855",                LG_CYRILLIC,       FALSE },
83         { N_("Cyrillic (I_SO-8859-5)"),             "ISO-8859-5",            LG_CYRILLIC,       FALSE },
84         { N_("Cyrillic (IS_O-IR-111)"),             "ISO-IR-111",            LG_CYRILLIC,       FALSE },
85         { N_("Cyrillic (_KOI8-R)"),                 "KOI8-R",                LG_CYRILLIC,       FALSE },
86         { N_("Cyrillic (_MacCyrillic)"),            "x-mac-cyrillic",        LG_CYRILLIC,       FALSE },
87         { N_("Cyrillic (_Windows-1251)"),           "windows-1251",          LG_CYRILLIC,       FALSE },
88         { N_("Cyrillic/_Russian (IBM-866)"),        "IBM866",                LG_CYRILLIC,       FALSE },
89         { N_("Greek (_ISO-8859-7)"),                "ISO-8859-7",            LG_GREEK,          FALSE },
90         { N_("Greek (_MacGreek)"),                  "x-mac-greek",           LG_GREEK,          FALSE },
91         { N_("Greek (_Windows-1253)"),              "windows-1253",          LG_GREEK,          FALSE },
92         { N_("Gujarati (_MacGujarati)"),            "x-mac-gujarati",        LG_INDIAN,         FALSE },
93         { N_("Gurmukhi (Mac_Gurmukhi)"),            "x-mac-gurmukhi",        LG_INDIAN,         FALSE },
94         { N_("Hindi (Mac_Devanagari)"),             "x-mac-devanagari",      LG_INDIAN,         FALSE },
95         { N_("Hebrew (_IBM-862)"),                  "IBM862",                LG_HEBREW,         FALSE },
96         { N_("Hebrew (IS_O-8859-8-I)"),             "ISO-8859-8-I",          LG_HEBREW,         FALSE },
97         { N_("Hebrew (_MacHebrew)"),                "x-mac-hebrew",          LG_HEBREW,         FALSE },
98         { N_("Hebrew (_Windows-1255)"),             "windows-1255",          LG_HEBREW,         FALSE },
99         { N_("_Visual Hebrew (ISO-8859-8)"),        "ISO-8859-8",            LG_HEBREW,         FALSE },
100         { N_("Japanese (_EUC-JP)"),                 "EUC-JP",                LG_JAPANESE,       FALSE },
101         { N_("Japanese (_ISO-2022-JP)"),            "ISO-2022-JP",           LG_JAPANESE,       FALSE },
102         { N_("Japanese (_Shift-JIS)"),              "Shift_JIS",             LG_JAPANESE,       FALSE },
103         { N_("Korean (_EUC-KR)"),                   "EUC-KR",                LG_KOREAN,         FALSE },
104         { N_("Korean (_ISO-2022-KR)"),              "ISO-2022-KR",           LG_KOREAN,         FALSE },
105         { N_("Korean (_JOHAB)"),                    "x-johab",               LG_KOREAN,         FALSE },
106         { N_("Korean (_UHC)"),                      "x-windows-949",         LG_KOREAN,         FALSE },
107         { N_("_Celtic (ISO-8859-14)"),              "ISO-8859-14",           LG_NORDIC,         FALSE },
108         { N_("_Icelandic (MacIcelandic)"),          "x-mac-icelandic",       LG_NORDIC,         FALSE },
109         { N_("_Nordic (ISO-8859-10)"),              "ISO-8859-10",           LG_NORDIC,         FALSE },
110         { N_("_Persian (MacFarsi)"),                "x-mac-farsi",           LG_PERSIAN,        FALSE },
111         { N_("Croatian (Mac_Croatian)"),            "x-mac-croatian",        LG_SE_EUROPEAN,    FALSE },
112         { N_("_Romanian (MacRomanian)"),            "x-mac-romanian",        LG_SE_EUROPEAN,    FALSE },
113         { N_("R_omanian (ISO-8859-16)"),            "ISO-8859-16",           LG_SE_EUROPEAN,    FALSE },
114         { N_("South _European (ISO-8859-3)"),       "ISO-8859-3",            LG_SE_EUROPEAN,    FALSE },
115         { N_("Thai (TIS-_620)"),                    "TIS-620",               LG_THAI,           FALSE },
116         { N_("Thai (IS_O-8859-11)"),                "iso-8859-11",           LG_THAI,           FALSE },
117         { N_("_Thai (Windows-874)"),                "windows-874",           LG_THAI,           FALSE },
118         { N_("Turkish (_IBM-857)"),                 "IBM857",                LG_TURKISH,        FALSE },
119         { N_("Turkish (I_SO-8859-9)"),              "ISO-8859-9",            LG_TURKISH,        FALSE },
120         { N_("Turkish (_MacTurkish)"),              "x-mac-turkish",         LG_TURKISH,        FALSE },
121         { N_("Turkish (_Windows-1254)"),            "windows-1254",          LG_TURKISH,        FALSE },
122         { N_("Unicode (UTF-_8)"),                   "UTF-8",                 LG_UNICODE,        FALSE },
123         { N_("Cyrillic/Ukrainian (_KOI8-U)"),       "KOI8-U",                LG_UKRAINIAN,      FALSE },
124         { N_("Cyrillic/Ukrainian (Mac_Ukrainian)"), "x-mac-ukrainian",       LG_UKRAINIAN,      FALSE },
125         { N_("Vietnamese (_TCVN)"),                 "x-viet-tcvn5712",       LG_VIETNAMESE,     FALSE },
126         { N_("Vietnamese (_VISCII)"),               "VISCII",                LG_VIETNAMESE,     FALSE },
127         { N_("Vietnamese (V_PS)"),                  "x-viet-vps",            LG_VIETNAMESE,     FALSE },
128         { N_("Vietnamese (_Windows-1258)"),         "windows-1258",          LG_VIETNAMESE,     FALSE },
129         { N_("Western (_IBM-850)"),                 "IBM850",                LG_WESTERN,        FALSE },
130         { N_("Western (_ISO-8859-1)"),              "ISO-8859-1",            LG_WESTERN,        FALSE },
131         { N_("Western (IS_O-8859-15)"),             "ISO-8859-15",           LG_WESTERN,        FALSE },
132         { N_("Western (_MacRoman)"),                "x-mac-roman",           LG_WESTERN,        FALSE },
133         { N_("Western (_Windows-1252)"),            "windows-1252",          LG_WESTERN,        FALSE },
135         /* the following encodings are so rarely used that we don't want to pollute the "related"
136          * part of the encodings menu with them, so we set the language group to 0 here
137          */
138         { N_("English (_US-ASCII)"),                "us-ascii",              0,                 FALSE },
139         { N_("Unicode (UTF-_16 BE)"),               "UTF-16BE",              0,                 FALSE },
140         { N_("Unicode (UTF-1_6 LE)"),               "UTF-16LE",              0,                 FALSE },
141         { N_("Unicode (UTF-_32 BE)"),               "UTF-32BE",              0,                 FALSE },
142         { N_("Unicode (UTF-3_2 LE)"),               "UTF-32LE",              0,                 FALSE },
144         /* Translators: The text before the "|" is context to help you decide on
145          * the correct translation. You MUST OMIT it in the translated string. */
146         { N_("autodetectors|Off"),                                                  "",                            LG_NONE,                                                             TRUE },
147         /* Translators: The text before the "|" is context to help you decide on
148          * the correct translation. You MUST OMIT it in the translated string. */
149         { N_("automatically detect ... character encodings|Chinese"),               "zh_parallel_state_machine",   LG_CHINESE_TRAD | LG_CHINESE_SIMP,                                   TRUE },
150         /* Translators: The text before the "|" is context to help you decide on
151          * the correct translation. You MUST OMIT it in the translated string. */
152         { N_("automatically detect ... character encodings|Simplified Chinese"),    "zhcn_parallel_state_machine", LG_CHINESE_SIMP,                                                     TRUE },
153         /* Translators: The text before the "|" is context to help you decide on
154          * the correct translation. You MUST OMIT it in the translated string. */
155         { N_("automatically detect ... character encodings|Traditional Chinese"),   "zhtw_parallel_state_machine", LG_CHINESE_TRAD,                                                     TRUE },
156         /* Translators: The text before the "|" is context to help you decide on
157          * the correct translation. You MUST OMIT it in the translated string. */
158         { N_("automatically detect ... character encodings|East Asian"),            "cjk_parallel_state_machine",  LG_CHINESE_TRAD | LG_CHINESE_SIMP | LG_JAPANESE | LG_KOREAN,         TRUE },
159         /* Translators: The text before the "|" is context to help you decide on
160          * the correct translation. You MUST OMIT it in the translated string. */
161         { N_("automatically detect ... character encodings|Japanese"),              "ja_parallel_state_machine",   LG_JAPANESE,                                                         TRUE },
162         /* Translators: The text before the "|" is context to help you decide on
163          * the correct translation. You MUST OMIT it in the translated string. */
164         { N_("automatically detect ... character encodings|Korean"),                "ko_parallel_state_machine",   LG_KOREAN,                                                           TRUE },
165         /* Translators: The text before the "|" is context to help you decide on
166          * the correct translation. You MUST OMIT it in the translated string. */
167         { N_("automatically detect ... character encodings|Russian"),               "ruprob",                      LG_CYRILLIC | LG_UKRAINIAN,                                          TRUE },
168         /* Translators: The text before the "|" is context to help you decide on
169          * the correct translation. You MUST OMIT it in the translated string. */
170         { N_("automatically detect ... character encodings|Universal"),             "universal_charset_detector",  LG_ALL,                                                              TRUE },
171         /* Translators: The text before the "|" is context to help you decide on
172          * the correct translation. You MUST OMIT it in the translated string. */
173         { N_("automatically detect ... character encodings|Ukrainian"),             "ukprob",                      LG_UKRAINIAN,                                                        TRUE }
175 static const guint n_encoding_entries = G_N_ELEMENTS (encoding_entries);
177 enum
179         ALL_NODE_ID = 2,
180         ENCODINGS_NODE_ID = 3,
181         DETECTORS_NODE_ID = 5
184 #define RECENT_KEY      "/apps/epiphany/general/recent_encodings"
185 #define RECENT_MAX      4
187 static void ephy_encodings_class_init   (EphyEncodingsClass *klass);
188 static void ephy_encodings_init         (EphyEncodings *ma);
190 static GObjectClass *parent_class = NULL;
192 GType
193 ephy_encodings_get_type (void)
195         static GType type = 0;
197         if (G_UNLIKELY (type == 0))
198         {
199                 const GTypeInfo our_info =
200                 {
201                         sizeof (EphyEncodingsClass),
202                         NULL,
203                         NULL,
204                         (GClassInitFunc) ephy_encodings_class_init,
205                         NULL,
206                         NULL,
207                         sizeof (EphyEncodings),
208                         0,
209                         (GInstanceInitFunc) ephy_encodings_init
210                 };
212                 type = g_type_register_static (G_TYPE_OBJECT,
213                                                "EphyEncodings",
214                                                 &our_info, 0);
215         }
217         return type;
220 static void
221 ephy_encodings_finalize (GObject *object)
223         EphyEncodings *encodings = EPHY_ENCODINGS (object);
225         g_hash_table_destroy (encodings->priv->hash);
227         ephy_node_unref (encodings->priv->encodings);
228         ephy_node_unref (encodings->priv->detectors);
229         ephy_node_unref (encodings->priv->root);
231         g_slist_foreach (encodings->priv->recent, (GFunc) g_free, NULL);
232         g_slist_free (encodings->priv->recent);
234         g_object_unref (encodings->priv->db);
236         LOG ("EphyEncodings finalised");
238         G_OBJECT_CLASS (parent_class)->finalize (object);
241 static void
242 ephy_encodings_class_init (EphyEncodingsClass *klass)
244         GObjectClass *object_class = G_OBJECT_CLASS (klass);
246         parent_class = g_type_class_peek_parent (klass);
248         object_class->finalize = ephy_encodings_finalize;
250         g_type_class_add_private (object_class, sizeof (EphyEncodingsPrivate));
253 /* copied from egg-toolbar-editor.c */
254 static char *
255 elide_underscores (const char *original)
257         char *q, *result;
258         const char *p;
259         gboolean last_underscore;
261         q = result = g_malloc (strlen (original) + 1);
262         last_underscore = FALSE;
264         for (p = original; *p; p++)
265         {
266                 if (!last_underscore && *p == '_')
267                 {
268                         last_underscore = TRUE;
269                 }
270                 else
271                 {
272                         last_underscore = FALSE;
273                         *q++ = *p;
274                 }
275         }
277         *q = '\0';
279         return result;
282 static EphyNode *
283 add_encoding (EphyEncodings *encodings,
284               const char *title,
285               const char *code,
286               EphyLanguageGroup groups,
287               gboolean is_autodetector)
289         EphyNode *node;
290         char *elided, *normalised;
291         GValue value = { 0, };
293         node = ephy_node_new (encodings->priv->db);
295         ephy_node_set_property_string (node, EPHY_NODE_ENCODING_PROP_TITLE,
296                                        title);
298         elided = elide_underscores (title);
299         normalised = g_utf8_normalize (elided, -1, G_NORMALIZE_DEFAULT);
301         g_value_init (&value, G_TYPE_STRING);
302         g_value_take_string (&value, g_utf8_collate_key (normalised, -1));
303         ephy_node_set_property (node, EPHY_NODE_ENCODING_PROP_COLLATION_KEY, &value);
304         g_value_unset (&value);
306         g_free (normalised);
308         g_value_init (&value, G_TYPE_STRING);
309         g_value_take_string (&value, elided);
310         ephy_node_set_property (node, EPHY_NODE_ENCODING_PROP_TITLE_ELIDED, &value);
311         g_value_unset (&value);
313         ephy_node_set_property_string (node, EPHY_NODE_ENCODING_PROP_ENCODING,
314                                        code);
316         ephy_node_set_property_int (node,
317                                     EPHY_NODE_ENCODING_PROP_LANGUAGE_GROUPS,
318                                     groups);
319                                     
320         ephy_node_set_property_boolean (node,
321                                         EPHY_NODE_ENCODING_PROP_IS_AUTODETECTOR,
322                                         is_autodetector);
324         /* now insert the node in our structure */
325         ephy_node_add_child (encodings->priv->root, node);
326         g_hash_table_insert (encodings->priv->hash, g_strdup (code), node);
328         if (is_autodetector)
329         {
330                 ephy_node_add_child (encodings->priv->detectors, node);
331         }
332         else
333         {
334                 ephy_node_add_child (encodings->priv->encodings, node);
335         }
337         return node;
340 EphyNode *
341 ephy_encodings_get_node (EphyEncodings *encodings,
342                          const char *code,
343                          gboolean add_if_not_found)
345         EphyNode *node;
347         g_return_val_if_fail (EPHY_IS_ENCODINGS (encodings), NULL);
349         node = g_hash_table_lookup (encodings->priv->hash, code);
351         /* if it doesn't exist, add a node for it */
352         if (!EPHY_IS_NODE (node) && add_if_not_found)
353         {
354                 char *title;
356                 /* translators: this is the title that an unknown encoding will
357                  * be displayed as.
358                  */
359                 title = g_strdup_printf (_("Unknown (%s)"), code);
360                 node = add_encoding (encodings, title, code, 0, FALSE);
361                 g_free (title);
362         }
364         return node;
367 GList *
368 ephy_encodings_get_encodings (EphyEncodings *encodings,
369                               EphyLanguageGroup group_mask)
371         GList *list = NULL;
372         GPtrArray *children;
373         int i, n_items;
375         children = ephy_node_get_children (encodings->priv->encodings);
376         n_items = children->len;
377         for (i = 0; i < n_items; i++)
378         {
379                 EphyNode *kid;
380                 EphyLanguageGroup group;
381                                                                                                                              
382                 kid = g_ptr_array_index (children, i);
383                 group = ephy_node_get_property_int
384                         (kid, EPHY_NODE_ENCODING_PROP_LANGUAGE_GROUPS);
385                                                                                                                               
386                 if ((group & group_mask) != 0)
387                 {
388                         list = g_list_prepend (list, kid);
389                 }
390         }
392         return list;
395 EphyNode *
396 ephy_encodings_get_detectors (EphyEncodings *encodings)
398         g_return_val_if_fail (EPHY_IS_ENCODINGS (encodings), NULL);
400         return encodings->priv->detectors;
403 EphyNode *
404 ephy_encodings_get_all (EphyEncodings *encodings)
406         g_return_val_if_fail (EPHY_IS_ENCODINGS (encodings), NULL);
408         return encodings->priv->encodings;
411 void
412 ephy_encodings_add_recent (EphyEncodings *encodings,
413                            const char *code)
415         GSList *element;
417         g_return_if_fail (EPHY_IS_ENCODINGS (encodings));
418         g_return_if_fail (code != NULL);
419         
420         if (ephy_encodings_get_node (encodings, code, FALSE) == NULL) return;
422         /* keep the list elements unique */
423         element = g_slist_find_custom (encodings->priv->recent, code,
424                                        (GCompareFunc) strcmp);
425         if (element != NULL)
426         {
427                 g_free (element->data);
428                 encodings->priv->recent =
429                         g_slist_remove_link (encodings->priv->recent, element);
430         }
432         /* add the new code upfront */
433         encodings->priv->recent =
434                 g_slist_prepend (encodings->priv->recent, g_strdup (code));
436         /* truncate the list if necessary; it's at most 1 element too much */
437         if (g_slist_length (encodings->priv->recent) > RECENT_MAX)
438         {
439                 GSList *tail;
441                 tail = g_slist_last (encodings->priv->recent);
442                 g_free (tail->data);
443                 encodings->priv->recent =
444                         g_slist_remove_link (encodings->priv->recent, tail);
445         }
447         /* persist the list */
448         eel_gconf_set_string_list (RECENT_KEY, encodings->priv->recent);
451 GList *
452 ephy_encodings_get_recent (EphyEncodings *encodings)
454         GSList *l;
455         GList *list = NULL;
457         for (l = encodings->priv->recent; l != NULL; l = l->next)
458         {
459                 EphyNode *node;
461                 node = ephy_encodings_get_node (encodings, (char *) l->data, FALSE);
462                 g_return_val_if_fail (EPHY_IS_NODE (node), NULL);
464                 list = g_list_prepend (list, node);
465         }
467         return list;
470 static void
471 ephy_encodings_init (EphyEncodings *encodings)
473         EphyNodeDb *db;
474         GSList *list, *l;
475         guint i;
477         encodings->priv = EPHY_ENCODINGS_GET_PRIVATE (encodings);
479         LOG ("EphyEncodings initialising");
481         db = ephy_node_db_new ("EncodingsDB");
482         encodings->priv->db = db;
484         encodings->priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
485                                                        (GDestroyNotify) g_free,
486                                                        NULL);
488         encodings->priv->root = ephy_node_new_with_id (db, ALL_NODE_ID);
489         encodings->priv->encodings = ephy_node_new_with_id (db, ENCODINGS_NODE_ID);
490         encodings->priv->detectors = ephy_node_new_with_id (db, DETECTORS_NODE_ID);
492         /* now fill the db */
493         for (i = 0; i < n_encoding_entries; i++)
494         {
495                 add_encoding (encodings,
496                               encoding_entries[i].is_autodetector
497                                 ? Q_(encoding_entries[i].title)
498                                 : _(encoding_entries[i].title),
499                               encoding_entries[i].code,
500                               encoding_entries[i].groups,
501                               encoding_entries[i].is_autodetector);
502         }
504         /* get the list of recently used encodings */
505         list = eel_gconf_get_string_list (RECENT_KEY);
507         /* make sure the list has no duplicates (GtkUIManager goes
508          * crazy otherwise), and only valid entries
509          */
510         encodings->priv->recent = NULL;
511         for (l = list; l != NULL; l = l->next)
512         {
513                 if (g_slist_find (encodings->priv->recent, l->data) == NULL
514                     && g_slist_length (encodings->priv->recent) < RECENT_MAX
515                     && ephy_encodings_get_node (encodings, l->data, FALSE) != NULL)
516                 {
517                         encodings->priv->recent =
518                                 g_slist_prepend (encodings->priv->recent,
519                                                  l->data);
520                 }
521                 else
522                 {
523                         g_free (l->data);
524                 }
525         }
526         encodings->priv->recent = g_slist_reverse (encodings->priv->recent);
527         g_slist_free (list);
530 EphyEncodings *
531 ephy_encodings_new (void)
533         return g_object_new (EPHY_TYPE_ENCODINGS, NULL);