Index: tz-window.c
===================================================================
--- tz-window.c	(révision 10532)
+++ tz-window.c	(copie de travail)
@@ -119,7 +119,7 @@ tz_window_item_set_tooltip (TzWindowItem
 	 * (as in "FR") and the last string is another line (it's the one
 	 * looking like "BST (UTC +01:00)") */
 	text = g_strdup_printf (_("%s - %s\n%s"),
-				_(tz_location_get_zone (tz_loc)),
+				tz_location_get_display_text (tz_loc),
 				tz_location_get_country (tz_loc),
 				line);
 	g_free (line);
Index: tz.h
===================================================================
--- tz.h	(révision 10532)
+++ tz.h	(copie de travail)
@@ -58,6 +58,7 @@ void       tz_location_get_position   (T
 				       double     *latitude);
 const char *tz_location_get_country    (TzLocation *loc);
 const char *tz_location_get_zone       (TzLocation *loc);
+const char *tz_location_get_display_text (TzLocation *loc);
 #ifdef TZ_USE_COMMENT
 const char *tz_location_get_comment    (TzLocation *loc);
 #endif
Index: tz-list.c
===================================================================
--- tz-list.c	(révision 10532)
+++ tz-list.c	(copie de travail)
@@ -141,7 +141,7 @@ tz_list_item_get_zone (TzListItem *item)
 {
 	g_return_val_if_fail (item != NULL, NULL);
 
-	return tz_location_get_zone (item->tz_loc);
+	return tz_location_get_display_text (item->tz_loc);
 }
 
 const char *
Index: tz-sel-dialog.c
===================================================================
--- tz-sel-dialog.c	(révision 10532)
+++ tz-sel-dialog.c	(copie de travail)
@@ -169,8 +169,9 @@ tz_sel_dialog_set_hint (TzSelDialogData 
 	 * practice there are no reasons why it should */
 
 	if (data->point_hover)
-		zone = tz_location_get_zone (tz_location_from_point (data,
-								     data->point_hover));
+		zone = tz_location_get_display_text (
+				tz_location_from_point (data,
+							data->point_hover));
 	else
 		zone = NULL;
 
@@ -194,13 +195,13 @@ tz_sel_dialog_set_hint (TzSelDialogData 
 				 * second is a time. Result looks like this:
 				 * Europe/Paris - 15:45 */
 				location = g_strdup_printf (_("%s - %s"),
-							    _(zone), utf8);
+							    zone, utf8);
 				g_free (utf8);
 			};
 		}
 
 		if (location == NULL)
-			location = g_strdup (_(zone));
+			location = g_strdup (zone);
 	} else
 		location = g_strdup_printf ("<i>%s</i>", _("move the mouse on the map"));
 
@@ -596,7 +597,7 @@ tz_sel_dialog_fill_timezones (TzSelDialo
 
 		gtk_list_store_append (data->combo_store, &iter);
 		gtk_list_store_set (data->combo_store, &iter,
-				    COMBO_NAME_COLUMN, _(tz_location_get_zone (tzl)),
+				    COMBO_NAME_COLUMN, tz_location_get_display_text (tzl),
 				    COMBO_LOCATION_COLUMN, tzl,
 				    -1); 
 	}
