1 /*
2 * Copyright (C) 2001-2006 Bastien Nocera <hadess@hadess.net>
3 *
4 * encoding list copied from gnome-terminal/encoding.c
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * The Totem project hereby grant permission for non-gpl compatible GStreamer
21 * plugins to be used and distributed together with GStreamer and Totem. This
22 * permission are above and beyond the permissions granted by the GPL license
23 * Totem is covered by.
24 *
25 * Monday 7th February 2005: Christian Schaller: Add exception clause.
26 * See license_change file for details.
27 *
28 */
29
30 #include "config.h"
31 #include <glib/gi18n.h>
32 #include "totem-subtitle-encoding.h"
33 #include <string.h>
34
35 typedef enum
36 {
37 SUBTITLE_ENCODING_CURRENT_LOCALE,
38
39 SUBTITLE_ENCODING_ISO_8859_6,
40 SUBTITLE_ENCODING_IBM_864,
41 SUBTITLE_ENCODING_MAC_ARABIC,
42 SUBTITLE_ENCODING_WINDOWS_1256,
43
44 SUBTITLE_ENCODING_ARMSCII_8,
45
46 SUBTITLE_ENCODING_ISO_8859_4,
47 SUBTITLE_ENCODING_ISO_8859_13,
48 SUBTITLE_ENCODING_WINDOWS_1257,
49
50 SUBTITLE_ENCODING_ISO_8859_14,
51
52 SUBTITLE_ENCODING_ISO_8859_2,
53 SUBTITLE_ENCODING_IBM_852,
54 SUBTITLE_ENCODING_MAC_CE,
55 SUBTITLE_ENCODING_WINDOWS_1250,
56
57 SUBTITLE_ENCODING_GB18030,
58 SUBTITLE_ENCODING_GB2312,
59 SUBTITLE_ENCODING_GBK,
60 SUBTITLE_ENCODING_HZ,
61
62 SUBTITLE_ENCODING_BIG5,
63 SUBTITLE_ENCODING_BIG5_HKSCS,
64 SUBTITLE_ENCODING_EUC_TW,
65
66 SUBTITLE_ENCODING_MAC_CROATIAN,
67
68 SUBTITLE_ENCODING_ISO_8859_5,
69 SUBTITLE_ENCODING_IBM_855,
70 SUBTITLE_ENCODING_ISO_IR_111,
71 SUBTITLE_ENCODING_KOI8_R,
72 SUBTITLE_ENCODING_MAC_CYRILLIC,
73 SUBTITLE_ENCODING_WINDOWS_1251,
74
75 SUBTITLE_ENCODING_CP_866,
76
77 SUBTITLE_ENCODING_MAC_UKRAINIAN,
78 SUBTITLE_ENCODING_KOI8_U,
79
80 SUBTITLE_ENCODING_GEOSTD8,
81
82 SUBTITLE_ENCODING_ISO_8859_7,
83 SUBTITLE_ENCODING_MAC_GREEK,
84 SUBTITLE_ENCODING_WINDOWS_1253,
85
86 SUBTITLE_ENCODING_MAC_GUJARATI,
87
88 SUBTITLE_ENCODING_MAC_GURMUKHI,
89
90 SUBTITLE_ENCODING_ISO_8859_8_I,
91 SUBTITLE_ENCODING_IBM_862,
92 SUBTITLE_ENCODING_MAC_HEBREW,
93 SUBTITLE_ENCODING_WINDOWS_1255,
94
95 SUBTITLE_ENCODING_ISO_8859_8,
96
97 SUBTITLE_ENCODING_MAC_DEVANAGARI,
98
99 SUBTITLE_ENCODING_MAC_ICELANDIC,
100
101 SUBTITLE_ENCODING_EUC_JP,
102 SUBTITLE_ENCODING_ISO_2022_JP,
103 SUBTITLE_ENCODING_SHIFT_JIS,
104
105 SUBTITLE_ENCODING_EUC_KR,
106 SUBTITLE_ENCODING_ISO_2022_KR,
107 SUBTITLE_ENCODING_JOHAB,
108 SUBTITLE_ENCODING_UHC,
109
110 SUBTITLE_ENCODING_ISO_8859_10,
111
112 SUBTITLE_ENCODING_MAC_FARSI,
113
114 SUBTITLE_ENCODING_ISO_8859_16,
115 SUBTITLE_ENCODING_MAC_ROMANIAN,
116
117 SUBTITLE_ENCODING_ISO_8859_3,
118
119 SUBTITLE_ENCODING_TIS_620,
120
121 SUBTITLE_ENCODING_ISO_8859_9,
122 SUBTITLE_ENCODING_IBM_857,
123 SUBTITLE_ENCODING_MAC_TURKISH,
124 SUBTITLE_ENCODING_WINDOWS_1254,
125
126 SUBTITLE_ENCODING_UTF_7,
127 SUBTITLE_ENCODING_UTF_8,
128 SUBTITLE_ENCODING_UTF_16,
129 SUBTITLE_ENCODING_UCS_2,
130 SUBTITLE_ENCODING_UCS_4,
131
132 SUBTITLE_ENCODING_ISO_8859_1,
133 SUBTITLE_ENCODING_ISO_8859_15,
134 SUBTITLE_ENCODING_IBM_850,
135 SUBTITLE_ENCODING_MAC_ROMAN,
136 SUBTITLE_ENCODING_WINDOWS_1252,
137
138 SUBTITLE_ENCODING_TCVN,
139 SUBTITLE_ENCODING_VISCII,
140 SUBTITLE_ENCODING_WINDOWS_1258,
141
142 SUBTITLE_ENCODING_LAST
143 } SubtitleEncodingIndex;
144
145
146 typedef struct {
147 int index;
148 const char *charset;
149 const char *name;
150 } SubtitleEncoding;
151
152
153 static SubtitleEncoding encodings[] = {
154
155 {SUBTITLE_ENCODING_CURRENT_LOCALE,
156 NULL, N_("Current Locale")},
157
158 {SUBTITLE_ENCODING_ISO_8859_6,
159 "ISO-8859-6", N_("Arabic")},
160 {SUBTITLE_ENCODING_IBM_864,
161 "IBM864", N_("Arabic")},
162 {SUBTITLE_ENCODING_MAC_ARABIC,
163 "MAC_ARABIC", N_("Arabic")},
164 {SUBTITLE_ENCODING_WINDOWS_1256,
165 "WINDOWS-1256", N_("Arabic")},
166
167 {SUBTITLE_ENCODING_ARMSCII_8,
168 "ARMSCII-8", N_("Armenian")},
169
170 {SUBTITLE_ENCODING_ISO_8859_4,
171 "ISO-8859-4", N_("Baltic")},
172 {SUBTITLE_ENCODING_ISO_8859_13,
173 "ISO-8859-13", N_("Baltic")},
174 {SUBTITLE_ENCODING_WINDOWS_1257,
175 "WINDOWS-1257", N_("Baltic")},
176
177 {SUBTITLE_ENCODING_ISO_8859_14,
178 "ISO-8859-14", N_("Celtic")},
179
180 {SUBTITLE_ENCODING_ISO_8859_2,
181 "ISO-8859-2", N_("Central European")},
182 {SUBTITLE_ENCODING_IBM_852,
183 "IBM852", N_("Central European")},
184 {SUBTITLE_ENCODING_MAC_CE,
185 "MAC_CE", N_("Central European")},
186 {SUBTITLE_ENCODING_WINDOWS_1250,
187 "WINDOWS-1250", N_("Central European")},
188
189 {SUBTITLE_ENCODING_GB18030,
190 "GB18030", N_("Chinese Simplified")},
191 {SUBTITLE_ENCODING_GB2312,
192 "GB2312", N_("Chinese Simplified")},
193 {SUBTITLE_ENCODING_GBK,
194 "GBK", N_("Chinese Simplified")},
195 {SUBTITLE_ENCODING_HZ,
196 "HZ", N_("Chinese Simplified")},
197
198 {SUBTITLE_ENCODING_BIG5,
199 "BIG5", N_("Chinese Traditional")},
200 {SUBTITLE_ENCODING_BIG5_HKSCS,
201 "BIG5-HKSCS", N_("Chinese Traditional")},
202 {SUBTITLE_ENCODING_EUC_TW,
203 "EUC-TW", N_("Chinese Traditional")},
204
205 {SUBTITLE_ENCODING_MAC_CROATIAN,
206 "MAC_CROATIAN", N_("Croatian")},
207
208 {SUBTITLE_ENCODING_ISO_8859_5,
209 "ISO-8859-5", N_("Cyrillic")},
210 {SUBTITLE_ENCODING_IBM_855,
211 "IBM855", N_("Cyrillic")},
212 {SUBTITLE_ENCODING_ISO_IR_111,
213 "ISO-IR-111", N_("Cyrillic")},
214 {SUBTITLE_ENCODING_KOI8_R,
215 "KOI8-R", N_("Cyrillic")},
216 {SUBTITLE_ENCODING_MAC_CYRILLIC,
217 "MAC-CYRILLIC", N_("Cyrillic")},
218 {SUBTITLE_ENCODING_WINDOWS_1251,
219 "WINDOWS-1251", N_("Cyrillic")},
220
221 {SUBTITLE_ENCODING_CP_866,
222 "CP866", N_("Cyrillic/Russian")},
223
224 {SUBTITLE_ENCODING_MAC_UKRAINIAN,
225 "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian")},
226 {SUBTITLE_ENCODING_KOI8_U,
227 "KOI8-U", N_("Cyrillic/Ukrainian")},
228
229 {SUBTITLE_ENCODING_GEOSTD8,
230 "GEORGIAN-PS", N_("Georgian")},
231
232 {SUBTITLE_ENCODING_ISO_8859_7,
233 "ISO-8859-7", N_("Greek")},
234 {SUBTITLE_ENCODING_MAC_GREEK,
235 "MAC_GREEK", N_("Greek")},
236 {SUBTITLE_ENCODING_WINDOWS_1253,
237 "WINDOWS-1253", N_("Greek")},
238
239 {SUBTITLE_ENCODING_MAC_GUJARATI,
240 "MAC_GUJARATI", N_("Gujarati")},
241
242 {SUBTITLE_ENCODING_MAC_GURMUKHI,
243 "MAC_GURMUKHI", N_("Gurmukhi")},
244
245 {SUBTITLE_ENCODING_ISO_8859_8_I,
246 "ISO-8859-8-I", N_("Hebrew")},
247 {SUBTITLE_ENCODING_IBM_862,
248 "IBM862", N_("Hebrew")},
249 {SUBTITLE_ENCODING_MAC_HEBREW,
250 "MAC_HEBREW", N_("Hebrew")},
251 {SUBTITLE_ENCODING_WINDOWS_1255,
252 "WINDOWS-1255", N_("Hebrew")},
253
254 {SUBTITLE_ENCODING_ISO_8859_8,
255 "ISO-8859-8", N_("Hebrew Visual")},
256
257 {SUBTITLE_ENCODING_MAC_DEVANAGARI,
258 "MAC_DEVANAGARI", N_("Hindi")},
259
260 {SUBTITLE_ENCODING_MAC_ICELANDIC,
261 "MAC_ICELANDIC", N_("Icelandic")},
262
263 {SUBTITLE_ENCODING_EUC_JP,
264 "EUC-JP", N_("Japanese")},
265 {SUBTITLE_ENCODING_ISO_2022_JP,
266 "ISO2022JP", N_("Japanese")},
267 {SUBTITLE_ENCODING_SHIFT_JIS,
268 "SHIFT-JIS", N_("Japanese")},
269
270 {SUBTITLE_ENCODING_EUC_KR,
271 "EUC-KR", N_("Korean")},
272 {SUBTITLE_ENCODING_ISO_2022_KR,
273 "ISO2022KR", N_("Korean")},
274 {SUBTITLE_ENCODING_JOHAB,
275 "JOHAB", N_("Korean")},
276 {SUBTITLE_ENCODING_UHC,
277 "UHC", N_("Korean")},
278
279 {SUBTITLE_ENCODING_ISO_8859_10,
280 "ISO-8859-10", N_("Nordic")},
281
282 {SUBTITLE_ENCODING_MAC_FARSI,
283 "MAC_FARSI", N_("Persian")},
284
285 {SUBTITLE_ENCODING_ISO_8859_16,
286 "ISO-8859-16", N_("Romanian")},
287 {SUBTITLE_ENCODING_MAC_ROMANIAN,
288 "MAC_ROMANIAN", N_("Romanian")},
289
290 {SUBTITLE_ENCODING_ISO_8859_3,
291 "ISO-8859-3", N_("South European")},
292
293 {SUBTITLE_ENCODING_TIS_620,
294 "TIS-620", N_("Thai")},
295
296 {SUBTITLE_ENCODING_ISO_8859_9,
297 "ISO-8859-9", N_("Turkish")},
298 {SUBTITLE_ENCODING_IBM_857,
299 "IBM857", N_("Turkish")},
300 {SUBTITLE_ENCODING_MAC_TURKISH,
301 "MAC_TURKISH", N_("Turkish")},
302 {SUBTITLE_ENCODING_WINDOWS_1254,
303 "WINDOWS-1254", N_("Turkish")},
304
305 {SUBTITLE_ENCODING_UTF_7,
306 "UTF-7", N_("Unicode")},
307 {SUBTITLE_ENCODING_UTF_8,
308 "UTF-8", N_("Unicode")},
309 {SUBTITLE_ENCODING_UTF_16,
310 "UTF-16", N_("Unicode")},
311 {SUBTITLE_ENCODING_UCS_2,
312 "UCS-2", N_("Unicode")},
313 {SUBTITLE_ENCODING_UCS_4,
314 "UCS-4", N_("Unicode")},
315
316 {SUBTITLE_ENCODING_ISO_8859_1,
317 "ISO-8859-1", N_("Western")},
318 {SUBTITLE_ENCODING_ISO_8859_15,
319 "ISO-8859-15", N_("Western")},
320 {SUBTITLE_ENCODING_IBM_850,
321 "IBM850", N_("Western")},
322 {SUBTITLE_ENCODING_MAC_ROMAN,
323 "MAC_ROMAN", N_("Western")},
324 {SUBTITLE_ENCODING_WINDOWS_1252,
325 "WINDOWS-1252", N_("Western")},
326
327 {SUBTITLE_ENCODING_TCVN,
328 "TCVN", N_("Vietnamese")},
329 {SUBTITLE_ENCODING_VISCII,
330 "VISCII", N_("Vietnamese")},
331 {SUBTITLE_ENCODING_WINDOWS_1258,
332 "WINDOWS-1258", N_("Vietnamese")}
333 };
334
335 static const SubtitleEncoding *
find_encoding_by_charset(const char * charset)336 find_encoding_by_charset (const char *charset)
337 {
338 int i;
339
340 i = 1; /* skip current locale */
341 while (i < SUBTITLE_ENCODING_LAST) {
342 if (strcasecmp (charset, encodings[i].charset) == 0)
343 return &encodings[i];
344
345 ++i;
346 }
347
348 if (strcasecmp (charset,
349 encodings[SUBTITLE_ENCODING_CURRENT_LOCALE].charset) == 0)
350 return &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
351
352 return NULL;
353 }
354
355 static void
subtitle_encoding_init(void)356 subtitle_encoding_init (void)
357 {
358 guint i;
359
360 g_get_charset ((const char **)
361 &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE].charset);
362
363 g_assert (G_N_ELEMENTS (encodings) == SUBTITLE_ENCODING_LAST);
364
365 for (i = 0; i < SUBTITLE_ENCODING_LAST; i++) {
366 /* Translate the names */
367 encodings[i].name = _(encodings[i].name);
368 }
369 }
370
371 static int
subtitle_encoding_get_index(const char * charset)372 subtitle_encoding_get_index (const char *charset)
373 {
374 const SubtitleEncoding *e;
375
376 e = find_encoding_by_charset (charset);
377 if (e != NULL)
378 return e->index;
379 else
380 return SUBTITLE_ENCODING_CURRENT_LOCALE;
381 }
382
383 static const char *
subtitle_encoding_get_charset(int charset_index)384 subtitle_encoding_get_charset (int charset_index)
385 {
386 const SubtitleEncoding *e;
387
388 if (charset_index >= SUBTITLE_ENCODING_LAST)
389 e = &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
390 else if (charset_index < SUBTITLE_ENCODING_CURRENT_LOCALE)
391 e = &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
392 else
393 e = &encodings[charset_index];
394 return e->charset;
395 }
396
397 enum
398 {
399 INDEX_COL,
400 NAME_COL
401 };
402
403 static gint
compare(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)404 compare (GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer data)
405 {
406 gchar *str_a, *str_b;
407 gint result;
408
409 gtk_tree_model_get (model, a, NAME_COL, &str_a, -1);
410 gtk_tree_model_get (model, b, NAME_COL, &str_b, -1);
411
412 result = strcmp (str_a, str_b);
413
414 g_free (str_a);
415 g_free (str_b);
416
417 return result;
418 }
419
420 static void
is_encoding_sensitive(GtkCellLayout * cell_layout,GtkCellRenderer * cell,GtkTreeModel * tree_model,GtkTreeIter * iter,gpointer data)421 is_encoding_sensitive (GtkCellLayout * cell_layout,
422 GtkCellRenderer * cell,
423 GtkTreeModel * tree_model, GtkTreeIter * iter, gpointer data)
424 {
425
426 gboolean sensitive;
427
428 sensitive = !gtk_tree_model_iter_has_child (tree_model, iter);
429 g_object_set (cell, "sensitive", sensitive, NULL);
430 }
431
432 static GtkTreeModel *
subtitle_encoding_create_store(void)433 subtitle_encoding_create_store (void)
434 {
435 gchar *label;
436 const gchar *lastlang = "";
437 GtkTreeIter iter, iter2;
438 GtkTreeStore *store;
439 int i;
440
441 store = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_STRING);
442
443 for (i = 0; i < SUBTITLE_ENCODING_LAST; i++) {
444 if (strcmp (lastlang, encodings[i].name)) {
445 lastlang = encodings[i].name;
446 gtk_tree_store_append (store, &iter, NULL);
447 gtk_tree_store_set (store, &iter, INDEX_COL,
448 -1, NAME_COL, lastlang, -1);
449 }
450 label = g_strdup_printf("%s (%s)", lastlang, encodings[i].charset);
451 gtk_tree_store_append (store, &iter2, &iter);
452 gtk_tree_store_set (store, &iter2, INDEX_COL,
453 encodings[i].index, NAME_COL, label, -1);
454 g_free(label);
455 }
456 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
457 compare, NULL, NULL);
458 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
459 NAME_COL, GTK_SORT_ASCENDING);
460 return GTK_TREE_MODEL (store);
461 }
462
463 static void
subtitle_encoding_combo_render(GtkComboBox * combo)464 subtitle_encoding_combo_render (GtkComboBox * combo)
465 {
466 GtkCellRenderer *renderer;
467
468 renderer = gtk_cell_renderer_text_new ();
469 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
470 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
471 "text", NAME_COL, NULL);
472 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
473 renderer, is_encoding_sensitive, NULL, NULL);
474 }
475
476 const char *
totem_subtitle_encoding_get_selected(GtkComboBox * combo)477 totem_subtitle_encoding_get_selected (GtkComboBox * combo)
478 {
479 GtkTreeModel *model;
480 GtkTreeIter iter;
481 gint charset_index = -1;
482
483 model = gtk_combo_box_get_model (combo);
484 if (gtk_combo_box_get_active_iter (combo, &iter)) {
485 gtk_tree_model_get (model, &iter, INDEX_COL, &charset_index, -1);
486 }
487 if (charset_index == -1)
488 return NULL;
489 return subtitle_encoding_get_charset (charset_index);
490 }
491
492 void
totem_subtitle_encoding_set(GtkComboBox * combo,const char * encoding)493 totem_subtitle_encoding_set (GtkComboBox * combo, const char *encoding)
494 {
495 GtkTreeModel *model;
496 GtkTreeIter iter, iter2;
497 gint enc_index, i;
498
499 g_return_if_fail (encoding != NULL);
500
501 model = gtk_combo_box_get_model (combo);
502 enc_index = subtitle_encoding_get_index (encoding);
503 gtk_tree_model_get_iter_first (model, &iter);
504 do {
505 if (!gtk_tree_model_iter_has_child (model, &iter))
506 continue;
507 if (!gtk_tree_model_iter_children (model, &iter2, &iter))
508 continue;
509 do {
510 gtk_tree_model_get (model, &iter2, INDEX_COL, &i, -1);
511 if (i == enc_index)
512 break;
513 } while (gtk_tree_model_iter_next (model, &iter2));
514 if (i == enc_index)
515 break;
516 } while (gtk_tree_model_iter_next (model, &iter));
517 gtk_combo_box_set_active_iter (combo, &iter2);
518 }
519
520 void
totem_subtitle_encoding_init(GtkComboBox * combo)521 totem_subtitle_encoding_init (GtkComboBox *combo)
522 {
523 GtkTreeModel *model;
524 subtitle_encoding_init ();
525 model = subtitle_encoding_create_store ();
526 gtk_combo_box_set_model (combo, model);
527 g_object_unref (model);
528 subtitle_encoding_combo_render (combo);
529 }
530
531 /*
532 * vim: sw=2 ts=8 cindent noai bs=2
533 */
534