Updated Spanish translation
[evolution.git] / e-util / e-xml-utils.c
blobc3f9a03ce802717480517344f991b4570de06d6a
1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Authors:
16 * Chris Lahey <clahey@ximian.com>
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include "e-xml-utils.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <locale.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 #include <math.h>
39 #include <glib/gi18n.h>
40 #include <glib/gstdio.h>
41 #include <libxml/parser.h>
42 #include <libxml/xmlmemory.h>
44 #include "e-misc-utils.h"
46 /* Returns the first child with the name child_name and the "lang"
47 * attribute that matches the current LC_MESSAGES, or else, the first
48 * child with the name child_name and no "lang" attribute.
50 xmlNode *
51 e_xml_get_child_by_name_by_lang (const xmlNode *parent,
52 const xmlChar *child_name,
53 const gchar *lang)
55 #ifdef G_OS_WIN32
56 gchar *freeme = NULL;
57 #endif
58 xmlNode *child;
59 /* This is the default version of the string. */
60 xmlNode *C = NULL;
62 g_return_val_if_fail (parent != NULL, NULL);
63 g_return_val_if_fail (child_name != NULL, NULL);
65 if (lang == NULL) {
66 #ifndef G_OS_WIN32
67 #ifdef HAVE_LC_MESSAGES
68 lang = setlocale (LC_MESSAGES, NULL);
69 #else
70 lang = setlocale (LC_CTYPE, NULL);
71 #endif
72 #else
73 lang = freeme = g_win32_getlocale ();
74 #endif
76 for (child = parent->xmlChildrenNode; child != NULL; child = child->next) {
77 if (xmlStrcmp (child->name, child_name) == 0) {
78 xmlChar *this_lang = xmlGetProp (
79 child, (const guchar *)"lang");
80 if (this_lang == NULL) {
81 C = child;
82 } else if (xmlStrcmp (this_lang, (xmlChar *) lang) == 0) {
83 #ifdef G_OS_WIN32
84 g_free (freeme);
85 #endif
86 return child;
90 #ifdef G_OS_WIN32
91 g_free (freeme);
92 #endif
93 return C;
96 static xmlNode *
97 e_xml_get_child_by_name_by_lang_list_with_score (const xmlNode *parent,
98 const gchar *name,
99 const GList *lang_list,
100 gint *best_lang_score)
102 xmlNodePtr best_node = NULL, node;
104 for (node = parent->xmlChildrenNode; node != NULL; node = node->next) {
105 xmlChar *lang;
107 if (node->name == NULL || strcmp ((gchar *) node->name, name) != 0) {
108 continue;
110 lang = xmlGetProp (node, (const guchar *)"xml:lang");
111 if (lang != NULL) {
112 const GList *l;
113 gint i;
115 for (l = lang_list, i = 0;
116 l != NULL && i < *best_lang_score;
117 l = l->next, i++) {
118 if (strcmp ((gchar *) l->data, (gchar *) lang) == 0) {
119 best_node = node;
120 *best_lang_score = i;
123 } else {
124 if (best_node == NULL) {
125 best_node = node;
128 xmlFree (lang);
129 if (*best_lang_score == 0) {
130 return best_node;
134 return best_node;
137 xmlNode *
138 e_xml_get_child_by_name_by_lang_list (const xmlNode *parent,
139 const gchar *name,
140 const GList *lang_list)
142 gint best_lang_score = INT_MAX;
144 g_return_val_if_fail (parent != NULL, NULL);
145 g_return_val_if_fail (name != NULL, NULL);
147 if (lang_list == NULL) {
148 const gchar * const *language_names;
150 language_names = g_get_language_names ();
151 while (*language_names != NULL)
152 lang_list = g_list_append (
153 (GList *) lang_list, (gchar *) * language_names++);
155 return e_xml_get_child_by_name_by_lang_list_with_score
156 (parent,name,
157 lang_list,
158 &best_lang_score);
161 xmlNode *
162 e_xml_get_child_by_name_no_lang (const xmlNode *parent,
163 const gchar *name)
165 xmlNodePtr node;
167 g_return_val_if_fail (parent != NULL, NULL);
168 g_return_val_if_fail (name != NULL, NULL);
170 for (node = parent->xmlChildrenNode; node != NULL; node = node->next) {
171 xmlChar *lang;
173 if (node->name == NULL || strcmp ((gchar *) node->name, name) != 0) {
174 continue;
176 lang = xmlGetProp (node, (const guchar *)"xml:lang");
177 if (lang == NULL) {
178 return node;
180 xmlFree (lang);
183 return NULL;
186 gint
187 e_xml_get_integer_prop_by_name (const xmlNode *parent,
188 const xmlChar *prop_name)
190 g_return_val_if_fail (parent != NULL, 0);
191 g_return_val_if_fail (prop_name != NULL, 0);
193 return e_xml_get_integer_prop_by_name_with_default (parent, prop_name, 0);
196 gint
197 e_xml_get_integer_prop_by_name_with_default (const xmlNode *parent,
198 const xmlChar *prop_name,
199 gint def)
201 xmlChar *prop;
202 gint ret_val = def;
204 g_return_val_if_fail (parent != NULL, 0);
205 g_return_val_if_fail (prop_name != NULL, 0);
207 prop = xmlGetProp ((xmlNode *) parent, prop_name);
208 if (prop != NULL) {
209 (void) sscanf ((gchar *) prop, "%d", &ret_val);
210 xmlFree (prop);
212 return ret_val;
215 void
216 e_xml_set_integer_prop_by_name (xmlNode *parent,
217 const xmlChar *prop_name,
218 gint value)
220 gchar *valuestr;
222 g_return_if_fail (parent != NULL);
223 g_return_if_fail (prop_name != NULL);
225 valuestr = g_strdup_printf ("%d", value);
226 xmlSetProp (parent, prop_name, (guchar *) valuestr);
227 g_free (valuestr);
230 guint
231 e_xml_get_uint_prop_by_name (const xmlNode *parent,
232 const xmlChar *prop_name)
234 g_return_val_if_fail (parent != NULL, 0);
235 g_return_val_if_fail (prop_name != NULL, 0);
237 return e_xml_get_uint_prop_by_name_with_default (parent, prop_name, 0);
240 guint
241 e_xml_get_uint_prop_by_name_with_default (const xmlNode *parent,
242 const xmlChar *prop_name,
243 guint def)
245 xmlChar *prop;
246 guint ret_val = def;
248 g_return_val_if_fail (parent != NULL, 0);
249 g_return_val_if_fail (prop_name != NULL, 0);
251 prop = xmlGetProp ((xmlNode *) parent, prop_name);
252 if (prop != NULL) {
253 (void) sscanf ((gchar *) prop, "%u", &ret_val);
254 xmlFree (prop);
256 return ret_val;
259 void
260 e_xml_set_uint_prop_by_name (xmlNode *parent,
261 const xmlChar *prop_name,
262 guint value)
264 gchar *valuestr;
266 g_return_if_fail (parent != NULL);
267 g_return_if_fail (prop_name != NULL);
269 valuestr = g_strdup_printf ("%u", value);
270 xmlSetProp (parent, prop_name, (guchar *) valuestr);
271 g_free (valuestr);
274 gboolean
275 e_xml_get_bool_prop_by_name (const xmlNode *parent,
276 const xmlChar *prop_name)
278 g_return_val_if_fail (parent != NULL, 0);
279 g_return_val_if_fail (prop_name != NULL, 0);
281 return e_xml_get_bool_prop_by_name_with_default (
282 parent, prop_name, FALSE);
285 gboolean
286 e_xml_get_bool_prop_by_name_with_default (const xmlNode *parent,
287 const xmlChar *prop_name,
288 gboolean def)
290 xmlChar *prop;
291 gboolean ret_val = def;
293 g_return_val_if_fail (parent != NULL, 0);
294 g_return_val_if_fail (prop_name != NULL, 0);
296 prop = xmlGetProp ((xmlNode *) parent, prop_name);
297 if (prop != NULL) {
298 if (g_ascii_strcasecmp ((gchar *) prop, "true") == 0) {
299 ret_val = TRUE;
300 } else if (g_ascii_strcasecmp ((gchar *) prop, "false") == 0) {
301 ret_val = FALSE;
303 xmlFree (prop);
305 return ret_val;
308 void
309 e_xml_set_bool_prop_by_name (xmlNode *parent,
310 const xmlChar *prop_name,
311 gboolean value)
313 g_return_if_fail (parent != NULL);
314 g_return_if_fail (prop_name != NULL);
316 if (value) {
317 xmlSetProp (parent, prop_name, (const guchar *)"true");
318 } else {
319 xmlSetProp (parent, prop_name, (const guchar *)"false");
323 gdouble
324 e_xml_get_double_prop_by_name (const xmlNode *parent,
325 const xmlChar *prop_name)
327 g_return_val_if_fail (parent != NULL, 0);
328 g_return_val_if_fail (prop_name != NULL, 0);
330 return e_xml_get_double_prop_by_name_with_default (parent, prop_name, 0.0);
333 gdouble
334 e_xml_get_double_prop_by_name_with_default (const xmlNode *parent,
335 const xmlChar *prop_name,
336 gdouble def)
338 xmlChar *prop;
339 gdouble ret_val = def;
341 g_return_val_if_fail (parent != NULL, 0);
342 g_return_val_if_fail (prop_name != NULL, 0);
344 prop = xmlGetProp ((xmlNode *) parent, prop_name);
345 if (prop != NULL) {
346 ret_val = e_flexible_strtod ((gchar *) prop, NULL);
347 xmlFree (prop);
349 return ret_val;
352 void
353 e_xml_set_double_prop_by_name (xmlNode *parent,
354 const xmlChar *prop_name,
355 gdouble value)
357 gchar buffer[E_ASCII_DTOSTR_BUF_SIZE];
358 gchar *format;
360 g_return_if_fail (parent != NULL);
361 g_return_if_fail (prop_name != NULL);
363 if (fabs (value) < 1e9 && fabs (value) > 1e-5) {
364 format = g_strdup_printf ("%%.%df", DBL_DIG);
365 } else {
366 format = g_strdup_printf ("%%.%dg", DBL_DIG);
368 e_ascii_dtostr (buffer, sizeof (buffer), format, value);
369 g_free (format);
371 xmlSetProp (parent, prop_name, (const guchar *) buffer);
374 gchar *
375 e_xml_get_string_prop_by_name (const xmlNode *parent,
376 const xmlChar *prop_name)
378 g_return_val_if_fail (parent != NULL, NULL);
379 g_return_val_if_fail (prop_name != NULL, NULL);
381 return e_xml_get_string_prop_by_name_with_default (parent, prop_name, NULL);
384 gchar *
385 e_xml_get_string_prop_by_name_with_default (const xmlNode *parent,
386 const xmlChar *prop_name,
387 const gchar *def)
389 xmlChar *prop;
390 gchar *ret_val;
392 g_return_val_if_fail (parent != NULL, NULL);
393 g_return_val_if_fail (prop_name != NULL, NULL);
395 prop = xmlGetProp ((xmlNode *) parent, prop_name);
396 if (prop != NULL) {
397 ret_val = g_strdup ((gchar *) prop);
398 xmlFree (prop);
399 } else {
400 ret_val = g_strdup (def);
402 return ret_val;
405 void
406 e_xml_set_string_prop_by_name (xmlNode *parent,
407 const xmlChar *prop_name,
408 const gchar *value)
410 g_return_if_fail (parent != NULL);
411 g_return_if_fail (prop_name != NULL);
413 if (value != NULL) {
414 xmlSetProp (parent, prop_name, (guchar *) value);
418 gchar *
419 e_xml_get_translated_string_prop_by_name (const xmlNode *parent,
420 const xmlChar *prop_name)
422 xmlChar *prop;
423 gchar *ret_val = NULL;
424 gchar *combined_name;
426 g_return_val_if_fail (parent != NULL, NULL);
427 g_return_val_if_fail (prop_name != NULL, NULL);
429 prop = xmlGetProp ((xmlNode *) parent, prop_name);
430 if (prop != NULL) {
431 ret_val = g_strdup ((gchar *) prop);
432 xmlFree (prop);
433 return ret_val;
436 combined_name = g_strdup_printf ("_%s", prop_name);
437 prop = xmlGetProp ((xmlNode *) parent, (guchar *) combined_name);
438 if (prop != NULL) {
439 ret_val = g_strdup (gettext ((gchar *) prop));
440 xmlFree (prop);
442 g_free (combined_name);
444 return ret_val;