@@ -614,7 +615,7 @@ tz_sel_dialog_fill_tree_view (TzSelDialo
 
 		gtk_list_store_append (data->list_store, &iter);
 		gtk_list_store_set (data->list_store, &iter,
-				    ZONE_COLUMN, _(tz_list_item_get_zone (item)),
+				    ZONE_COLUMN, tz_list_item_get_zone (item),
 				    NAME_COLUMN, tz_list_item_get_name (item),
 				    SORT_COLUMN, tz_list_item_get_sort_order (item),
 				    EDITABLE_COLUMN, TRUE,
@@ -633,7 +634,7 @@ tz_sel_dialog_item_added (TzList        
 	gtk_list_store_append (data->list_store, &iter);
 
 	gtk_list_store_set (data->list_store, &iter,
-			    ZONE_COLUMN, _(tz_list_item_get_zone (item)),
+			    ZONE_COLUMN, tz_list_item_get_zone (item),
 			    NAME_COLUMN, tz_list_item_get_name (item),
 			    SORT_COLUMN, tz_list_item_get_sort_order (item),
 			    EDITABLE_COLUMN, TRUE,
@@ -659,7 +660,7 @@ change_item (GtkTreeModel *model,
 
 	if (iter_item == item) {
 		gtk_list_store_set (GTK_LIST_STORE (model), iter,
-				    ZONE_COLUMN, _(tz_list_item_get_zone (item)),
+				    ZONE_COLUMN, tz_list_item_get_zone (item),
 				    NAME_COLUMN, tz_list_item_get_name (item),
 				    SORT_COLUMN, tz_list_item_get_sort_order (item),
 				    -1); 
Index: tz-cldr.c
===================================================================
--- tz-cldr.c	(révision 0)
+++ tz-cldr.c	(révision 0)
@@ -0,0 +1,395 @@
+/*
+ * tz-cldr.c: reads the CLDR data files for timezone information
+ *
+ * Copyright (C) 2007 Vincent Untz <vuntz@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *      Vincent Untz <vuntz@gnome.org>
+ */
+
+#include <config.h>
+
+#include <locale.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libxml/parser.h>
+
+#include "tz-cldr.h"
+
+/*
+ * Format of the CLDR xml file (part of interest to us):
+ *
+ * ldml
+ *  localeDisplayNames
+ *   territories
+ *    <territory type="002">Afrique</territory>
+ *  dates
+ *   timeZoneNames
+ *    <zone type="Africa/Timbuktu">
+ *     <exemplarCity>Tombouctou</exemplarCity>
+ *    </zone>
+ *    <metazone type="Atlantic">
+ *     <long>
+ *      <generic>Heure de l’Atlantique</generic>
+ *      <standard>Heure normale de l’Atlantique</standard>
+ *      <daylight>Heure avancée de l’Atlantique</daylight>
+ *     </long>
+ *     ...
+ *    </metazone>
+ */
+
+#define TZ_CLDR_PATH "/gnome/head/svn/gnome-panel/applets/clock"
+
+struct _TzCldr {
+	xmlDocPtr  docptr;
+	xmlNodePtr territoryptr;
+	xmlNodePtr tzptr;
+
+	xmlDocPtr  fallback_docptr;
+	xmlNodePtr fallback_territoryptr;
+	xmlNodePtr fallback_tzptr;
+};
+
+static char *
+tz_cldr_get_node_content (xmlDocPtr  doc,
+			  xmlNodePtr node)
+{
+	xmlChar *content;
+
+	if (!node || !node->children)
+		return NULL;
+
+	content = xmlNodeListGetString (doc, node->children, 1);
+
+	if (content) {
+		char *retval;
+
+		if (xmlStrcmp (content, (xmlChar *) "") == 0)
+			retval = NULL;
+		else
+			retval = g_strdup ((char *) content);
+
+		xmlFree (content);
+		return retval;
+	}
+
+	return NULL;
+}
+
+static xmlNodePtr
+tz_cldr_find_node (xmlNodePtr  root,
+		   const char *name)
+{
+	xmlNodePtr cur;
+
+	if (!root)
+		return NULL;
+
+	for (cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+		if ((xmlStrcmp (cur->name, (const xmlChar *) name)) == 0)
+			return cur;
+	}
+
+	return NULL;
+}
+
+static xmlNodePtr
+tz_cldr_find_node_with_attr (xmlNodePtr  root,
+			     const char *name,
+			     const char *attr_name,
+			     const char *attr_value)
+{
+	xmlNodePtr cur;
+
+	if (!root)
+		return NULL;
+
+	for (cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+		if ((xmlStrcmp (cur->name, (const xmlChar *) name)) == 0) {
+			gboolean  found;
+			xmlChar  *value;
+
+			value = xmlGetProp (cur, (xmlChar *) attr_name);
+
+			found = value &&
+				xmlStrcmp (value, (xmlChar *) attr_value) == 0;
+
+			if (value)
+				xmlFree (value);
+
+			if (found)
+				return cur;
+		}
+	}
+
+	return NULL;
+}
+
+static char *
+tz_cldr_get_territory_from_ptr (xmlDocPtr   doc,
+				xmlNodePtr  territoryptr,
+				const char *attr_value)
+{
+	xmlNodePtr ptr;
+
+	ptr = tz_cldr_find_node_with_attr (territoryptr, "territory", 
+					   "type", attr_value);
+
+	return tz_cldr_get_node_content (doc, ptr);
+}
+
+char *
+tz_cldr_get_territory (TzCldr     *cldr,
+		       const char *territory)
+{
+	char *attr_value;
+	char *retval;
+
+	g_return_val_if_fail (cldr != NULL, NULL);
+	g_return_val_if_fail (territory != NULL, NULL);
+
+	/* the attr values come from CLDR and should never change */
+	if (strcmp (territory, "Africa") == 0)
+		attr_value = "002";
+	else if (strcmp (territory, "America") == 0)
+		attr_value = "019";
+	else if (strcmp (territory, "Antarctica") == 0)
+		attr_value = "AQ";
+	else if (strcmp (territory, "Arctic") == 0)
+		return g_strdup (_("Arctic Ocean"));
+	else if (strcmp (territory, "Asia") == 0)
+		attr_value = "142";
+	else if (strcmp (territory, "Atlantic") == 0)
+		return g_strdup (_("Atlantic Ocean"));
+	else if (strcmp (territory, "Australia") == 0)
+		attr_value = "AU";
+	else if (strcmp (territory, "Europe") == 0)
+		attr_value = "150";
+	else if (strcmp (territory, "Indian") == 0)
+		return g_strdup (_("Indian Ocean"));
+	else if (strcmp (territory, "Pacific") == 0)
+		return g_strdup (_("Pacific Ocean"));
+	else
+		attr_value = NULL;
+
+	if (!attr_value)
+		return g_strdup (territory);
+
+	retval = tz_cldr_get_territory_from_ptr (cldr->docptr,
+						 cldr->territoryptr,
+						 attr_value);
+	if (!retval)
+		retval = tz_cldr_get_territory_from_ptr (cldr->fallback_docptr,
+							 cldr->fallback_territoryptr,
+							 attr_value);
+
+	if (retval)
+		return retval;
+	else
+		return g_strdup (territory);
+}
+
+static char *
+tz_cldr_get_timezone_from_ptr (xmlDocPtr   doc,
+			       xmlNodePtr  tzptr,
+			       const char *tz_id)
+{
+	xmlNodePtr ptr;
+
+	ptr = tz_cldr_find_node_with_attr (tzptr, "zone", "type", tz_id);
+	ptr = tz_cldr_find_node (ptr, "exemplarCity");
+
+	if (!ptr) {
+		ptr = tz_cldr_find_node_with_attr (tzptr, "metazone",
+						   "type", tz_id);
+		ptr = tz_cldr_find_node (ptr, "long");
+		ptr = tz_cldr_find_node (ptr, "generic");
+	}
+
+	return tz_cldr_get_node_content (doc, ptr);
+}
+
+char *
+tz_cldr_get_timezone (TzCldr     *cldr,
+		      const char *tz_id)
+{
+	char *retval;
+
+	g_return_val_if_fail (cldr != NULL, NULL);
+	g_return_val_if_fail (tz_id != NULL, NULL);
+
+	retval = tz_cldr_get_timezone_from_ptr (cldr->docptr,
+						cldr->tzptr, tz_id);
+	if (!retval)
+		retval = tz_cldr_get_timezone_from_ptr (cldr->fallback_docptr,
+							cldr->fallback_tzptr,
+							tz_id);
+
+	if (retval)
+		return retval;
+	else
+		return g_strdup (tz_id);
+}
+
+static void
+tz_cldr_get_filename_from_locale (char **filename,
+				  char **fallback_filename)
+{
+	char *locale;
+	char *language;
+	char *territory;
+	char *codeset;
+	char *modifier;
+	char *cldr_encoding;
+
+	/* language[_territory][.codeset][@modifier] */
+	locale = setlocale (LC_MESSAGES, NULL);
+
+	if (!locale) {
+		*filename = NULL;
+		*fallback_filename = NULL;
+		return;
+	}
+
+	if (strcmp (locale, "C") == 0 ||
+	    strcmp (locale, "POSIX") == 0) {
+		*filename = g_strdup_printf ("%s%cen_US_POSIX.xml",
+					     TZ_CLDR_PATH, G_DIR_SEPARATOR);
+		*fallback_filename = NULL;
+		return;
+	}
+
+	locale = g_strdup (locale);
+
+	modifier = strchr (locale, '@');
+	if (modifier) {
+		modifier [0] = '\0';
+		modifier++;
+	}
+
+	codeset = strchr (locale, '.');
+	if (codeset) {
+		codeset [0] = '\0';
+		codeset++;
+	}
+
+	territory = strchr (locale, '_');
+	if (territory) {
+		territory [0] = '\0';
+		territory++;
+	}
+
+	language = locale;
+
+	cldr_encoding = NULL;
+	if (modifier) {
+		/*
+		if (strcmp (modifier, "") == 0)
+			cldr_encoding = "Arab";
+		else */
+		if (strcmp (modifier, "cyrillic") == 0)
+			cldr_encoding = "Cyrl";
+		/*
+		else if (strcmp (modifier, "") == 0)
+			cldr_encoding = "Hans";
+		else if (strcmp (modifier, "") == 0)
+			cldr_encoding = "Hant";
+		else if (strcmp (modifier, "") == 0)
+			cldr_encoding = "Guru";
+		*/
+		else if (strcmp (modifier, "latin") == 0)
+			cldr_encoding = "Latn";
+	}
+
+	*filename = g_strdup_printf ("%s%c%s%s%s%s%s.xml",
+				     TZ_CLDR_PATH, G_DIR_SEPARATOR,
+				     language,
+				     cldr_encoding ? "_" : "",
+				     cldr_encoding ? cldr_encoding : "",
+				     territory ? "_" : "",
+				     territory ? territory : "");
+
+	*fallback_filename = g_strdup_printf ("%s%c%s.xml",
+					      TZ_CLDR_PATH, G_DIR_SEPARATOR,
+					      language);
+
+	g_free (locale);
+}
+
+TzCldr *
+tz_cldr_new (void)
+{
+	TzCldr     *cldr;
+	char       *filename;
+	char       *fallback;
+	xmlNodePtr  rootptr;
+	xmlNodePtr  fallback_rootptr;
+	xmlNodePtr  bufptr;
+
+	cldr = g_slice_new (TzCldr);
+
+	tz_cldr_get_filename_from_locale (&filename, &fallback);
+
+	if (filename) {
+		cldr->docptr = xmlParseFile (filename);
+		rootptr = xmlDocGetRootElement (cldr->docptr);
+	} else {
+		cldr->docptr = NULL;
+		rootptr = NULL;
+	}
+
+	if (fallback) {
+		cldr->fallback_docptr = xmlParseFile (fallback);
+		fallback_rootptr = xmlDocGetRootElement (cldr->fallback_docptr);
+	} else {
+		cldr->fallback_docptr = NULL;
+		fallback_rootptr = NULL;
+	}
+
+	bufptr = tz_cldr_find_node (rootptr, "localeDisplayNames");
+	cldr->territoryptr = tz_cldr_find_node (bufptr, "territories");
+
+	bufptr = tz_cldr_find_node (fallback_rootptr, "localeDisplayNames");
+	cldr->fallback_territoryptr = tz_cldr_find_node (bufptr, "territories");
+
+	bufptr = tz_cldr_find_node (rootptr, "dates");
+	cldr->tzptr = tz_cldr_find_node (bufptr, "timeZoneNames");
+
+	bufptr = tz_cldr_find_node (fallback_rootptr, "dates");
+	cldr->fallback_tzptr = tz_cldr_find_node (bufptr, "timeZoneNames");
+
+	return cldr;
+}
+
+void
+tz_cldr_free (TzCldr *cldr)
+{
+	g_return_if_fail (cldr != NULL);
+
+	if (cldr->docptr)
+		xmlFreeDoc (cldr->docptr);
+	cldr->docptr = NULL;
+
+	if (cldr->fallback_docptr)
+		xmlFreeDoc (cldr->fallback_docptr);
+	cldr->fallback_docptr = NULL;
+
+	g_slice_free (TzCldr, cldr);
+}
Index: tz-cldr.h
===================================================================
--- tz-cldr.h	(révision 0)
+++ tz-cldr.h	(révision 0)
@@ -0,0 +1,42 @@
+/*
+ * tz-cldr.h: reads the CLDR data files for timezone information
+ *
+ * Copyright (C) 2007 Vincent Untz <vuntz@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *      Vincent Untz <vuntz@gnome.org>
+ */
+
+#ifndef _TZ_CLDR_H
+#define _TZ_CLDR_H
+
+G_BEGIN_DECLS
+
+typedef struct _TzCldr TzCldr;
+
+TzCldr *tz_cldr_new  (void);
+void    tz_cldr_free (TzCldr *cldr);
+
+char *tz_cldr_get_territory (TzCldr     *cldr,
+			     const char *territory);
+char *tz_cldr_get_timezone  (TzCldr     *cldr,
+			     const char *tz_id);
+
+G_END_DECLS
+
+#endif /* _TZ_CLDR_H */
Index: Makefile.am
===================================================================
--- Makefile.am	(révision 10532)
+++ Makefile.am	(copie de travail)
@@ -35,6 +35,8 @@ CLOCK_SOURCES = 		\
 	tz-sel-dialog.h		\
  	tz-list.c		\
  	tz-list.h		\
+ 	tz-cldr.c		\
+ 	tz-cldr.h		\
  	tz.c			\
  	tz.h			\
 	obox.c			\
Index: tz.c
===================================================================
--- tz.c	(révision 10554)
+++ tz.c	(copie de travail)
@@ -37,6 +37,8 @@
 
 #include "tz.h"
 
+#include "tz-cldr.h"
+
 #ifdef HAVE_SOLARIS
 #define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
 #define ZONE_DIR     "/usr/share/lib/zoneinfo"
@@ -58,6 +60,8 @@ struct _TzLocation
 	gdouble latitude;
 	gdouble longitude;
 	char *zone;
+	char *display_text;
+	GSList *tree;
 #ifdef TZ_USE_COMMENT
 	char *comment;
 #endif
@@ -161,6 +165,7 @@ tz_build_db (void)
 {
   FILE *tzfile;
   char buf[4096];
+  TzCldr *cldr;
 
   g_assert (global_tz_db == NULL);
 
@@ -171,6 +176,8 @@ tz_build_db (void)
       return NULL;
     }
 
+  cldr = tz_cldr_new ();
+
   global_tz_db = g_new0 (TzDB, 1);
   global_tz_db->locations = g_ptr_array_new ();
 
@@ -201,6 +208,7 @@ tz_build_db (void)
       loc = g_slice_new (TzLocation);
       loc->country = g_strdup (tmpstrarr[0]);
       loc->zone = g_strdup (tmpstrarr[2]);
+      loc->display_text = tz_cldr_get_timezone (cldr, tmpstrarr[2]);
       loc->latitude = convert_pos (latstr, 2);
       loc->longitude = convert_pos (lngstr, 3);
 #ifdef HAVE_SOLARIS
@@ -246,6 +254,8 @@ tz_build_db (void)
 
   fclose (tzfile);
 
+  tz_cldr_free (cldr);
+
   /* now sort by country */
   g_ptr_array_sort (global_tz_db->locations, tz_location_cmp_zone);
 
@@ -258,11 +268,19 @@ tz_build_db (void)
 static void
 tz_location_free (TzLocation *tz)
 {
+  GSList *sl;
 
   if (tz->country)
     g_free (tz->country);
   if (tz->zone)
     g_free (tz->zone);
+  if (tz->display_text)
+    g_free (tz->display_text);
+  if (tz->display_text)
+    g_free (tz->display_text);
+  for (sl = tz->tree; sl != NULL; sl = sl->next)
+    g_free (sl->data);
+  g_slist_free (tz->tree);
 #ifdef TZ_USE_COMMENT
   if (tz->comment)
     g_free (tz->comment);
@@ -291,6 +309,12 @@ tz_location_get_zone (TzLocation *loc)
   return loc->zone;
 }
 
+const char *
+tz_location_get_display_text (TzLocation *loc)
+{
+  return loc->display_text;
+}
+
 #ifdef TZ_USE_COMMENT
 const char *
 tz_location_get_comment (TzLocation *loc)
