summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
authorGlynn Foster <glynn.foster@sun.com>2003-01-24 16:16:40 +0000
committerGlynn Foster <gman@src.gnome.org>2003-01-24 16:16:40 +0000
commit89255c3b352855d728ae3adc20b0cdd90fe582dd (patch)
treef11eb7e80cb88a3844d401070e32417272a0a804 /src/util.c
parent65daf49dc53cd37478602083790236c6d6cd8884 (diff)
Provide correct help URL.
2003-01-24 Glynn Foster <glynn.foster@sun.com> * src/about.c: Provide correct help URL. * src/util.h, src/util.c: Add functions from libgnome/gnome-i18n so that we can correctly find the apropriate help file. * xmldocs.make: Install help into $(datadir)/help/$(lang)/ * THANKS: Update from the code I stole from libgnome
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c332
1 files changed, 328 insertions, 4 deletions
diff --git a/src/util.c b/src/util.c
index dbc30d8..bbb6d77 100644
--- a/src/util.c
+++ b/src/util.c
@@ -4,6 +4,7 @@
* Copyright (C) 2002 Sun Microsystems, Inc.
* (C) 1999, 2000 Red Hat Inc.
* (C) 1998 James Henstridge
+ * (C) 1995-2002 Free Software Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,12 +24,15 @@
* Authors: Glynn Foster <glynn.foster@sun.com>
* Havoc Pennington <hp@redhat.com>
* James Henstridge <james@daa.com.au>
+ * Tom Tromey <tromey@redhat.com>
*/
#include <stdio.h>
+#include <locale.h>
#include <errno.h>
#include "config.h"
#include "util.h"
+#include "zenity.h"
#include <gconf/gconf-client.h>
#define URL_HANDLER_DIR "/desktop/gnome/url-handlers/"
@@ -164,12 +168,329 @@ zenity_util_set_window_icon_from_stock (GtkWidget *widget, const gchar *stock_id
g_object_unref (pixbuf);
}
+/* This is copied from libgnome/gnome-i18n.c since we try and avoid using
+ * the evils of gnome_program_init (), which messes up the commandline
+ */
+
+static GHashTable *alias_table = NULL;
+
+/*read an alias file for the locales*/
+static void
+zenity_read_aliases (char *file)
+{
+ FILE *fp;
+ char buf[256];
+
+ if (!alias_table)
+ alias_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ fp = fopen (file,"r");
+
+ if (!fp)
+ return;
+
+ while (fgets (buf,256,fp)) {
+ gchar *p;
+ g_strstrip (buf);
+
+ if (buf[0]=='#' || buf[0]=='\0')
+ continue;
+
+ p = (gchar *) strtok (buf, "\t ");
+
+ if (!p)
+ continue;
+
+ p = (gchar *) strtok (NULL, "\t ");
+
+ if(!p)
+ continue;
+
+ if (!g_hash_table_lookup (alias_table, buf))
+ g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (p));
+ }
+
+ fclose (fp);
+}
+
+/*return the un-aliased language as a newly allocated string*/
+static char *
+zenity_unalias_lang (char *lang)
+{
+ char *p;
+ int i;
+
+ if (!alias_table) {
+ zenity_read_aliases ("/usr/share/locale/locale.alias");
+ zenity_read_aliases ("/usr/local/share/locale/locale.alias");
+ zenity_read_aliases ("/usr/lib/X11/locale/locale.alias");
+ zenity_read_aliases ("/usr/openwin/lib/locale/locale.alias");
+ }
+
+ i = 0;
+ while ((p = g_hash_table_lookup (alias_table,lang)) && strcmp (p, lang)) {
+ lang = p;
+
+ if (i++ == 30) {
+ static gboolean said_before = FALSE;
+
+ if (!said_before)
+ g_warning (_("Too many alias levels for a locale may indicate a loop"));
+
+ said_before = TRUE;
+ return lang;
+ }
+ }
+ return lang;
+}
+
+/* Mask for components of locale spec. The ordering here is from
+ * least significant to most significant
+ */
+enum
+{
+ COMPONENT_CODESET = 1 << 0,
+ COMPONENT_TERRITORY = 1 << 1,
+ COMPONENT_MODIFIER = 1 << 2
+};
+
+/* Break an X/Open style locale specification into components
+ */
+static guint
+zenity_explode_locale (const gchar *locale,
+ gchar **language,
+ gchar **territory,
+ gchar **codeset,
+ gchar **modifier)
+{
+ const gchar *uscore_pos;
+ const gchar *at_pos;
+ const gchar *dot_pos;
+ guint mask = 0;
+
+ uscore_pos = (const gchar *) strchr (locale, '_');
+ dot_pos = (const gchar *) strchr (uscore_pos ? uscore_pos : locale, '.');
+ at_pos = (const gchar *) strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');
+
+ if (at_pos) {
+ mask |= COMPONENT_MODIFIER;
+ *modifier = g_strdup (at_pos);
+ } else
+ at_pos = locale + strlen (locale);
+
+ if (dot_pos) {
+ mask |= COMPONENT_CODESET;
+ *codeset = g_new (gchar, 1 + at_pos - dot_pos);
+ strncpy (*codeset, dot_pos, at_pos - dot_pos);
+ (*codeset) [at_pos - dot_pos] = '\0';
+ } else
+ dot_pos = at_pos;
+
+ if (uscore_pos) {
+ mask |= COMPONENT_TERRITORY;
+ *territory = g_new (gchar, 1 + dot_pos - uscore_pos);
+ strncpy (*territory, uscore_pos, dot_pos - uscore_pos);
+ (*territory)[dot_pos - uscore_pos] = '\0';
+ } else
+ uscore_pos = dot_pos;
+
+ *language = g_new (gchar, 1 + uscore_pos - locale);
+ strncpy (*language, locale, uscore_pos - locale);
+ (*language) [uscore_pos - locale] = '\0';
+
+ return mask;
+}
+
+static GList *
+zenity_compute_locale_variants (const gchar *locale)
+{
+ GList *retval = NULL;
+ gchar *language;
+ gchar *territory;
+ gchar *codeset;
+ gchar *modifier;
+ guint mask;
+ guint i;
+
+
+ g_return_val_if_fail (locale != NULL, NULL);
+
+ mask = zenity_explode_locale (locale, &language, &territory, &codeset, &modifier);
+
+ /* Iterate through all possible combinations, from least attractive
+ * to most attractive.
+ */
+
+ for (i = 0; i <= mask; i++)
+ if ((i & ~mask) == 0) {
+ gchar *val = g_strconcat (language,
+ (i & COMPONENT_TERRITORY) ? territory : "",
+ (i & COMPONENT_CODESET) ? codeset : "",
+ (i & COMPONENT_MODIFIER) ? modifier : "", NULL);
+ retval = g_list_prepend (retval, val);
+ }
+
+ g_free (language);
+
+ if (mask & COMPONENT_CODESET)
+ g_free (codeset);
+ if (mask & COMPONENT_TERRITORY)
+ g_free (territory);
+ if (mask & COMPONENT_MODIFIER)
+ g_free (modifier);
+
+ return retval;
+}
+
+static const gchar *
+zenity_guess_category_value (const gchar *categoryname)
+{
+ const gchar *retval;
+
+ /* The highest priority value is the `LANGUAGE' environment
+ * variable. This is a GNU extension.
+ */
+
+ retval = g_getenv ("LANGUAGE");
+
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* `LANGUAGE' is not set. So we have to proceed with the POSIX
+ * methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some
+ * systems this can be done by the `setlocale' function itself.
+ */
+
+ /* Setting of LC_ALL overwrites all other. */
+
+ retval = g_getenv ("LC_ALL");
+
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* Next comes the name of the desired category. */
+ retval = g_getenv (categoryname);
+
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ /* Last possibility is the LANG environment variable. */
+ retval = g_getenv ("LANG");
+ if (retval != NULL && retval[0] != '\0')
+ return retval;
+
+ return NULL;
+}
+
+
+static GHashTable *category_table= NULL;
+
+static const GList *
+zenity_i18n_get_language_list (const gchar *category_name)
+{
+ GList *list;
+
+ if (!category_name)
+ category_name= "LC_ALL";
+
+ if (category_table) {
+ list= g_hash_table_lookup (category_table, (const gpointer) category_name);
+ } else {
+ category_table= g_hash_table_new (g_str_hash, g_str_equal);
+ list= NULL;
+ }
+
+ if (!list) {
+ gint c_locale_defined= FALSE;
+ const gchar *category_value;
+ gchar *category_memory, *orig_category_memory;
+
+ category_value = zenity_guess_category_value (category_name);
+
+ if (! category_value)
+ category_value = "C";
+
+ orig_category_memory = category_memory = g_malloc (strlen (category_value) + 1);
+
+ while (category_value[0] != '\0') {
+ while (category_value[0] != '\0' && category_value[0] == ':')
+ ++category_value;
+
+ if (category_value[0] != '\0') {
+ char *cp= category_memory;
+
+ while (category_value[0] != '\0' && category_value[0] != ':')
+ *category_memory++= *category_value++;
+
+ category_memory[0]= '\0';
+ category_memory++;
+
+ cp = zenity_unalias_lang (cp);
+
+ if (strcmp (cp, "C") == 0)
+ c_locale_defined= TRUE;
+
+ list= g_list_concat (list, zenity_compute_locale_variants (cp));
+ }
+ }
+
+ g_free (orig_category_memory);
+
+ if (!c_locale_defined)
+ list= g_list_append (list, "C");
+
+ g_hash_table_insert (category_table, (gpointer) category_name, list);
+ }
+
+ return list;
+}
+
+/* This is copied from libgnome/gnome-help.c since we try and avoid using
+ * the evils of gnome_program_init (), which messes up the commandline
+ */
+
+static char *
+zenity_locate_help_file (const char *path, const char *doc_name)
+{
+ int i;
+ char *exts[] = { ".xml", ".docbook", ".sgml", ".html", "", NULL };
+ const GList *lang_list = zenity_i18n_get_language_list ("LC_MESSAGES");
+
+ for (;lang_list != NULL; lang_list = lang_list->next) {
+ const char *lang = lang_list->data;
+
+ /* This has to be a valid language AND a language with
+ * no encoding postfix. The language will come up without
+ * encoding next
+ */
+
+ if (lang == NULL || (gchar *) strchr (lang, '.') != NULL)
+ continue;
+
+ for (i = 0; exts[i] != NULL; i++) {
+ char *name;
+ char *full;
+
+ name = g_strconcat (doc_name, exts[i], NULL);
+ full = g_build_filename (path, lang, name, NULL);
+
+ if (g_file_test (full, G_FILE_TEST_EXISTS))
+ return full;
+
+ g_free (full);
+
+ }
+ }
+
+ return NULL;
+}
+
/* This is copied from libgnome/gnome-url.c since we try and avoid using
* the evils of gnome_program_init (), which messes up the commandline
*/
gboolean
-zenity_util_show_help (const gchar *url, GError **error)
+zenity_util_show_help (const gchar *path, const gchar *document, GError **error)
{
GConfClient *client;
gint i;
@@ -177,10 +498,13 @@ zenity_util_show_help (const gchar *url, GError **error)
int argc;
char **argv;
gboolean ret;
+ char *url;
- g_return_val_if_fail (url != NULL, FALSE);
-
- pos = strchr (url, ':');
+ g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (document != NULL, FALSE);
+
+ url = g_strconcat ("ghelp:///", zenity_locate_help_file (path, document), NULL);
+ pos = (gchar *) strchr (url, ':');
client = gconf_client_get_default ();