1 /* charset.c
2 * Copyright (C) 2005 Sylvain Cresto <scresto@gmail.com>
3 *
4 * This file is part of graveman!
5 *
6 * graveman! 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
9 * (at your option) any later version.
10 *
11 * graveman! 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 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with program; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
20 *
21 * URL: http://www.nongnu.org/graveman/
22 *
23 */
24
25 /* definition des fenetres */
26
27 #include "graveman.h"
28
29 GSList *Gcharsetlist = NULL;
30
31 /* table de correspondance pour l'autodetection des charsets */
32 Tdata Gautoconvcharset[] = {
33 /* iso */
34 { "iso8859-1", N_("Latin/Occidental alphabet (ISO 8859-1)") },
35 { "iso8859-2", N_("Latin alphabet No. 2 (ISO 8859-2)") },
36 { "iso8859-3", N_("Latin alphabet No. 3 (ISO 8859-3)") },
37 { "iso8859-4", N_("Latin alphabet No. 4 (ISO 8859-4)") },
38 { "iso8859-5", N_("Latin/Cyrillic alphabet (ISO 8859-5)") },
39 { "iso8859-6", N_("Latin/Arabic alphabet (ISO 8859-6)") },
40 { "iso8859-7", N_("Latin/Greek alphabet (ISO 8859-7)") },
41 { "iso8859-8", N_("Latin/Hebrew alphabet (ISO 8859-8)") },
42 { "iso8859-9", N_("Latin alphabet No. 5 (ISO 8859-9)") },
43 { "iso8859-10", N_("Latin alphabet No. 6 (ISO 8859-10)") },
44 { "iso8859-11", N_("Latin/Thai alphabet (ISO 8859-11)") },
45 { "iso8859-13", N_("Latin alphabet No. 7 (ISO 8859-13)") },
46 { "iso8859-14", N_("Latin/Celtic alphabet (ISO 8859-14)") },
47 { "iso8859-15", N_("Latin/Occidental+euro alphabet (ISO 8859-15)") },
48
49 /* koi8 ukraine + russie */
50 { "koi8-u", N_("Ukrainian (KOI8-U)") },
51 { "koi8-r", N_("Russian (KOI8-R)") },
52
53 /* windows */
54 { "cp1250", N_("Windows Central European (CP1250)") },
55 { "cp1251", N_("Windows Cyrillic (CP1251)") },
56 { "cp1252", N_("Windows US ANSI (CP1252)") },
57 { "cp1254", N_("Windows Turkish (CP1254)") },
58 { "cp1257", N_("Windows Baltic (CP1257)") },
59
60 /* ms dos */
61 { "cp437", N_("MS-DOS US (CP437)") },
62 { "cp737", N_("MS-DOS Greek (CP737)") },
63 { "cp775", N_("MS-DOS Baltic (CP774)") },
64 { "cp850", N_("MS-DOS Multilingual Latin1 (CP852)") },
65 { "cp852", N_("MS-DOS Slavic (CP852)") },
66 { "cp855", N_("MS-DOS Cyrillic (CP855)") },
67 { "cp857", N_("MS-DOS Turkish (CP857)") },
68 { "cp860", N_("MS-DOS Portugese (CP860)") },
69 { "cp861", N_("MS-DOS Icelandic (CP861)") },
70 { "cp862", N_("MS-DOS Hebrew (CP862)") },
71 { "cp863", N_("MS-DOS Canadian French (CP863)") },
72 { "cp864", N_("MS-DOS Arabic (CP864)") },
73 { "cp865", N_("MS-DOS Nordic (CP865)") },
74 { "cp866", N_("MS-DOS Russian (CP866)") },
75 { "cp869", N_("MS-DOS Modern Greek (CP869)") },
76 { "cp874", N_("MS-DOS Thai (CP874)") },
77
78 /* macintosh */
79 { "cp10000", N_("Macintosh Roman (CP10000)") },
80 { "cp10004", N_("Macintosh Arabic (CP10004)") },
81 { "cp10006", N_("Macintosh Greek (CP10006)") },
82 { "cp10007", N_("Macintosh Cyrillic (CP10007)") },
83 { "cp10029", N_("Macintosh Central European (CP10029)") },
84 { "cp10079", N_("Macintosh Icelandic (CP10079)") },
85 { "cp10081", N_("Macintosh Turkish (CP10081)") },
86 { NULL, NULL },
87 };
88
89
charset_code_to_label(gchar * Acode)90 const char *charset_code_to_label(gchar *Acode)
91 {
92 gint i;
93
94 for (i=0; Gautoconvcharset[i].data; i++) {
95 if (!strcmp(Gautoconvcharset[i].data, Acode)) {
96 return _(Gautoconvcharset[i].label);
97 }
98 }
99
100 return Acode;
101 }
102
103 /* initialisation treeview contenant la liste des charsets */
prepare_properties_charsettreeview(GtkTreeView * Atreeview)104 void prepare_properties_charsettreeview(GtkTreeView *Atreeview)
105 {
106 GtkListStore *Lmodel = gtk_list_store_new(4, G_TYPE_INT, GDK_TYPE_PIXBUF, G_TYPE_STRING,
107 G_TYPE_STRING);
108 GtkCellRenderer *Lcellrender;
109 GtkTreeViewColumn *Lcell;
110
111 gtk_tree_view_set_model(Atreeview, GTK_TREE_MODEL(Lmodel));
112
113 /* creation colonnes */
114 Lcellrender = gtk_cell_renderer_pixbuf_new();
115 Lcell = gtk_tree_view_column_new_with_attributes("", Lcellrender, "pixbuf", 1, NULL);
116 gtk_tree_view_append_column(GTK_TREE_VIEW(Atreeview), Lcell);
117 gtk_tree_view_column_set_resizable(Lcell, TRUE);
118
119 Lcellrender = gtk_cell_renderer_text_new();
120 Lcell = gtk_tree_view_column_new_with_attributes(_("Code / Location"), Lcellrender, "text", 2, NULL);
121 gtk_tree_view_column_set_resizable(Lcell, TRUE);
122 gtk_tree_view_append_column(GTK_TREE_VIEW(Atreeview), Lcell);
123
124 Lcellrender = gtk_cell_renderer_text_new();
125 Lcell = gtk_tree_view_column_new_with_attributes(_("Label"), Lcellrender, "text", 3, NULL);
126 gtk_tree_view_column_set_resizable(Lcell, TRUE);
127 gtk_tree_view_append_column(GTK_TREE_VIEW(Atreeview), Lcell);
128 }
129
130 /* boite de dialogue "selection d'un fichier charset" */
create_charsetselection(GtkWindow * AParent)131 GtkWidget* create_charsetselection (GtkWindow *AParent)
132 {
133 GtkWidget *Lfileselection;
134
135 GtkFileFilter *filterall;
136
137 /* filtres pour la selection de fichiers */
138 filterall = gtk_file_filter_new ();
139 gtk_file_filter_set_name (filterall, _("All files (*.*)"));
140 gtk_file_filter_add_pattern(filterall, "*");
141
142 Lfileselection = gtk_file_chooser_dialog_new(_("Select file containing character set table"),
143 AParent, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
144 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
145 NULL);
146
147 gtk_dialog_set_default_response (GTK_DIALOG (Lfileselection), GTK_RESPONSE_ACCEPT);
148 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (Lfileselection), filterall);
149
150 return Lfileselection;
151 }
152
153
154 /* selection d'un fichier charset */
gtk_charset_sel(GtkWidget * Abtn,gpointer Adata)155 void gtk_charset_sel(GtkWidget *Abtn, gpointer Adata)
156 {
157 Tgrave *Lg = (Tgrave *)Adata;
158 GtkWidget *Ltextdest = (GtkWidget *) sc_grave_get_widget(Lg, "charsetlocation");
159 gint Lresp;
160 GtkWidget *Lfilesel;
161
162 Lfilesel = create_charsetselection(sc_grave_get_data(Lg, "window"));
163 use_last_dir(GTK_FILE_CHOOSER(Lfilesel));
164 Lresp=gtk_dialog_run(GTK_DIALOG(Lfilesel));
165 gtk_widget_hide (Lfilesel);
166 while (gtk_events_pending())
167 gtk_main_iteration();
168
169 if (Lresp == GTK_RESPONSE_ACCEPT) {
170 gchar *Lfilenamebrut = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER ( Lfilesel));
171 gchar *Lfilename = _FILENAME(Lfilenamebrut);
172 save_last_dir(GTK_FILE_CHOOSER(Lfilesel));
173 gtk_entry_set_text(GTK_ENTRY(Ltextdest), Lfilename);
174 g_free(Lfilename);
175 g_free(Lfilenamebrut);
176 }
177
178 gtk_widget_destroy(Lfilesel);
179 }
180
181 /* ajouter manuelement une definition de charset */
gtk_charset_add(GtkWidget * Abtn,gpointer Adata)182 void gtk_charset_add(GtkWidget *Abtn, gpointer Adata)
183 {
184 Tgrave *Lg = (Tgrave *) Adata;
185 GtkWidget *Lparent = GTK_WIDGET(sc_grave_get_data(Lg, "window"));
186 Tgrave *Ldialoghash = create_dialog_add_charset(Lparent);
187 GtkWidget *Lwinaddcharset = sc_grave_get_data(Ldialoghash, "window");
188 GtkWidget *Lmessage;
189 gboolean Lcontinue = TRUE;
190
191 while (Lcontinue) {
192 if (gtk_dialog_run(GTK_DIALOG(Lwinaddcharset)) != GTK_RESPONSE_CANCEL) {
193 GtkEntry *Lcharsetlabel = GTK_ENTRY(sc_grave_get_widget(Ldialoghash, "charsetlabel"));
194 gchar *Lfilename = _FILENAME(gtk_entry_get_text(GTK_ENTRY(sc_grave_get_widget(Ldialoghash, "charsetlocation"))));
195
196 if (*Lfilename && g_file_test(Lfilename, G_FILE_TEST_EXISTS)) {
197 config_append_charset(Lfilename, (gchar *)gtk_entry_get_text(Lcharsetlabel));
198
199 /* mise a jour de la liste des peripheriques */
200 update_charsets(Lg);
201
202 Lmessage = gtk_message_dialog_new(GTK_WINDOW(Lparent),
203 GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
204 _("Charset succesfully added !"));
205 Lcontinue = FALSE;
206 } else if (*Lfilename) {
207 gchar *Lmsg = g_strdup_printf(_("Cannot add this charset, file '%s' doesn't exist !"), Lfilename);
208
209 Lmessage = gtk_message_dialog_new(GTK_WINDOW(Lparent),
210 GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, Lmsg);
211 g_free(Lmsg);
212 } else {
213 break;
214 }
215
216 gtk_dialog_run(GTK_DIALOG(Lmessage));
217 gtk_widget_destroy(Lmessage);
218
219 g_free(Lfilename);
220
221 } else {
222 Lcontinue = FALSE;
223 }
224 }
225 gtk_widget_destroy(Lwinaddcharset);
226 sc_grave_destroy(Ldialoghash);
227 }
228
gtk_charset_edit(GtkWidget * Abtn,gpointer Adata)229 void gtk_charset_edit(GtkWidget *Abtn, gpointer Adata)
230 {
231 Tgrave *Lg = (Tgrave *) Adata;
232 GtkWidget *Lparent = GTK_WIDGET(sc_grave_get_data(Lg, "window"));
233 GtkTreeView *Lliste = GTK_TREE_VIEW(sc_grave_get_widget(Lg, "charsetdata"));
234 GtkTreeSelection *Lselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(Lliste));
235 GtkTreeIter Liter;
236 GtkTreeModel *Ltreemodel;
237
238 if (gtk_tree_selection_get_selected(Lselection, &Ltreemodel, &Liter)) {
239 Tgrave *Ldialoghash;
240 GtkWidget *Lwineditcharset;
241 Tdata *Lcharset;
242 gint Lnum;
243
244 gtk_tree_model_get(Ltreemodel, &Liter, 0, &Lnum, -1);
245 Lcharset = (Tdata *)g_slist_nth_data(Gcharsetlist, Lnum);
246 Ldialoghash = create_dialog_edit_charset(Lparent, Lcharset);
247 Lwineditcharset = sc_grave_get_data(Ldialoghash, "window");
248
249 if (gtk_dialog_run(GTK_DIALOG(Lwineditcharset)) != GTK_RESPONSE_CANCEL) {
250 GtkEntry *Lcharsetlabel = GTK_ENTRY(sc_grave_get_widget(Ldialoghash, "charsetlabel"));
251
252 /* on remplace le nom dans la liste des lecteurs */
253 g_free(Lcharset->label);
254 Lcharset->label = g_strdup(gtk_entry_get_text(Lcharsetlabel));
255 /* ainsi que dans la liste affich�e */
256 gtk_list_store_set(GTK_LIST_STORE(Ltreemodel), &Liter, 3, Lcharset->label, -1);
257 }
258 gtk_widget_destroy(Lwineditcharset);
259 sc_grave_destroy(Ldialoghash);
260 }
261
262
263 }
264
265 /* l'utilisateur a cliquer sur supprimer un charset */
gtk_charset_remove(GtkWidget * Abtn,gpointer Adata)266 void gtk_charset_remove(GtkWidget *Abtn, gpointer Adata)
267 {
268 Tgrave *Lg = (Tgrave *)Adata;
269 GtkWidget *Lwindow1 = GTK_WIDGET(sc_grave_get_widget(Lg, "topwindow"));
270 GtkWidget *Lconfirm;
271 gint Lrep;
272
273 /* confirmation debut de l'operation */
274 Lconfirm = gtk_message_dialog_new(GTK_WINDOW(Lwindow1),
275 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
276 GTK_BUTTONS_YES_NO,
277 _("Do you really want to remove this character set ?"));
278 Lrep = gtk_dialog_run(GTK_DIALOG(Lconfirm));
279 gtk_widget_destroy(Lconfirm);
280
281 if (Lrep == GTK_RESPONSE_YES) {
282 /* oui on supprime un charsets */
283 GtkTreeView *Lliste = GTK_TREE_VIEW(sc_grave_get_widget(Lg, "charsetdata"));
284 GtkTreeSelection *Lselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(Lliste));
285 GtkTreeIter Liter;
286 GtkTreeModel *Ltreemodel;
287 gint Lnum;
288
289 if (gtk_tree_selection_get_selected(Lselection, &Ltreemodel, &Liter)) {
290 gtk_tree_model_get(Ltreemodel, &Liter, 0, &Lnum, -1);
291
292 _DEB("ON SUPRIMME LE CHARSET = %d\n", Lnum);
293 Gcharsetlist = g_slist_remove(Gcharsetlist, g_slist_nth_data(Gcharsetlist, Lnum));
294 gtk_list_store_remove(GTK_LIST_STORE(Ltreemodel), &Liter);
295 }
296
297 update_charsets(Lg);
298 }
299 }
300
301 /* boite de dialogue "ajouter un charset" */
create_dialog_add_charset(GtkWidget * Aparent)302 Tgrave *create_dialog_add_charset(GtkWidget *Aparent)
303 {
304 Tgrave *Lg = sc_grave_load("dialog_add_charset.glade");
305 GtkWidget *Ldialog;
306
307 g_assert(Lg);
308
309 Ldialog = sc_grave_get_widget(Lg, "dialog_add_charset");
310 gtk_window_set_transient_for(GTK_WINDOW(Ldialog), GTK_WINDOW(Aparent));
311 sc_grave_ref_wtd(Lg, "dialog_add_charset", "window");
312
313 gtk_dialog_set_default_response(GTK_DIALOG(Ldialog), GTK_RESPONSE_OK);
314
315 gtk_entry_set_text(GTK_ENTRY(sc_grave_get_widget(Lg, "charsetlabel")), _("New charset"));
316
317 g_signal_connect(G_OBJECT(sc_grave_get_widget(Lg, "btnbrowse")), "clicked", G_CALLBACK(gtk_charset_sel), Lg);
318
319
320 return Lg;
321 }
322
323 /* boite de dialogue "editer un charset" */
create_dialog_edit_charset(GtkWidget * Aparent,Tdata * Adata)324 Tgrave *create_dialog_edit_charset(GtkWidget *Aparent, Tdata *Adata)
325 {
326 Tgrave *Lg = sc_grave_load("dialog_charset.glade");
327 GtkWidget *Ldialog;
328 GtkEntry *Lentry;
329
330 g_assert(Lg);
331
332 Ldialog = sc_grave_get_widget(Lg, "dialog_charset");
333 gtk_window_set_transient_for(GTK_WINDOW(Ldialog), GTK_WINDOW(Aparent));
334 sc_grave_ref_wtd(Lg, "dialog_charset", "window");
335 gtk_dialog_set_default_response(GTK_DIALOG(Ldialog), GTK_RESPONSE_OK);
336
337 Lentry = GTK_ENTRY(sc_grave_get_widget(Lg, "charsetlabel"));
338 gtk_entry_set_text(Lentry, Adata->label);
339 gtk_label_set_text(GTK_LABEL(sc_grave_get_widget(Lg, "charsetcode")), Adata->data);
340
341 g_signal_connect(G_OBJECT(Lentry), "key-release-event", G_CALLBACK(callback_simpledialog_eventkeyrelease), Ldialog);
342
343 return Lg;
344 }
345
remplirelistecharset(GtkListStore * Adata,gboolean Aadddef)346 void remplirelistecharset(GtkListStore *Adata, gboolean Aadddef)
347 {
348 GtkTreeIter Liter;
349 gint i;
350 GSList *Lcur;
351 Tdata *Lptr;
352
353 gtk_list_store_clear(Adata);
354
355 if (Aadddef) {
356 /* ajout premiere ligne "default" */
357 gtk_list_store_append(Adata, &Liter);
358
359 gtk_list_store_set(Adata, &Liter, 0, -1, 1, get_image("CharsetSmallIcon"), 2,
360 "DEFAULT", 3, _("Use default character set"), -1);
361 }
362
363 for (Lcur = Gcharsetlist, i=0; Lcur; Lcur = g_slist_next(Lcur), i++) {
364 Lptr = (Tdata *)Lcur->data;
365
366 gtk_list_store_append(Adata, &Liter);
367
368 gtk_list_store_set(Adata, &Liter, 0, i, 1, get_image("CharsetSmallIcon"), 2,
369 Lptr->data, 3, Lptr->label, -1);
370 }
371 }
372
selectcombocharset(GtkComboBox * Acombo,gchar * Avalue)373 void selectcombocharset(GtkComboBox *Acombo, gchar *Avalue)
374 {
375 GtkTreeModel *Lmodel = gtk_combo_box_get_model(Acombo);
376 gboolean Lselect = FALSE;
377 GtkTreeIter Liter;
378 gboolean Lstatus;
379 gchar *Lcode;
380
381 if (Avalue) {
382 for (Lstatus = gtk_tree_model_get_iter_first(Lmodel, &Liter); Lstatus == TRUE && Lselect == FALSE;
383 Lstatus = gtk_tree_model_iter_next(Lmodel, &Liter)) {
384 gtk_tree_model_get(Lmodel, &Liter, 2, &Lcode, -1);
385 if (!strcmp(Lcode, Avalue)) {
386 gtk_combo_box_set_active_iter(Acombo, &Liter);
387 Lselect = TRUE;
388 }
389 g_free(Lcode);
390 }
391 }
392
393 if (Lselect == FALSE) {
394 gtk_combo_box_set_active(Acombo, 0);
395 }
396 }
397
update_charsets(Tgrave * Ag)398 void update_charsets(Tgrave *Ag)
399 {
400 GtkComboBox *Lcombo = GTK_COMBO_BOX(sc_grave_get_widget(Ag, "inputcharset"));
401
402 charset_sort_list();
403 remplirelistecharset(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sc_grave_get_widget(Ag, "charsetdata")))), FALSE);
404 remplirelistecharset(GTK_LIST_STORE(gtk_combo_box_get_model(Lcombo)), TRUE);
405 selectcombocharset(Lcombo, conf_get_string("charsetdata"));
406 }
407
408 /* operation de recherche des charsets */
cherchecharset(GtkWidget * Aobj,gpointer Adata)409 void cherchecharset(GtkWidget *Aobj, gpointer Adata)
410 {
411 Tgrave *Lg = (Tgrave *)Adata;
412 GtkWidget *Lwindow1 = sc_grave_get_data(Lg, "window");
413 GtkWidget *Lstatusbox;
414
415 if (get_builtin_charset(Lg, NULL) == TRUE && GTK_IS_WIDGET(Aobj)) {
416 update_charsets(Lg);
417
418 /* boite de dialoge operation terminee */
419 Lstatusbox = gtk_message_dialog_new(GTK_WINDOW(Lwindow1), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
420 _("configuration updated."));
421 gtk_dialog_run(GTK_DIALOG(Lstatusbox));
422 gtk_widget_destroy(Lstatusbox);
423 }
424 }
425
charset_sort_callback(gconstpointer Ad1,gconstpointer Ad2)426 gint charset_sort_callback(gconstpointer Ad1, gconstpointer Ad2)
427 {
428 Tdata *Ld1 = (Tdata *) Ad1;
429 Tdata *Ld2 = (Tdata *) Ad2;
430 return g_utf8_collate(Ld1->label, Ld2->label);
431 }
432
433 /* tri pour afficher la liste des charsets dans le bon ordre */
charset_sort_list()434 void charset_sort_list()
435 {
436 if (g_slist_length(Gcharsetlist))
437 Gcharsetlist = g_slist_sort(Gcharsetlist, charset_sort_callback);
438 }
439
440 /*
441 * vim:et:ts=8:sts=2:sw=2
442 */
443