r4269: Bugfix: New detail crashes cleanice theme. Try another value... (reported
[rox-filer/translations.git] / ROX-Filer / src / i18n.c
blob471586202a4d05ed6d67672b89ae8825249a2e32
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2005, 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 /* Two/five-char country_territory code, or NULL */
43 char *current_lang = NULL;
45 static Option o_translation;
47 static GtkWidget *i18n_message = NULL;
49 /* Static Prototypes */
50 static void set_trans(const guchar *lang);
51 static void trans_changed(void);
52 static GList *build_i18n_message(Option *option, xmlNode *node, guchar *label);
54 /****************************************************************
55 * EXTERNAL INTERFACE *
56 ****************************************************************/
59 /* Set things up for internationalisation */
60 void i18n_init(void)
62 gtk_set_locale();
64 option_add_string(&o_translation, "i18n_translation", "From LANG");
65 set_trans(o_translation.value);
66 o_translation.has_changed = FALSE; /* Prevent warning about saving */
68 option_add_notify(trans_changed);
70 option_register_widget("i18n-message", build_i18n_message);
73 /* These two stolen from dia :-).
74 * Slight modification though: '>' means 'same as above' so that
75 * if a translation is missing it doesn't muck up the whole menu structure!
77 GtkItemFactoryEntry *translate_entries(GtkItemFactoryEntry *entries, gint n)
79 guchar *first = NULL, *second = NULL; /* Previous menu, submenu */
80 gint i;
81 GtkItemFactoryEntry *ret;
83 ret = g_malloc(sizeof(GtkItemFactoryEntry) * n);
84 for (i = 0; i < n; i++)
86 const gchar *from = entries[i].path;
87 gchar *trans, *slash;
88 int indent;
90 if (from[0] == '>')
92 if (from[1] == '>')
93 indent = 2;
94 else
95 indent = 1;
97 else
98 indent = 0;
100 if (from[indent])
101 from = _(from + indent);
102 else
103 from = "";
105 if (indent == 0)
106 trans = g_strdup_printf("/%s", from);
107 else if (indent == 1)
108 trans = g_strdup_printf("/%s/%s", first, from);
109 else
110 trans = g_strdup_printf("/%s/%s/%s",
111 first, second, from);
113 ret[i].path = trans;
115 g_free(first);
116 null_g_free(&second);
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;
139 ret[i].extra_data = entries[i].extra_data;
142 g_free(first);
143 g_free(second);
145 return ret;
148 void free_translated_entries(GtkItemFactoryEntry *entries, gint n)
150 gint i;
152 for (i=0; i<n; i++)
153 g_free(entries[i].path);
154 g_free(entries);
158 /****************************************************************
159 * INTERNAL FUNCTIONS *
160 ****************************************************************/
162 static void trans_changed(void)
164 if (!o_translation.has_changed)
165 return;
167 set_trans(o_translation.value);
169 if (i18n_message)
170 gtk_label_set_text(GTK_LABEL(i18n_message), MESSAGE);
173 /* Load the 'Messages/<name>.gmo' translation.
174 * Special values 'None' and 'From LANG' are also allowed.
176 static void set_trans(const guchar *lang)
178 guchar *path;
179 gchar *lang2;
181 g_return_if_fail(lang != NULL);
183 rox_clear_translation();
185 null_g_free(&current_lang);
187 if (strcmp(lang, "None") == 0)
188 return;
189 else if (strcmp(lang, "From LANG") == 0)
191 const guchar *end;
193 lang = getenv("LANG");
194 if (!lang)
195 return;
196 /* Extract the language code from the locale name.
197 * language[_territory][.codeset][@modifier]
200 end = strchr(lang, '.');
201 if (!end)
202 end = strchr(lang, '@');
203 if (end)
204 lang2 = g_strndup(lang, end - lang);
205 else
206 lang2 = g_strdup(lang);
208 else
209 lang2 = g_strdup(lang);
211 current_lang = lang2;
213 path = g_strdup_printf("%s/Messages/%s.gmo", app_dir, current_lang);
214 if (!file_exists(path) && strchr(current_lang, '_'))
216 /* Try again without the territory */
217 strcpy(strrchr(path, '_'), ".gmo");
220 if (file_exists(path))
221 rox_add_translations(path);
222 g_free(path);
225 static GList *build_i18n_message(Option *option, xmlNode *node, guchar *label)
227 GtkWidget *hbox, *image, *align;
229 g_return_val_if_fail(option == NULL, NULL);
230 g_return_val_if_fail(label == NULL, NULL);
231 g_return_val_if_fail(i18n_message == NULL, NULL);
233 i18n_message = gtk_label_new(MESSAGE);
234 g_signal_connect(i18n_message, "destroy",
235 G_CALLBACK(gtk_widget_destroyed), &i18n_message);
237 gtk_misc_set_alignment(GTK_MISC(i18n_message), 0, 0.5);
238 gtk_label_set_justify(GTK_LABEL(i18n_message), GTK_JUSTIFY_LEFT);
239 gtk_label_set_line_wrap(GTK_LABEL(i18n_message), TRUE);
241 hbox = gtk_hbox_new(FALSE, 4);
242 image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO,
243 GTK_ICON_SIZE_BUTTON);
244 align = gtk_alignment_new(0, 0, 0, 0);
246 gtk_container_add(GTK_CONTAINER(align), image);
247 gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, TRUE, 0);
248 gtk_box_pack_start(GTK_BOX(hbox), i18n_message, FALSE, TRUE, 0);
250 return g_list_append(NULL, hbox);