r1583: Updated French translation (Vincent Lef�vre).
[rox-filer.git] / ROX-Filer / src / i18n.c
blob3bd05deb1fd69b3caeb4b8e78811d84bb85c7946
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <string.h>
29 #include "global.h"
31 #include "support.h"
32 #include "choices.h"
33 #include "options.h"
34 #include "i18n.h"
35 #include "gui_support.h"
36 #include "main.h"
38 #define MESSAGE _("Note that you must save your choices " \
39 "and restart the filer for the new language " \
40 "setting to take full effect.")
42 char *current_lang = NULL; /* Two-char country code, or NULL */
44 static Option o_translation;
46 static GtkWidget *i18n_message = NULL;
48 /* Static Prototypes */
49 static void set_trans(guchar *lang);
50 static void trans_changed(void);
51 static GList *build_i18n_message(Option *option, xmlNode *node, guchar *label);
53 /****************************************************************
54 * EXTERNAL INTERFACE *
55 ****************************************************************/
58 /* Set things up for internationalisation */
59 void i18n_init(void)
61 gtk_set_locale();
63 option_add_string(&o_translation, "i18n_translation", "From LANG");
64 set_trans(o_translation.value);
65 o_translation.has_changed = FALSE; /* Prevent warning about saving */
67 option_add_notify(trans_changed);
69 option_register_widget("i18n-message", build_i18n_message);
72 /* These two stolen from dia :-).
73 * Slight modification though: '>' means 'same as above' so that
74 * if a translation is missing it doesn't muck up the whole menu structure!
76 GtkItemFactoryEntry *translate_entries(GtkItemFactoryEntry *entries, gint n)
78 guchar *first = NULL, *second = NULL; /* Previous menu, submenu */
79 gint i;
80 GtkItemFactoryEntry *ret;
82 ret = g_malloc(sizeof(GtkItemFactoryEntry) * n);
83 for (i = 0; i < n; i++)
85 const gchar *from = entries[i].path;
86 gchar *trans, *slash;
87 int indent;
89 if (from[0] == '>')
91 if (from[1] == '>')
92 indent = 2;
93 else
94 indent = 1;
96 else
97 indent = 0;
99 if (from[indent])
100 from = _(from + indent);
101 else
102 from = "";
104 if (indent == 0)
105 trans = g_strdup_printf("/%s", from);
106 else if (indent == 1)
107 trans = g_strdup_printf("/%s/%s", first, from);
108 else
109 trans = g_strdup_printf("/%s/%s/%s",
110 first, second, from);
112 ret[i].path = trans;
114 g_free(first);
115 g_free(second);
116 second = NULL;
118 trans++;
119 slash = strchr(trans, '/');
120 if (slash)
122 first = g_strndup(trans, slash - trans);
123 trans = slash + 1;
125 slash = strchr(trans, '/');
126 if (slash)
127 second = g_strndup(trans, slash - trans);
128 else
129 second = g_strdup(trans);
131 else
132 first = g_strdup(trans);
134 /* accelerator and item_type are not duped, only referenced */
135 ret[i].accelerator = entries[i].accelerator;
136 ret[i].callback = entries[i].callback;
137 ret[i].callback_action = entries[i].callback_action;
138 ret[i].item_type = entries[i].item_type;
141 g_free(first);
142 g_free(second);
144 return ret;
147 void free_translated_entries(GtkItemFactoryEntry *entries, gint n)
149 gint i;
151 for (i=0; i<n; i++)
152 g_free(entries[i].path);
153 g_free(entries);
157 /****************************************************************
158 * INTERNAL FUNCTIONS *
159 ****************************************************************/
161 static void trans_changed(void)
163 if (!o_translation.has_changed)
164 return;
166 set_trans(o_translation.value);
168 if (i18n_message)
169 gtk_label_set_text(GTK_LABEL(i18n_message), MESSAGE);
172 /* Load the 'Messages/<name>.gmo' translation.
173 * Special values 'None' and 'From LANG' are also allowed.
175 static void set_trans(guchar *lang)
177 struct stat info;
178 guchar *path;
179 gchar *lang2 = NULL;
181 g_return_if_fail(lang != NULL);
183 rox_clear_translation();
185 if (current_lang)
187 g_free(current_lang);
188 current_lang = NULL;
191 if (strcmp(lang, "None") == 0)
192 return;
193 else if (strcmp(lang, "From LANG") == 0)
195 lang = getenv("LANG");
196 if (!lang)
197 return;
198 /* Extract the language code from the locale name.
199 * language[_territory][.codeset][@modifier]
201 if (lang[0] != '\0' && lang[1] != '\0'
202 && (lang[2] == '_' || lang[2] == '.' || lang[2] == '@'))
203 lang2 = g_strndup((gchar *) lang, 2);
206 current_lang = lang2 ? lang2 : g_strdup(lang);
208 path = g_strdup_printf("%s/Messages/%s.gmo", app_dir, current_lang);
209 if (stat(path, &info) == 0)
210 rox_add_translations(path);
211 g_free(path);
214 static GList *build_i18n_message(Option *option, xmlNode *node, guchar *label)
216 GtkWidget *hbox, *image, *align;
218 g_return_val_if_fail(option == NULL, NULL);
219 g_return_val_if_fail(label == NULL, NULL);
220 g_return_val_if_fail(i18n_message == NULL, NULL);
222 i18n_message = gtk_label_new(MESSAGE);
223 g_signal_connect(i18n_message, "destroy",
224 G_CALLBACK(gtk_widget_destroyed), &i18n_message);
226 gtk_misc_set_alignment(GTK_MISC(i18n_message), 0, 0.5);
227 gtk_label_set_justify(GTK_LABEL(i18n_message), GTK_JUSTIFY_LEFT);
228 gtk_label_set_line_wrap(GTK_LABEL(i18n_message), TRUE);
230 hbox = gtk_hbox_new(FALSE, 4);
231 image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO,
232 GTK_ICON_SIZE_BUTTON);
233 align = gtk_alignment_new(0, 0, 0, 0);
235 gtk_container_add(GTK_CONTAINER(align), image);
236 gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, TRUE, 0);
237 gtk_box_pack_start(GTK_BOX(hbox), i18n_message, FALSE, TRUE, 0);
239 return g_list_append(NULL, hbox);