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