summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@fedoraproject.org>2007-10-14 06:15:56 +0000
committerMatthias Clasen <mclasen@fedoraproject.org>2007-10-14 06:15:56 +0000
commite0b3ac9bb97fdfcfaa66696b3173f0dc6a386a8e (patch)
tree9f8052f7d6e8d48a8a0de17016137a4b32845887
parenta2405b974a926937f0c49613761e30c4d583a93c (diff)
downloadgnome-panel-e0b3ac9bb97fdfcfaa66696b3173f0dc6a386a8e.tar.gz
gnome-panel-e0b3ac9bb97fdfcfaa66696b3173f0dc6a386a8e.tar.xz
gnome-panel-e0b3ac9bb97fdfcfaa66696b3173f0dc6a386a8e.zip
Add network monitoring to intlclockgnome-panel-2_20_0_1-8_fc9
-rw-r--r--gnome-panel.spec8
-rw-r--r--intlclock-changes-20071005.patch9697
-rw-r--r--intlclock-changes-20071009.patch10832
-rw-r--r--intlclock-changes-20071014.patch (renamed from intlclock-changes-20071013.patch)116
4 files changed, 111 insertions, 20542 deletions
diff --git a/gnome-panel.spec b/gnome-panel.spec
index c34adfa..7a6a43e 100644
--- a/gnome-panel.spec
+++ b/gnome-panel.spec
@@ -22,7 +22,7 @@
Summary: GNOME panel
Name: gnome-panel
Version: 2.20.0.1
-Release: 7%{?dist}
+Release: 8%{?dist}
URL: http://www.gnome.org
Source0: http://download.gnome.org/sources/gnome-panel/2.20/%{name}-%{version}.tar.bz2
# we are upstream for this
@@ -30,7 +30,7 @@ Source1: timezone.tar.gz
# Novell intlclock, I don't think this has a canonical upstream location
Source2: intlclock-1.0.tar.gz
Patch98: timezone-changes.patch
-Patch99: intlclock-changes-20071009.patch
+Patch99: intlclock-changes-20071014.patch
Patch100: dont-build-clock.patch
Patch101: intlclock-build-fixes.patch
@@ -94,6 +94,7 @@ BuildRequires: dbus-devel >= %{dbus_version}
BuildRequires: PolicyKit-devel
BuildRequires: gnome-applets-devel
BuildRequires: librsvg2-devel
+BuildRequires: NetworkManager-devel
Patch0: gnome-panel-2.19.5-vendor.patch
Patch1: gnome-panel-2.10.1-speak-to-us-ye-old-wise-fish.patch
@@ -380,6 +381,9 @@ fi
%{_datadir}/gtk-doc/html/*
%changelog
+* Sun Oct 14 2007 Matthias Clasen <mclasen@redhat.com> - 2.20.0.1-8
+- Add network monitoring to the intlclock
+
* Sat Oct 13 2007 Matthias Clasen <mclasen@redhat.com> - 2.20.0.1-7
- Another round of intlclock updates
* show offsets in popup
diff --git a/intlclock-changes-20071005.patch b/intlclock-changes-20071005.patch
deleted file mode 100644
index 32496a1..0000000
--- a/intlclock-changes-20071005.patch
+++ /dev/null
@@ -1,9697 +0,0 @@
-diff --git a/configure.in b/configure.in
-index 4e818da..6c75db1 100644
---- a/configure.in
-+++ b/configure.in
-@@ -59,7 +59,7 @@ if test -n "$LIBECAL_REQUIREMENT"; then
- fi
- AM_CONDITIONAL(HAVE_LIBECAL, test -n "$LIBECAL_REQUIREMENT")
-
--PKG_CHECK_MODULES(INTLCLOCK, [ glib-2.0 gobject-2.0 gtk+-2.0 gdk-2.0 librsvg-2.0 libpanelapplet-2.0 libgnome-2.0 gconf-2.0 $LIBECAL_REQUIREMENT ])
-+PKG_CHECK_MODULES(INTLCLOCK, [ glib-2.0 gobject-2.0 gtk+-2.0 gdk-2.0 librsvg-2.0 libpanelapplet-2.0 libgnome-2.0 gconf-2.0 $LIBECAL_REQUIREMENT dbus-glib-1 gweather libxml-2.0 polkit polkit-dbus ])
-
- AC_SUBST(INTLCLOCK_CFLAGS)
- AC_SUBST(INTLCLOCK_LIBS)
-diff --git a/data/GNOME_IntlClockApplet.xml b/data/GNOME_IntlClockApplet.xml
-index dd2e8b8..152f26c 100644
---- a/data/GNOME_IntlClockApplet.xml
-+++ b/data/GNOME_IntlClockApplet.xml
-@@ -1,9 +1,6 @@
- <Root>
- <popups>
- <popup name="button3">
-- <menuitem name="Clock Configure Item" verb="IntlClockConfig"
-- _label="Cha_nge Date or Time"
-- pixtype="stock" pixname="gtk-preferences"/>
- <menuitem name="Clock Preferences Item" verb="IntlClockPreferences" _label="_Preferences"
- pixtype="stock" pixname="gtk-properties"/>
- </popup>
-diff --git a/data/GNOME_IntlClockApplet_Factory.server.in.in b/data/GNOME_IntlClockApplet_Factory.server.in.in
-index 1446822..705fb76 100644
---- a/data/GNOME_IntlClockApplet_Factory.server.in.in
-+++ b/data/GNOME_IntlClockApplet_Factory.server.in.in
-@@ -20,7 +20,7 @@
- </oaf_attribute>
- <oaf_attribute name="name" type="string" value="International Clock"/>
- <oaf_attribute name="description" type="string" value="International Clock applet for the GNOME panel"/>
-- <oaf_attribute name="panel:icon" type="string" value="clock.png"/>
-+ <oaf_attribute name="panel:icon" type="string" value="gnome-panel-clock"/>
- </oaf_server>
-
- <oaf_server iid="OAFIID:GNOME_ClockApplet"
-diff --git a/data/intlclock.glade b/data/intlclock.glade
-index e7b8c01..b23ade0 100644
---- a/data/intlclock.glade
-+++ b/data/intlclock.glade
-@@ -26,7 +26,7 @@
- <property name="spacing">0</property>
-
- <child>
-- <widget class="GtkNotebook" id="notebook1">
-+ <widget class="GtkNotebook" id="notebook">
- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
-@@ -37,194 +37,35 @@
- <property name="enable_popup">False</property>
-
- <child>
-- <widget class="GtkTable" id="table1">
-- <property name="border_width">6</property>
-+ <widget class="GtkVBox" id="vbox17">
-+ <property name="border_width">12</property>
- <property name="visible">True</property>
-- <property name="n_rows">4</property>
-- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
-- <property name="row_spacing">6</property>
-- <property name="column_spacing">6</property>
-+ <property name="spacing">18</property>
-
- <child>
-- <widget class="GtkLabel" id="label11">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">Clock options:</property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label12">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label13">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">3</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label14">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">3</property>
-- <property name="bottom_attach">4</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label15">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">3</property>
-- <property name="bottom_attach">4</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkCheckButton" id="seconds_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">Show s_econds</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">3</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkHBox" id="hbox3">
-+ <widget class="GtkVBox" id="vbox18">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkRadioButton" id="12hr_radio">
-+ <widget class="GtkLabel" id="label210">
- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">12 _hour format</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-+ <property name="label" translatable="yes">&lt;b&gt;Clock Options&lt;/b&gt;</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">True</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
-@@ -234,290 +75,15 @@
- </child>
-
- <child>
-- <widget class="GtkRadioButton" id="24hr_radio">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">24 h_our format</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- <property name="group">12hr_radio</property>
-- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
-- </child>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options">fill</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkCheckButton" id="date_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">Show the _date</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label16">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label17">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label201">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">3</property>
-- <property name="bottom_attach">4</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
-- </widget>
-- <packing>
-- <property name="tab_expand">False</property>
-- <property name="tab_fill">True</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label1">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">General</property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="type">tab</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkTable" id="table5">
-- <property name="border_width">6</property>
-- <property name="visible">True</property>
-- <property name="n_rows">8</property>
-- <property name="n_columns">4</property>
-- <property name="homogeneous">False</property>
-- <property name="row_spacing">6</property>
-- <property name="column_spacing">6</property>
--
-- <child>
-- <widget class="GtkLabel" id="label36">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">3</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label37">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">3</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkScrolledWindow" id="scrolledwindow2">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
-- <property name="vscrollbar_policy">GTK_POLICY_NEVER</property>
-- <property name="shadow_type">GTK_SHADOW_IN</property>
-- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
--
-- <child>
-- <widget class="GtkTreeView" id="cities_list">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="headers_visible">False</property>
-- <property name="rules_hint">False</property>
-- <property name="reorderable">False</property>
-- <property name="enable_search">True</property>
-- <property name="fixed_height_mode">False</property>
-- <property name="hover_selection">False</property>
-- <property name="hover_expand">True</property>
-- </widget>
-- </child>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">8</property>
-- <property name="x_options">fill</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkAlignment" id="alignment6">
-- <property name="visible">True</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xscale">0</property>
-- <property name="yscale">1</property>
-- <property name="top_padding">0</property>
-- <property name="bottom_padding">0</property>
-- <property name="left_padding">0</property>
-- <property name="right_padding">0</property>
--
-- <child>
-- <widget class="GtkVBox" id="vbox2">
-+ <widget class="GtkHBox" id="hbox48">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
-- <property name="spacing">6</property>
-+ <property name="spacing">0</property>
-
- <child>
-- <widget class="GtkLabel" id="label39">
-+ <widget class="GtkLabel" id="label211">
- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-+ <property name="label"> </property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
-@@ -540,62 +106,163 @@
- </child>
-
- <child>
-- <widget class="GtkVButtonBox" id="vbuttonbox1">
-+ <widget class="GtkVBox" id="vbox19">
- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_START</property>
-+ <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkButton" id="prefs-locations-add-button">
-- <property name="width_request">24</property>
-- <property name="height_request">25</property>
-+ <widget class="GtkHBox" id="hbox49">
- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-add</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">13</property>
-+
-+ <child>
-+ <widget class="GtkRadioButton" id="12hr_radio">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">12 _hour format</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkRadioButton" id="24hr_radio">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">24 h_our format</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
-+ <property name="group">12hr_radio</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
- </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
- </child>
-
- <child>
-- <widget class="GtkButton" id="prefs-locations-edit-button">
-- <property name="width_request">24</property>
-- <property name="height_request">24</property>
-+ <widget class="GtkCheckButton" id="date_check">
- <property name="visible">True</property>
-- <property name="can_default">True</property>
- <property name="can_focus">True</property>
-- <property name="label">gtk-edit</property>
-- <property name="use_stock">True</property>
-+ <property name="label" translatable="yes">Show the _date</property>
-+ <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
- </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
- </child>
-
- <child>
-- <widget class="GtkButton" id="prefs-locations-remove-button">
-+ <widget class="GtkCheckButton" id="seconds_check">
- <property name="visible">True</property>
-- <property name="can_default">True</property>
- <property name="can_focus">True</property>
-- <property name="label">gtk-remove</property>
-- <property name="use_stock">True</property>
-+ <property name="label" translatable="yes">Show _seconds</property>
-+ <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
- </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
- </packing>
- </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox20">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label212">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">&lt;b&gt;Time Settings&lt;/b&gt;</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">True</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="time_settings_box">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-
- <child>
-- <widget class="GtkLabel" id="label38">
-+ <widget class="GtkLabel" id="label217">
- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-+ <property name="label"> </property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
-@@ -616,115 +283,377 @@
- <property name="fill">False</property>
- </packing>
- </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox52">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">12</property>
-+
-+ <child>
-+ <widget class="GtkCalendar" id="calendar">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="display_options">GTK_CALENDAR_SHOW_HEADING</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox22">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label218">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Current Time:</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label219">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Time:</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox23">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="current_time_label">
-+ <property name="visible">True</property>
-+ <property name="label">23:59:59</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox53">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkSpinButton" id="hours_spin">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="climb_rate">1</property>
-+ <property name="digits">0</property>
-+ <property name="numeric">True</property>
-+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-+ <property name="snap_to_ticks">False</property>
-+ <property name="wrap">True</property>
-+ <property name="adjustment">23 0 23 1 12 12</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkSpinButton" id="minutes_spin">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="climb_rate">1</property>
-+ <property name="digits">0</property>
-+ <property name="numeric">True</property>
-+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-+ <property name="snap_to_ticks">False</property>
-+ <property name="wrap">True</property>
-+ <property name="adjustment">59 0 59 1 30 30</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkSpinButton" id="seconds_spin">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="climb_rate">1</property>
-+ <property name="digits">0</property>
-+ <property name="numeric">True</property>
-+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-+ <property name="snap_to_ticks">False</property>
-+ <property name="wrap">True</property>
-+ <property name="adjustment">59 0 59 1 30 30</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkAlignment" id="alignment30">
-+ <property name="visible">True</property>
-+ <property name="xalign">1</property>
-+ <property name="yalign">1</property>
-+ <property name="xscale">0</property>
-+ <property name="yscale">0</property>
-+ <property name="top_padding">0</property>
-+ <property name="bottom_padding">0</property>
-+ <property name="left_padding">0</property>
-+ <property name="right_padding">0</property>
-+
-+ <child>
-+ <widget class="GtkButton" id="set_time_button">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Set System Time</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
- </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
- </child>
- </widget>
- <packing>
-- <property name="left_attach">3</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">8</property>
-- <property name="x_options"></property>
-- <property name="y_options">fill</property>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">True</property>
- </packing>
- </child>
-+ </widget>
-+ <packing>
-+ <property name="tab_expand">False</property>
-+ <property name="tab_fill">True</property>
-+ </packing>
-+ </child>
-
-- <child>
-- <widget class="GtkCheckButton" id="show_map_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">Show the world _map in the clock</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
-+ <child>
-+ <widget class="GtkLabel" id="label209">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">General</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="type">tab</property>
-+ </packing>
-+ </child>
-
-- <child>
-- <widget class="GtkLabel" id="label41">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
-+ <child>
-+ <widget class="GtkVBox" id="vbox24">
-+ <property name="border_width">12</property>
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">18</property>
-
- <child>
-- <widget class="GtkLabel" id="label160">
-+ <widget class="GtkHBox" id="hbox54">
- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">12</property>
-
-- <child>
-- <widget class="GtkCheckButton" id="show_locations_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">S_how locations in the clock</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-+ <child>
-+ <widget class="GtkScrolledWindow" id="scrolledwindow10">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
-+ <property name="vscrollbar_policy">GTK_POLICY_NEVER</property>
-+ <property name="shadow_type">GTK_SHADOW_IN</property>
-+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+
-+ <child>
-+ <widget class="GtkTreeView" id="cities_list">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="headers_visible">False</property>
-+ <property name="rules_hint">False</property>
-+ <property name="reorderable">False</property>
-+ <property name="enable_search">True</property>
-+ <property name="fixed_height_mode">False</property>
-+ <property name="hover_selection">False</property>
-+ <property name="hover_expand">True</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVButtonBox" id="vbuttonbox2">
-+ <property name="visible">True</property>
-+ <property name="layout_style">GTK_BUTTONBOX_START</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkButton" id="prefs-locations-add-button">
-+ <property name="width_request">24</property>
-+ <property name="height_request">25</property>
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-add</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="prefs-locations-edit-button">
-+ <property name="width_request">24</property>
-+ <property name="height_request">24</property>
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-edit</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="prefs-locations-remove-button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-remove</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
- </widget>
- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
- </packing>
- </child>
- </widget>
-@@ -735,7 +664,7 @@
- </child>
-
- <child>
-- <widget class="GtkLabel" id="label2">
-+ <widget class="GtkLabel" id="label220">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Locations</property>
- <property name="use_underline">False</property>
-@@ -791,80 +720,6 @@
- <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkButton" id="prefs-time-settings-button">
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
--
-- <child>
-- <widget class="GtkAlignment" id="alignment5">
-- <property name="visible">True</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xscale">0</property>
-- <property name="yscale">0</property>
-- <property name="top_padding">0</property>
-- <property name="bottom_padding">0</property>
-- <property name="left_padding">0</property>
-- <property name="right_padding">0</property>
--
-- <child>
-- <widget class="GtkHBox" id="hbox8">
-- <property name="visible">True</property>
-- <property name="homogeneous">False</property>
-- <property name="spacing">2</property>
--
-- <child>
-- <widget class="GtkImage" id="image5">
-- <property name="visible">True</property>
-- <property name="stock">gtk-properties</property>
-- <property name="icon_size">4</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label35">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">Time _Settings</property>
-- <property name="use_underline">True</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
-- </child>
-- </widget>
-- </child>
-- </widget>
-- </child>
-- </widget>
-- </child>
--
-- <child>
- <widget class="GtkButton" id="prefs-close-button">
- <property name="visible">True</property>
- <property name="can_default">True</property>
-@@ -910,13 +765,13 @@
-
- <child>
- <widget class="GtkVBox" id="vbox14">
-+ <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
-- <property name="spacing">0</property>
-+ <property name="spacing">24</property>
-
- <child>
- <widget class="GtkTable" id="table23">
-- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">3</property>
-@@ -926,7 +781,6 @@
-
- <child>
- <widget class="GtkVBox" id="vbox15">
-- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-@@ -1088,27 +942,6 @@
- </child>
-
- <child>
-- <widget class="GtkEntry" id="edit-location-name-entry">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="editable">True</property>
-- <property name="visibility">True</property>
-- <property name="max_length">0</property>
-- <property name="text" translatable="yes"></property>
-- <property name="has_frame">True</property>
-- <property name="invisible_char">●</property>
-- <property name="activates_default">False</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
- <widget class="GtkLabel" id="label208">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Longitude:</property>
-@@ -1269,6 +1102,57 @@ South</property>
- <property name="y_options"></property>
- </packing>
- </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox55">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkEntry" id="edit-location-name-entry">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="editable">True</property>
-+ <property name="visibility">True</property>
-+ <property name="max_length">0</property>
-+ <property name="text" translatable="yes"></property>
-+ <property name="has_frame">True</property>
-+ <property name="invisible_char">●</property>
-+ <property name="activates_default">False</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="find_location_button">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Find...</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="left_attach">1</property>
-+ <property name="right_attach">4</property>
-+ <property name="top_attach">1</property>
-+ <property name="bottom_attach">2</property>
-+ <property name="x_options">fill</property>
-+ <property name="y_options">fill</property>
-+ </packing>
-+ </child>
- </widget>
- <packing>
- <property name="padding">0</property>
-@@ -1294,60 +1178,33 @@ South</property>
- </child>
-
- <child>
-- <widget class="GtkHBox" id="hbox40">
-- <property name="border_width">6</property>
-+ <widget class="GtkHButtonBox" id="hbuttonbox20">
- <property name="visible">True</property>
-- <property name="homogeneous">False</property>
-- <property name="spacing">0</property>
-+ <property name="layout_style">GTK_BUTTONBOX_END</property>
-+ <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkHButtonBox" id="hbuttonbox12">
-+ <widget class="GtkButton" id="edit-location-cancel-button">
- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
-- <property name="spacing">0</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-cancel</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
- </child>
-
- <child>
-- <widget class="GtkHButtonBox" id="hbuttonbox18">
-+ <widget class="GtkButton" id="edit-location-ok-button">
- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_END</property>
-- <property name="spacing">6</property>
--
-- <child>
-- <widget class="GtkButton" id="edit-location-cancel-button">
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-cancel</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
--
-- <child>
-- <widget class="GtkButton" id="edit-location-ok-button">
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-ok</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-ok</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">True</property>
-- <property name="fill">True</property>
-- </packing>
- </child>
- </widget>
- <packing>
-@@ -1723,4 +1580,245 @@ South</property>
- </child>
- </widget>
-
-+<widget class="GtkWindow" id="find-location-window">
-+ <property name="title" translatable="yes"></property>
-+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
-+ <property name="window_position">GTK_WIN_POS_NONE</property>
-+ <property name="modal">False</property>
-+ <property name="resizable">True</property>
-+ <property name="destroy_with_parent">False</property>
-+ <property name="decorated">True</property>
-+ <property name="skip_taskbar_hint">False</property>
-+ <property name="skip_pager_hint">False</property>
-+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-+ <property name="focus_on_map">True</property>
-+ <property name="urgency_hint">False</property>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox25">
-+ <property name="border_width">12</property>
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">24</property>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox26">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkScrolledWindow" id="scrolledwindow11">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-+ <property name="shadow_type">GTK_SHADOW_IN</property>
-+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+
-+ <child>
-+ <widget class="GtkTreeView" id="find_location_tree">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="headers_visible">False</property>
-+ <property name="rules_hint">False</property>
-+ <property name="reorderable">False</property>
-+ <property name="enable_search">True</property>
-+ <property name="fixed_height_mode">False</property>
-+ <property name="hover_selection">False</property>
-+ <property name="hover_expand">False</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox56">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label221">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">_Find:</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="mnemonic_widget">find_location_entry</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkEntry" id="find_location_entry">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="editable">True</property>
-+ <property name="visibility">True</property>
-+ <property name="max_length">0</property>
-+ <property name="text" translatable="yes"></property>
-+ <property name="has_frame">True</property>
-+ <property name="invisible_char">•</property>
-+ <property name="activates_default">False</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="find_next_location_button">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+
-+ <child>
-+ <widget class="GtkAlignment" id="alignment31">
-+ <property name="visible">True</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xscale">0</property>
-+ <property name="yscale">0</property>
-+ <property name="top_padding">0</property>
-+ <property name="bottom_padding">0</property>
-+ <property name="left_padding">0</property>
-+ <property name="right_padding">0</property>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox57">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">2</property>
-+
-+ <child>
-+ <widget class="GtkImage" id="image29">
-+ <property name="visible">True</property>
-+ <property name="stock">gtk-find</property>
-+ <property name="icon_size">4</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label222">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Find _Next</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHButtonBox" id="hbuttonbox19">
-+ <property name="visible">True</property>
-+ <property name="layout_style">GTK_BUTTONBOX_END</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkButton" id="find-location-cancel-button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-cancel</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="find-location-ok-button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-ok</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+</widget>
-+
- </glade-interface>
-diff --git a/data/intlclock.schemas.in b/data/intlclock.schemas.in
-index 2ab6772..00fee4f 100644
---- a/data/intlclock.schemas.in
-+++ b/data/intlclock.schemas.in
-@@ -89,41 +89,54 @@
- </schema>
-
- <schema>
-- <key>/schemas/apps/intlclock_applet/prefs/show_locations</key>
-+ <key>/schemas/apps/intlclock_applet/prefs/cities</key>
-+ <owner>clock-applet</owner>
-+ <type>list</type>
-+ <list_type>string</list_type>
-+ <default>[]</default>
-+ <locale name="C">
-+ <short>List of cities for the clock.</short>
-+ <long>
-+ List of cities to display in the international clock.
-+ </long>
-+ </locale>
-+ </schema>
-+
-+ <schema>
-+ <key>/schemas/apps/intlclock_applet/prefs/expand_locations</key>
- <owner>clock-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
-- <short>Show other locations in clock</short>
-+ <short>Expand the location section in clock</short>
- <long>
-- If true, show a list of locations in the international clock.
-+ If true, expand the list of locations in the international clock.
- </long>
- </locale>
- </schema>
-
- <schema>
-- <key>/schemas/apps/intlclock_applet/prefs/show_map</key>
-+ <key>/schemas/apps/intlclock_applet/prefs/expand_tasks</key>
- <owner>clock-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
-- <short>Show world map in clock</short>
-+ <short>Expand the tasks section in clock</short>
- <long>
-- If true, show the world map in the international clock.
-+ If true, expand the list of tasks in the international clock.
- </long>
- </locale>
- </schema>
-
- <schema>
-- <key>/schemas/apps/intlclock_applet/prefs/cities</key>
-+ <key>/schemas/apps/intlclock_applet/prefs/expand_appointments</key>
- <owner>clock-applet</owner>
-- <type>list</type>
-- <list_type>string</list_type>
-- <default>[]</default>
-+ <type>bool</type>
-+ <default>true</default>
- <locale name="C">
-- <short>List of cities for the clock.</short>
-+ <short>Expand the appointments section in clock</short>
- <long>
-- List of cities to display in the international clock.
-+ If true, expand the list of appointments in the international clock.
- </long>
- </locale>
- </schema>
-diff --git a/intltool-extract.in b/intltool-extract.in
-deleted file mode 100755
-index bb6c368..340fc8d
---- a/intltool-extract.in
-+++ /dev/null
-@@ -1,841 +0,0 @@
--#!@INTLTOOL_PERL@ -w
--# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
--
--#
--# The Intltool Message Extractor
--#
--# Copyright (C) 2000-2001, 2003 Free Software Foundation.
--#
--# Intltool 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.
--#
--# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA.
--#
--# As a special exception to the GNU General Public License, if you
--# distribute this file as part of a program that contains a
--# configuration script generated by Autoconf, you may include it under
--# the same distribution terms that you use for the rest of that program.
--#
--# Authors: Kenneth Christiansen <kenneth@gnu.org>
--# Darin Adler <darin@bentspoon.com>
--#
--
--## Release information
--my $PROGRAM = "intltool-extract";
--my $PACKAGE = "intltool";
--my $VERSION = "0.35.0";
--
--## Loaded modules
--use strict;
--use File::Basename;
--use Getopt::Long;
--
--## Scalars used by the option stuff
--my $TYPE_ARG = "0";
--my $LOCAL_ARG = "0";
--my $HELP_ARG = "0";
--my $VERSION_ARG = "0";
--my $UPDATE_ARG = "0";
--my $QUIET_ARG = "0";
--my $SRCDIR_ARG = ".";
--
--my $FILE;
--my $OUTFILE;
--
--my $gettext_type = "";
--my $input;
--my %messages = ();
--my %loc = ();
--my %count = ();
--my %comments = ();
--my $strcount = 0;
--
--my $XMLCOMMENT = "";
--
--## Use this instead of \w for XML files to handle more possible characters.
--my $w = "[-A-Za-z0-9._:]";
--
--## Always print first
--$| = 1;
--
--## Handle options
--GetOptions (
-- "type=s" => \$TYPE_ARG,
-- "local|l" => \$LOCAL_ARG,
-- "help|h" => \$HELP_ARG,
-- "version|v" => \$VERSION_ARG,
-- "update" => \$UPDATE_ARG,
-- "quiet|q" => \$QUIET_ARG,
-- "srcdir=s" => \$SRCDIR_ARG,
-- ) or &error;
--
--&split_on_argument;
--
--
--## Check for options.
--## This section will check for the different options.
--
--sub split_on_argument {
--
-- if ($VERSION_ARG) {
-- &version;
--
-- } elsif ($HELP_ARG) {
-- &help;
--
-- } elsif ($LOCAL_ARG) {
-- &place_local;
-- &extract;
--
-- } elsif ($UPDATE_ARG) {
-- &place_normal;
-- &extract;
--
-- } elsif (@ARGV > 0) {
-- &place_normal;
-- &message;
-- &extract;
--
-- } else {
-- &help;
--
-- }
--}
--
--sub place_normal {
-- $FILE = $ARGV[0];
-- $OUTFILE = "$FILE.h";
--}
--
--sub place_local {
-- $FILE = $ARGV[0];
-- $OUTFILE = fileparse($FILE, ());
-- if (!-e "tmp/") {
-- system("mkdir tmp/");
-- }
-- $OUTFILE = "./tmp/$OUTFILE.h"
--}
--
--sub determine_type {
-- if ($TYPE_ARG =~ /^gettext\/(.*)/) {
-- $gettext_type=$1
-- }
--}
--
--## Sub for printing release information
--sub version{
-- print <<_EOF_;
--${PROGRAM} (${PACKAGE}) $VERSION
--Copyright (C) 2000, 2003 Free Software Foundation, Inc.
--Written by Kenneth Christiansen, 2000.
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--_EOF_
-- exit;
--}
--
--## Sub for printing usage information
--sub help {
-- print <<_EOF_;
--Usage: ${PROGRAM} [OPTION]... [FILENAME]
--Generates a header file from an XML source file.
--
--It grabs all strings between <_translatable_node> and its end tag in
--XML files. Read manpage (man ${PROGRAM}) for more info.
--
-- --type=TYPE Specify the file type of FILENAME. Currently supports:
-- "gettext/glade", "gettext/ini", "gettext/keys"
-- "gettext/rfc822deb", "gettext/schemas",
-- "gettext/scheme", "gettext/xml"
-- -l, --local Writes output into current working directory
-- (conflicts with --update)
-- --update Writes output into the same directory the source file
-- reside (conflicts with --local)
-- --srcdir Root of the source tree
-- -v, --version Output version information and exit
-- -h, --help Display this help and exit
-- -q, --quiet Quiet mode
--
--Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
--or send email to <xml-i18n-tools\@gnome.org>.
--_EOF_
-- exit;
--}
--
--## Sub for printing error messages
--sub error{
-- print STDERR "Try `${PROGRAM} --help' for more information.\n";
-- exit;
--}
--
--sub message {
-- print "Generating C format header file for translation.\n" unless $QUIET_ARG;
--}
--
--sub extract {
-- &determine_type;
--
-- &convert;
--
-- open OUT, ">$OUTFILE";
-- binmode (OUT) if $^O eq 'MSWin32';
-- &msg_write;
-- close OUT;
--
-- print "Wrote $OUTFILE\n" unless $QUIET_ARG;
--}
--
--sub convert {
--
-- ## Reading the file
-- {
-- local (*IN);
-- local $/; #slurp mode
-- open (IN, "<$SRCDIR_ARG/$FILE") || die "can't open $SRCDIR_ARG/$FILE: $!";
-- $input = <IN>;
-- }
--
-- &type_ini if $gettext_type eq "ini";
-- &type_keys if $gettext_type eq "keys";
-- &type_xml if $gettext_type eq "xml";
-- &type_glade if $gettext_type eq "glade";
-- &type_scheme if $gettext_type eq "scheme";
-- &type_schemas if $gettext_type eq "schemas";
-- &type_rfc822deb if $gettext_type eq "rfc822deb";
--}
--
--sub entity_decode_minimal
--{
-- local ($_) = @_;
--
-- s/&apos;/'/g; # '
-- s/&quot;/"/g; # "
-- s/&amp;/&/g;
--
-- return $_;
--}
--
--sub entity_decode
--{
-- local ($_) = @_;
--
-- s/&apos;/'/g; # '
-- s/&quot;/"/g; # "
-- s/&amp;/&/g;
-- s/&lt;/</g;
-- s/&gt;/>/g;
--
-- return $_;
--}
--
--sub escape_char
--{
-- return '\"' if $_ eq '"';
-- return '\n' if $_ eq "\n";
-- return '\\' if $_ eq '\\';
--
-- return $_;
--}
--
--sub escape
--{
-- my ($string) = @_;
-- return join "", map &escape_char, split //, $string;
--}
--
--sub type_ini {
-- ### For generic translatable desktop files ###
-- while ($input =~ /^_.*=(.*)$/mg) {
-- $messages{$1} = [];
-- }
--}
--
--sub type_keys {
-- ### For generic translatable mime/keys files ###
-- while ($input =~ /^\s*_\w+=(.*)$/mg) {
-- $messages{$1} = [];
-- }
--}
--
--sub type_xml {
-- ### For generic translatable XML files ###
-- my $tree = readXml($input);
-- parseTree(0, $tree);
--}
--
--sub print_var {
-- my $var = shift;
-- my $vartype = ref $var;
--
-- if ($vartype =~ /ARRAY/) {
-- my @arr = @{$var};
-- print "[ ";
-- foreach my $el (@arr) {
-- print_var($el);
-- print ", ";
-- }
-- print "] ";
-- } elsif ($vartype =~ /HASH/) {
-- my %hash = %{$var};
-- print "{ ";
-- foreach my $key (keys %hash) {
-- print "$key => ";
-- print_var($hash{$key});
-- print ", ";
-- }
-- print "} ";
-- } else {
-- print $var;
-- }
--}
--
--# Same syntax as getAttributeString in intltool-merge.in.in, similar logic (look for ## differences comment)
--sub getAttributeString
--{
-- my $sub = shift;
-- my $do_translate = shift || 1;
-- my $language = shift || "";
-- my $translate = shift;
-- my $result = "";
-- foreach my $e (reverse(sort(keys %{ $sub }))) {
-- my $key = $e;
-- my $string = $sub->{$e};
-- my $quote = '"';
--
-- $string =~ s/^[\s]+//;
-- $string =~ s/[\s]+$//;
--
-- if ($string =~ /^'.*'$/)
-- {
-- $quote = "'";
-- }
-- $string =~ s/^['"]//g;
-- $string =~ s/['"]$//g;
--
-- ## differences from intltool-merge.in.in
-- if ($key =~ /^_/) {
-- $comments{entity_decode($string)} = $XMLCOMMENT if $XMLCOMMENT;
-- $messages{entity_decode($string)} = [];
-- $$translate = 2;
-- }
-- ## differences end here from intltool-merge.in.in
-- $result .= " $key=$quote$string$quote";
-- }
-- return $result;
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub getXMLstring
--{
-- my $ref = shift;
-- my $spacepreserve = shift || 0;
-- my @list = @{ $ref };
-- my $result = "";
--
-- my $count = scalar(@list);
-- my $attrs = $list[0];
-- my $index = 1;
--
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
--
-- while ($index < $count) {
-- my $type = $list[$index];
-- my $content = $list[$index+1];
-- if (! $type ) {
-- # We've got CDATA
-- if ($content) {
-- # lets strip the whitespace here, and *ONLY* here
-- $content =~ s/\s+/ /gs if (!$spacepreserve);
-- $result .= $content;
-- }
-- } elsif ( "$type" ne "1" ) {
-- # We've got another element
-- $result .= "<$type";
-- $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
-- if ($content) {
-- my $subresult = getXMLstring($content, $spacepreserve);
-- if ($subresult) {
-- $result .= ">".$subresult . "</$type>";
-- } else {
-- $result .= "/>";
-- }
-- } else {
-- $result .= "/>";
-- }
-- }
-- $index += 2;
-- }
-- return $result;
--}
--
--# Verbatim copy from intltool-merge.in.in, except for MULTIPLE_OUTPUT handling removed
--# Translate list of nodes if necessary
--sub translate_subnodes
--{
-- my $fh = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $singlelang = shift || 0;
-- my $spacepreserve = shift || 0;
--
-- my @nodes = @{ $content };
--
-- my $count = scalar(@nodes);
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $nodes[$index];
-- my $rest = $nodes[$index+1];
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $index += 2;
-- }
--}
--
--# Based on traverse() in intltool-merge.in.in
--sub traverse
--{
-- my $fh = shift; # unused, to allow us to sync code between -merge and -extract
-- my $nodename = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $spacepreserve = shift || 0;
--
-- if ($nodename && "$nodename" eq "1") {
-- $XMLCOMMENT = $content;
-- } elsif ($nodename) {
-- # element
-- my @all = @{ $content };
-- my $attrs = shift @all;
-- my $translate = 0;
-- my $outattr = getAttributeString($attrs, 1, $language, \$translate);
--
-- if ($nodename =~ /^_/) {
-- $translate = 1;
-- $nodename =~ s/^_//;
-- }
-- my $lookup = '';
--
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- if ($translate) {
-- $lookup = getXMLstring($content, $spacepreserve);
-- if (!$spacepreserve) {
-- $lookup =~ s/^\s+//s;
-- $lookup =~ s/\s+$//s;
-- }
--
-- if ($lookup && $translate != 2) {
-- $comments{$lookup} = $XMLCOMMENT if $XMLCOMMENT;
-- $messages{$lookup} = [];
-- } elsif ($translate == 2) {
-- translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
-- }
-- } else {
-- $XMLCOMMENT = "";
-- my $count = scalar(@all);
-- if ($count > 0) {
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $all[$index];
-- my $rest = $all[$index+1];
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $index += 2;
-- }
-- }
-- }
-- $XMLCOMMENT = "";
-- }
--}
--
--
--# Verbatim copy from intltool-merge.in.in, $fh for compatibility
--sub parseTree
--{
-- my $fh = shift;
-- my $ref = shift;
-- my $language = shift || "";
--
-- my $name = shift @{ $ref };
-- my $cont = shift @{ $ref };
--
-- while (!$name || "$name" eq "1") {
-- $name = shift @{ $ref };
-- $cont = shift @{ $ref };
-- }
--
-- my $spacepreserve = 0;
-- my $attrs = @{$cont}[0];
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- traverse($fh, $name, $cont, $language, $spacepreserve);
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_comment
--{
-- my $expat = shift;
-- my $data = $expat->original_string();
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- $data =~ s/^<!--//s;
-- $data =~ s/-->$//s;
-- push @$clist, 1 => $data;
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_cdatastart
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- push @$clist, 0 => $expat->original_string();
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_cdataend
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- $clist->[$pos] .= $expat->original_string();
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_char
--{
-- my $expat = shift;
-- my $text = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- # Use original_string so that we retain escaped entities
-- # in CDATA sections.
-- #
-- if ($pos > 0 and $clist->[$pos - 1] eq '0') {
-- $clist->[$pos] .= $expat->original_string();
-- } else {
-- push @$clist, 0 => $expat->original_string();
-- }
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_start
--{
-- my $expat = shift;
-- my $tag = shift;
-- my @origlist = ();
--
-- # Use original_string so that we retain escaped entities
-- # in attribute values. We must convert the string to an
-- # @origlist array to conform to the structure of the Tree
-- # Style.
-- #
-- my @original_array = split /\x/, $expat->original_string();
-- my $source = $expat->original_string();
--
-- # Remove leading tag.
-- #
-- $source =~ s|^\s*<\s*(\S+)||s;
--
-- # Grab attribute key/value pairs and push onto @origlist array.
-- #
-- while ($source)
-- {
-- if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
-- push @origlist, $1;
-- push @origlist, '"' . $2 . '"';
-- }
-- elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
-- push @origlist, $1;
-- push @origlist, "'" . $2 . "'";
-- }
-- else
-- {
-- last;
-- }
-- }
--
-- my $ol = [ { @origlist } ];
--
-- push @{ $expat->{Lists} }, $expat->{Curlist};
-- push @{ $expat->{Curlist} }, $tag => $ol;
-- $expat->{Curlist} = $ol;
--}
--
--# Copied from intltool-merge.in.in and added comment handler.
--sub readXml
--{
-- my $xmldoc = shift || return;
-- my $ret = eval 'require XML::Parser';
-- if(!$ret) {
-- die "You must have XML::Parser installed to run $0\n\n";
-- }
-- my $xp = new XML::Parser(Style => 'Tree');
-- $xp->setHandlers(Char => \&intltool_tree_char);
-- $xp->setHandlers(Start => \&intltool_tree_start);
-- $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
-- $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
--
-- ## differences from intltool-merge.in.in
-- $xp->setHandlers(Comment => \&intltool_tree_comment);
-- ## differences end here from intltool-merge.in.in
--
-- my $tree = $xp->parse($xmldoc);
-- #print_var($tree);
--
--# <foo><!-- comment --><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
--# would be:
--# [foo, [{}, 1, "comment", head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar,
--# [{}, 0, "Howdy", ref, [{}]], 0, "do" ] ]
--
-- return $tree;
--}
--
--sub type_schemas {
-- ### For schemas XML files ###
--
-- # FIXME: We should handle escaped < (less than)
-- while ($input =~ /
-- <locale\ name="C">\s*
-- (<default>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/default>\s*)?
-- (<short>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/short>\s*)?
-- (<long>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/long>\s*)?
-- <\/locale>
-- /sgx) {
-- my @totranslate = ($3,$6,$9);
-- my @eachcomment = ($2,$5,$8);
-- foreach (@totranslate) {
-- my $currentcomment = shift @eachcomment;
-- next if !$_;
-- s/\s+/ /g;
-- $messages{entity_decode_minimal($_)} = [];
-- $comments{entity_decode_minimal($_)} = $currentcomment if (defined($currentcomment));
-- }
-- }
--}
--
--sub type_rfc822deb {
-- ### For rfc822-style Debian configuration files ###
--
-- my $lineno = 1;
-- my $type = '';
-- while ($input =~ /\G(.*?)(^|\n)(_+)([^:]+):[ \t]*(.*?)(?=\n\S|$)/sg)
-- {
-- my ($pre, $newline, $underscore, $tag, $text) = ($1, $2, $3, $4, $5);
-- while ($pre =~ m/\n/g)
-- {
-- $lineno ++;
-- }
-- $lineno += length($newline);
-- my @str_list = rfc822deb_split(length($underscore), $text);
-- for my $str (@str_list)
-- {
-- $strcount++;
-- $messages{$str} = [];
-- $loc{$str} = $lineno;
-- $count{$str} = $strcount;
-- my $usercomment = '';
-- while($pre =~ s/(^|\n)#([^\n]*)$//s)
-- {
-- $usercomment = "\n" . $2 . $usercomment;
-- }
-- $comments{$str} = $tag . $usercomment;
-- }
-- $lineno += ($text =~ s/\n//g);
-- }
--}
--
--sub rfc822deb_split {
-- # Debian defines a special way to deal with rfc822-style files:
-- # when a value contain newlines, it consists of
-- # 1. a short form (first line)
-- # 2. a long description, all lines begin with a space,
-- # and paragraphs are separated by a single dot on a line
-- # This routine returns an array of all paragraphs, and reformat
-- # them.
-- # When first argument is 2, the string is a comma separated list of
-- # values.
-- my $type = shift;
-- my $text = shift;
-- $text =~ s/^[ \t]//mg;
-- return (split(/, */, $text, 0)) if $type ne 1;
-- return ($text) if $text !~ /\n/;
--
-- $text =~ s/([^\n]*)\n//;
-- my @list = ($1);
-- my $str = '';
-- for my $line (split (/\n/, $text))
-- {
-- chomp $line;
-- if ($line =~ /^\.\s*$/)
-- {
-- # New paragraph
-- $str =~ s/\s*$//;
-- push(@list, $str);
-- $str = '';
-- }
-- elsif ($line =~ /^\s/)
-- {
-- # Line which must not be reformatted
-- $str .= "\n" if length ($str) && $str !~ /\n$/;
-- $line =~ s/\s+$//;
-- $str .= $line."\n";
-- }
-- else
-- {
-- # Continuation line, remove newline
-- $str .= " " if length ($str) && $str !~ /\n$/;
-- $str .= $line;
-- }
-- }
-- $str =~ s/\s*$//;
-- push(@list, $str) if length ($str);
-- return @list;
--}
--
--sub type_glade {
-- ### For translatable Glade XML files ###
--
-- my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message";
--
-- while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) {
-- # Glade sometimes uses tags that normally mark translatable things for
-- # little bits of non-translatable content. We work around this by not
-- # translating strings that only includes something like label4 or window1.
-- $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label|dialog)[0-9]+$/;
-- }
--
-- while ($input =~ /<items>(..[^<]*)<\/items>/sg) {
-- for my $item (split (/\n/, $1)) {
-- $messages{entity_decode($item)} = [];
-- }
-- }
--
-- ## handle new glade files
-- while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?:\s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) {
-- $messages{entity_decode($3)} = [] unless $3 =~ /^(window|label)[0-9]+$/;
-- if (defined($2) and !($3 =~ /^(window|label)[0-9]+$/)) {
-- $comments{entity_decode($3)} = entity_decode($2) ;
-- }
-- }
-- while ($input =~ /<atkaction\s+action_name="([^>]*)"\s+description="([^>]+)"\/>/sg) {
-- $messages{entity_decode_minimal($2)} = [];
-- }
--}
--
--sub type_scheme {
-- my ($line, $i, $state, $str, $trcomment, $char);
-- for $line (split(/\n/, $input)) {
-- $i = 0;
-- $state = 0; # 0 - nothing, 1 - string, 2 - translatable string
-- while ($i < length($line)) {
-- if (substr($line,$i,1) eq "\"") {
-- if ($state == 2) {
-- $comments{$str} = $trcomment if ($trcomment);
-- $messages{$str} = [];
-- $str = '';
-- $state = 0; $trcomment = "";
-- } elsif ($state == 1) {
-- $str = '';
-- $state = 0; $trcomment = "";
-- } else {
-- $state = 1;
-- $str = '';
-- if ($i>0 && substr($line,$i-1,1) eq '_') {
-- $state = 2;
-- }
-- }
-- } elsif (!$state) {
-- if (substr($line,$i,1) eq ";") {
-- $trcomment = substr($line,$i+1);
-- $trcomment =~ s/^;*\s*//;
-- $i = length($line);
-- } elsif ($trcomment && substr($line,$i,1) !~ /\s|\(|\)|_/) {
-- $trcomment = "";
-- }
-- } else {
-- if (substr($line,$i,1) eq "\\") {
-- $char = substr($line,$i+1,1);
-- if ($char ne "\"" && $char ne "\\") {
-- $str = $str . "\\";
-- }
-- $i++;
-- }
-- $str = $str . substr($line,$i,1);
-- }
-- $i++;
-- }
-- }
--}
--
--sub msg_write {
-- my @msgids;
-- if (%count)
-- {
-- @msgids = sort { $count{$a} <=> $count{$b} } keys %count;
-- }
-- else
-- {
-- @msgids = sort keys %messages;
-- }
-- for my $message (@msgids)
-- {
-- my $offsetlines = 1;
-- $offsetlines++ if $message =~ /%/;
-- if (defined ($comments{$message}))
-- {
-- while ($comments{$message} =~ m/\n/g)
-- {
-- $offsetlines++;
-- }
-- }
-- print OUT "# ".($loc{$message} - $offsetlines). " \"$FILE\"\n"
-- if defined $loc{$message};
-- print OUT "/* ".$comments{$message}." */\n"
-- if defined $comments{$message};
-- print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/;
--
-- my @lines = split (/\n/, $message, -1);
-- for (my $n = 0; $n < @lines; $n++)
-- {
-- if ($n == 0)
-- {
-- print OUT "char *s = N_(\"";
-- }
-- else
-- {
-- print OUT " \"";
-- }
--
-- print OUT escape($lines[$n]);
--
-- if ($n < @lines - 1)
-- {
-- print OUT "\\n\"\n";
-- }
-- else
-- {
-- print OUT "\");\n";
-- }
-- }
-- }
--}
--
-diff --git a/intltool-extract.in b/intltool-extract.in
-new file mode 120000
-index bb6c368..340fc8d
---- /dev/null
-+++ b/intltool-extract.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/intltool-extract.in
-\ No newline at end of file
-diff --git a/intltool-merge.in b/intltool-merge.in
-deleted file mode 100755
-index d0535ab..2238bbd
---- a/intltool-merge.in
-+++ /dev/null
-@@ -1,1356 +0,0 @@
--#!@INTLTOOL_PERL@ -w
--# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
--
--#
--# The Intltool Message Merger
--#
--# Copyright (C) 2000, 2003 Free Software Foundation.
--# Copyright (C) 2000, 2001 Eazel, Inc
--#
--# Intltool is free software; you can redistribute it and/or
--# modify it under the terms of the GNU General Public License
--# version 2 published by the Free Software Foundation.
--#
--# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA.
--#
--# As a special exception to the GNU General Public License, if you
--# distribute this file as part of a program that contains a
--# configuration script generated by Autoconf, you may include it under
--# the same distribution terms that you use for the rest of that program.
--#
--# Authors: Maciej Stachowiak <mjs@noisehavoc.org>
--# Kenneth Christiansen <kenneth@gnu.org>
--# Darin Adler <darin@bentspoon.com>
--#
--# Proper XML UTF-8'ification written by Cyrille Chepelov <chepelov@calixo.net>
--#
--
--## Release information
--my $PROGRAM = "intltool-merge";
--my $PACKAGE = "intltool";
--my $VERSION = "0.35.0";
--
--## Loaded modules
--use strict;
--use Getopt::Long;
--use Text::Wrap;
--use File::Basename;
--
--my $must_end_tag = -1;
--my $last_depth = -1;
--my $translation_depth = -1;
--my @tag_stack = ();
--my @entered_tag = ();
--my @translation_strings = ();
--my $leading_space = "";
--
--## Scalars used by the option stuff
--my $HELP_ARG = 0;
--my $VERSION_ARG = 0;
--my $BA_STYLE_ARG = 0;
--my $XML_STYLE_ARG = 0;
--my $KEYS_STYLE_ARG = 0;
--my $DESKTOP_STYLE_ARG = 0;
--my $SCHEMAS_STYLE_ARG = 0;
--my $RFC822DEB_STYLE_ARG = 0;
--my $QUIET_ARG = 0;
--my $PASS_THROUGH_ARG = 0;
--my $UTF8_ARG = 0;
--my $MULTIPLE_OUTPUT = 0;
--my $cache_file;
--
--## Handle options
--GetOptions
--(
-- "help" => \$HELP_ARG,
-- "version" => \$VERSION_ARG,
-- "quiet|q" => \$QUIET_ARG,
-- "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility
-- "ba-style|b" => \$BA_STYLE_ARG,
-- "xml-style|x" => \$XML_STYLE_ARG,
-- "keys-style|k" => \$KEYS_STYLE_ARG,
-- "desktop-style|d" => \$DESKTOP_STYLE_ARG,
-- "schemas-style|s" => \$SCHEMAS_STYLE_ARG,
-- "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG,
-- "pass-through|p" => \$PASS_THROUGH_ARG,
-- "utf8|u" => \$UTF8_ARG,
-- "multiple-output|m" => \$MULTIPLE_OUTPUT,
-- "cache|c=s" => \$cache_file
-- ) or &error;
--
--my $PO_DIR;
--my $FILE;
--my $OUTFILE;
--
--my %po_files_by_lang = ();
--my %translations = ();
--my $iconv = $ENV{"ICONV"} || $ENV{"INTLTOOL_ICONV"} || "@INTLTOOL_ICONV@";
--my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null');
--
--# Use this instead of \w for XML files to handle more possible characters.
--my $w = "[-A-Za-z0-9._:]";
--
--# XML quoted string contents
--my $q = "[^\\\"]*";
--
--## Check for options.
--
--if ($VERSION_ARG)
--{
-- &print_version;
--}
--elsif ($HELP_ARG)
--{
-- &print_help;
--}
--elsif ($BA_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &ba_merge_translations;
-- &finalize;
--}
--elsif ($XML_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &xml_merge_output;
-- &finalize;
--}
--elsif ($KEYS_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &keys_merge_translations;
-- &finalize;
--}
--elsif ($DESKTOP_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &desktop_merge_translations;
-- &finalize;
--}
--elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &schemas_merge_translations;
-- &finalize;
--}
--elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2)
--{
-- &preparation;
-- &print_message;
-- &rfc822deb_merge_translations;
-- &finalize;
--}
--else
--{
-- &print_help;
--}
--
--exit;
--
--## Sub for printing release information
--sub print_version
--{
-- print <<_EOF_;
--${PROGRAM} (${PACKAGE}) ${VERSION}
--Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen.
--
--Copyright (C) 2000-2003 Free Software Foundation, Inc.
--Copyright (C) 2000-2001 Eazel, Inc.
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--_EOF_
-- exit;
--}
--
--## Sub for printing usage information
--sub print_help
--{
-- print <<_EOF_;
--Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE
--Generates an output file that includes some localized attributes from an
--untranslated source file.
--
--Mandatory options: (exactly one must be specified)
-- -b, --ba-style includes translations in the bonobo-activation style
-- -d, --desktop-style includes translations in the desktop style
-- -k, --keys-style includes translations in the keys style
-- -s, --schemas-style includes translations in the schemas style
-- -r, --rfc822deb-style includes translations in the RFC822 style
-- -x, --xml-style includes translations in the standard xml style
--
--Other options:
-- -u, --utf8 convert all strings to UTF-8 before merging
-- (default for everything except RFC822 style)
-- -p, --pass-through deprecated, does nothing and issues a warning
-- -m, --multiple-output output one localized file per locale, instead of
-- a single file containing all localized elements
-- -c, --cache=FILE specify cache file name
-- (usually \$top_builddir/po/.intltool-merge-cache)
-- -q, --quiet suppress most messages
-- --help display this help and exit
-- --version output version information and exit
--
--Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
--or send email to <xml-i18n-tools\@gnome.org>.
--_EOF_
-- exit;
--}
--
--
--## Sub for printing error messages
--sub print_error
--{
-- print STDERR "Try `${PROGRAM} --help' for more information.\n";
-- exit;
--}
--
--
--sub print_message
--{
-- print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG;
--}
--
--
--sub preparation
--{
-- $PO_DIR = $ARGV[0];
-- $FILE = $ARGV[1];
-- $OUTFILE = $ARGV[2];
--
-- &gather_po_files;
-- &get_translation_database;
--}
--
--# General-purpose code for looking up translations in .po files
--
--sub po_file2lang
--{
-- my ($tmp) = @_;
-- $tmp =~ s/^.*\/(.*)\.po$/$1/;
-- return $tmp;
--}
--
--sub gather_po_files
--{
-- for my $po_file (glob "$PO_DIR/*.po") {
-- $po_files_by_lang{po_file2lang($po_file)} = $po_file;
-- }
--}
--
--sub get_local_charset
--{
-- my ($encoding) = @_;
-- my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "@INTLTOOL_LIBDIR@/charset.alias";
--
-- # seek character encoding aliases in charset.alias (glib)
--
-- if (open CHARSET_ALIAS, $alias_file)
-- {
-- while (<CHARSET_ALIAS>)
-- {
-- next if /^\#/;
-- return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i)
-- }
--
-- close CHARSET_ALIAS;
-- }
--
-- # if not found, return input string
--
-- return $encoding;
--}
--
--sub get_po_encoding
--{
-- my ($in_po_file) = @_;
-- my $encoding = "";
--
-- open IN_PO_FILE, $in_po_file or die;
-- while (<IN_PO_FILE>)
-- {
-- ## example: "Content-Type: text/plain; charset=ISO-8859-1\n"
-- if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/)
-- {
-- $encoding = $1;
-- last;
-- }
-- }
-- close IN_PO_FILE;
--
-- if (!$encoding)
-- {
-- print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG;
-- $encoding = "ISO-8859-1";
-- }
--
-- system ("$iconv -f $encoding -t UTF-8 <$devnull 2>$devnull");
-- if ($?) {
-- $encoding = get_local_charset($encoding);
-- }
--
-- return $encoding
--}
--
--sub utf8_sanity_check
--{
-- print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG;
-- $UTF8_ARG = 1;
--}
--
--sub get_translation_database
--{
-- if ($cache_file) {
-- &get_cached_translation_database;
-- } else {
-- &create_translation_database;
-- }
--}
--
--sub get_newest_po_age
--{
-- my $newest_age;
--
-- foreach my $file (values %po_files_by_lang)
-- {
-- my $file_age = -M $file;
-- $newest_age = $file_age if !$newest_age || $file_age < $newest_age;
-- }
--
-- $newest_age = 0 if !$newest_age;
--
-- return $newest_age;
--}
--
--sub create_cache
--{
-- print "Generating and caching the translation database\n" unless $QUIET_ARG;
--
-- &create_translation_database;
--
-- open CACHE, ">$cache_file" || die;
-- print CACHE join "\x01", %translations;
-- close CACHE;
--}
--
--sub load_cache
--{
-- print "Found cached translation database\n" unless $QUIET_ARG;
--
-- my $contents;
-- open CACHE, "<$cache_file" || die;
-- {
-- local $/;
-- $contents = <CACHE>;
-- }
-- close CACHE;
-- %translations = split "\x01", $contents;
--}
--
--sub get_cached_translation_database
--{
-- my $cache_file_age = -M $cache_file;
-- if (defined $cache_file_age)
-- {
-- if ($cache_file_age <= &get_newest_po_age)
-- {
-- &load_cache;
-- return;
-- }
-- print "Found too-old cached translation database\n" unless $QUIET_ARG;
-- }
--
-- &create_cache;
--}
--
--sub create_translation_database
--{
-- for my $lang (keys %po_files_by_lang)
-- {
-- my $po_file = $po_files_by_lang{$lang};
--
-- if ($UTF8_ARG)
-- {
-- my $encoding = get_po_encoding ($po_file);
--
-- if (lc $encoding eq "utf-8")
-- {
-- open PO_FILE, "<$po_file";
-- }
-- else
-- {
-- print "NOTICE: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;;
--
-- open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|";
-- }
-- }
-- else
-- {
-- open PO_FILE, "<$po_file";
-- }
--
-- my $nextfuzzy = 0;
-- my $inmsgid = 0;
-- my $inmsgstr = 0;
-- my $msgid = "";
-- my $msgstr = "";
--
-- while (<PO_FILE>)
-- {
-- $nextfuzzy = 1 if /^#, fuzzy/;
--
-- if (/^msgid "((\\.|[^\\])*)"/ )
-- {
-- $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
-- $msgid = "";
-- $msgstr = "";
--
-- if ($nextfuzzy) {
-- $inmsgid = 0;
-- } else {
-- $msgid = unescape_po_string($1);
-- $inmsgid = 1;
-- }
-- $inmsgstr = 0;
-- $nextfuzzy = 0;
-- }
--
-- if (/^msgstr "((\\.|[^\\])*)"/)
-- {
-- $msgstr = unescape_po_string($1);
-- $inmsgstr = 1;
-- $inmsgid = 0;
-- }
--
-- if (/^"((\\.|[^\\])*)"/)
-- {
-- $msgid .= unescape_po_string($1) if $inmsgid;
-- $msgstr .= unescape_po_string($1) if $inmsgstr;
-- }
-- }
-- $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
-- }
--}
--
--sub finalize
--{
--}
--
--sub unescape_one_sequence
--{
-- my ($sequence) = @_;
--
-- return "\\" if $sequence eq "\\\\";
-- return "\"" if $sequence eq "\\\"";
-- return "\n" if $sequence eq "\\n";
-- return "\r" if $sequence eq "\\r";
-- return "\t" if $sequence eq "\\t";
-- return "\b" if $sequence eq "\\b";
-- return "\f" if $sequence eq "\\f";
-- return "\a" if $sequence eq "\\a";
-- return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7)
--
-- return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/);
-- return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/);
--
-- # FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489
--
-- return $sequence;
--}
--
--sub unescape_po_string
--{
-- my ($string) = @_;
--
-- $string =~ s/(\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\.)/unescape_one_sequence($1)/eg;
--
-- return $string;
--}
--
--## NOTE: deal with < - &lt; but not > - &gt; because it seems its ok to have
--## > in the entity. For further info please look at #84738.
--sub entity_decode
--{
-- local ($_) = @_;
--
-- s/&apos;/'/g; # '
-- s/&quot;/"/g; # "
-- s/&amp;/&/g;
-- s/&lt;/</g;
--
-- return $_;
--}
--
--# entity_encode: (string)
--#
--# Encode the given string to XML format (encode '<' etc).
--
--sub entity_encode
--{
-- my ($pre_encoded) = @_;
--
-- my @list_of_chars = unpack ('C*', $pre_encoded);
--
-- # with UTF-8 we only encode minimalistic
-- return join ('', map (&entity_encode_int_minimalist, @list_of_chars));
--}
--
--sub entity_encode_int_minimalist
--{
-- return "&quot;" if $_ == 34;
-- return "&amp;" if $_ == 38;
-- return "&apos;" if $_ == 39;
-- return "&lt;" if $_ == 60;
-- return chr $_;
--}
--
--sub entity_encoded_translation
--{
-- my ($lang, $string) = @_;
--
-- my $translation = $translations{$lang, $string};
-- return $string if !$translation;
-- return entity_encode ($translation);
--}
--
--## XML (bonobo-activation specific) merge code
--
--sub ba_merge_translations
--{
-- my $source;
--
-- {
-- local $/; # slurp mode
-- open INPUT, "<$FILE" or die "can't open $FILE: $!";
-- $source = <INPUT>;
-- close INPUT;
-- }
--
-- open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!";
-- # Binmode so that selftest works ok if using a native Win32 Perl...
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s)
-- {
-- print OUTPUT $1;
--
-- my $node = $2 . "\n";
--
-- my @strings = ();
-- $_ = $node;
-- while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) {
-- push @strings, entity_decode($3);
-- }
-- print OUTPUT;
--
-- my %langs;
-- for my $string (@strings)
-- {
-- for my $lang (keys %po_files_by_lang)
-- {
-- $langs{$lang} = 1 if $translations{$lang, $string};
-- }
-- }
--
-- for my $lang (sort keys %langs)
-- {
-- $_ = $node;
-- s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s;
-- s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg;
-- print OUTPUT;
-- }
-- }
--
-- print OUTPUT $source;
--
-- close OUTPUT;
--}
--
--
--## XML (non-bonobo-activation) merge code
--
--
--# Process tag attributes
--# Only parameter is a HASH containing attributes -> values mapping
--sub getAttributeString
--{
-- my $sub = shift;
-- my $do_translate = shift || 0;
-- my $language = shift || "";
-- my $result = "";
-- my $translate = shift;
-- foreach my $e (reverse(sort(keys %{ $sub }))) {
-- my $key = $e;
-- my $string = $sub->{$e};
-- my $quote = '"';
--
-- $string =~ s/^[\s]+//;
-- $string =~ s/[\s]+$//;
--
-- if ($string =~ /^'.*'$/)
-- {
-- $quote = "'";
-- }
-- $string =~ s/^['"]//g;
-- $string =~ s/['"]$//g;
--
-- if ($do_translate && $key =~ /^_/) {
-- $key =~ s|^_||g;
-- if ($language) {
-- # Handle translation
-- my $decode_string = entity_decode($string);
-- my $translation = $translations{$language, $decode_string};
-- if ($translation) {
-- $translation = entity_encode($translation);
-- $string = $translation;
-- }
-- $$translate = 2;
-- } else {
-- $$translate = 2 if ($translate && (!$$translate)); # watch not to "overwrite" $translate
-- }
-- }
--
-- $result .= " $key=$quote$string$quote";
-- }
-- return $result;
--}
--
--# Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree
--sub getXMLstring
--{
-- my $ref = shift;
-- my $spacepreserve = shift || 0;
-- my @list = @{ $ref };
-- my $result = "";
--
-- my $count = scalar(@list);
-- my $attrs = $list[0];
-- my $index = 1;
--
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
--
-- while ($index < $count) {
-- my $type = $list[$index];
-- my $content = $list[$index+1];
-- if (! $type ) {
-- # We've got CDATA
-- if ($content) {
-- # lets strip the whitespace here, and *ONLY* here
-- $content =~ s/\s+/ /gs if (!$spacepreserve);
-- $result .= $content;
-- }
-- } elsif ( "$type" ne "1" ) {
-- # We've got another element
-- $result .= "<$type";
-- $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
-- if ($content) {
-- my $subresult = getXMLstring($content, $spacepreserve);
-- if ($subresult) {
-- $result .= ">".$subresult . "</$type>";
-- } else {
-- $result .= "/>";
-- }
-- } else {
-- $result .= "/>";
-- }
-- }
-- $index += 2;
-- }
-- return $result;
--}
--
--# Translate list of nodes if necessary
--sub translate_subnodes
--{
-- my $fh = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $singlelang = shift || 0;
-- my $spacepreserve = shift || 0;
--
-- my @nodes = @{ $content };
--
-- my $count = scalar(@nodes);
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $nodes[$index];
-- my $rest = $nodes[$index+1];
-- if ($singlelang) {
-- my $oldMO = $MULTIPLE_OUTPUT;
-- $MULTIPLE_OUTPUT = 1;
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $MULTIPLE_OUTPUT = $oldMO;
-- } else {
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- }
-- $index += 2;
-- }
--}
--
--sub isWellFormedXmlFragment
--{
-- my $ret = eval 'require XML::Parser';
-- if(!$ret) {
-- die "You must have XML::Parser installed to run $0\n\n";
-- }
--
-- my $fragment = shift;
-- return 0 if (!$fragment);
--
-- $fragment = "<root>$fragment</root>";
-- my $xp = new XML::Parser(Style => 'Tree');
-- my $tree = 0;
-- eval { $tree = $xp->parse($fragment); };
-- return $tree;
--}
--
--sub traverse
--{
-- my $fh = shift;
-- my $nodename = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $spacepreserve = shift || 0;
--
-- if (!$nodename) {
-- if ($content =~ /^[\s]*$/) {
-- $leading_space .= $content;
-- }
-- print $fh $content;
-- } else {
-- # element
-- my @all = @{ $content };
-- my $attrs = shift @all;
-- my $translate = 0;
-- my $outattr = getAttributeString($attrs, 1, $language, \$translate);
--
-- if ($nodename =~ /^_/) {
-- $translate = 1;
-- $nodename =~ s/^_//;
-- }
-- my $lookup = '';
--
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- print $fh "<$nodename", $outattr;
-- if ($translate) {
-- $lookup = getXMLstring($content, $spacepreserve);
-- if (!$spacepreserve) {
-- $lookup =~ s/^\s+//s;
-- $lookup =~ s/\s+$//s;
-- }
--
-- if ($lookup || $translate == 2) {
-- my $translation = $translations{$language, $lookup} if isWellFormedXmlFragment($translations{$language, $lookup});
-- if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) {
-- $translation = $lookup if (!$translation);
-- print $fh " xml:lang=\"", $language, "\"" if $language;
-- print $fh ">";
-- if ($translate == 2) {
-- translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
-- } else {
-- print $fh $translation;
-- }
-- print $fh "</$nodename>";
--
-- return; # this means there will be no same translation with xml:lang="$language"...
-- # if we want them both, just remove this "return"
-- } else {
-- print $fh ">";
-- if ($translate == 2) {
-- translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
-- } else {
-- print $fh $lookup;
-- }
-- print $fh "</$nodename>";
-- }
-- } else {
-- print $fh "/>";
-- }
--
-- for my $lang (sort keys %po_files_by_lang) {
-- if ($MULTIPLE_OUTPUT && $lang ne "$language") {
-- next;
-- }
-- if ($lang) {
-- # Handle translation
-- #
-- my $translate = 0;
-- my $localattrs = getAttributeString($attrs, 1, $lang, \$translate);
-- my $translation = $translations{$lang, $lookup} if isWellFormedXmlFragment($translations{$lang, $lookup});
-- if ($translate && !$translation) {
-- $translation = $lookup;
-- }
--
-- if ($translation || $translate) {
-- print $fh "\n";
-- $leading_space =~ s/.*\n//g;
-- print $fh $leading_space;
-- print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">";
-- if ($translate == 2) {
-- translate_subnodes($fh, \@all, $lang, 1, $spacepreserve);
-- } else {
-- print $fh $translation;
-- }
-- print $fh "</$nodename>";
-- }
-- }
-- }
--
-- } else {
-- my $count = scalar(@all);
-- if ($count > 0) {
-- print $fh ">";
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $all[$index];
-- my $rest = $all[$index+1];
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $index += 2;
-- }
-- print $fh "</$nodename>";
-- } else {
-- print $fh "/>";
-- }
-- }
-- }
--}
--
--sub intltool_tree_comment
--{
-- my $expat = shift;
-- my $data = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- push @$clist, 1 => $data;
--}
--
--sub intltool_tree_cdatastart
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- push @$clist, 0 => $expat->original_string();
--}
--
--sub intltool_tree_cdataend
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- $clist->[$pos] .= $expat->original_string();
--}
--
--sub intltool_tree_char
--{
-- my $expat = shift;
-- my $text = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- # Use original_string so that we retain escaped entities
-- # in CDATA sections.
-- #
-- if ($pos > 0 and $clist->[$pos - 1] eq '0') {
-- $clist->[$pos] .= $expat->original_string();
-- } else {
-- push @$clist, 0 => $expat->original_string();
-- }
--}
--
--sub intltool_tree_start
--{
-- my $expat = shift;
-- my $tag = shift;
-- my @origlist = ();
--
-- # Use original_string so that we retain escaped entities
-- # in attribute values. We must convert the string to an
-- # @origlist array to conform to the structure of the Tree
-- # Style.
-- #
-- my @original_array = split /\x/, $expat->original_string();
-- my $source = $expat->original_string();
--
-- # Remove leading tag.
-- #
-- $source =~ s|^\s*<\s*(\S+)||s;
--
-- # Grab attribute key/value pairs and push onto @origlist array.
-- #
-- while ($source)
-- {
-- if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
-- push @origlist, $1;
-- push @origlist, '"' . $2 . '"';
-- }
-- elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
-- push @origlist, $1;
-- push @origlist, "'" . $2 . "'";
-- }
-- else
-- {
-- last;
-- }
-- }
--
-- my $ol = [ { @origlist } ];
--
-- push @{ $expat->{Lists} }, $expat->{Curlist};
-- push @{ $expat->{Curlist} }, $tag => $ol;
-- $expat->{Curlist} = $ol;
--}
--
--sub readXml
--{
-- my $filename = shift || return;
-- if(!-f $filename) {
-- die "ERROR Cannot find filename: $filename\n";
-- }
--
-- my $ret = eval 'require XML::Parser';
-- if(!$ret) {
-- die "You must have XML::Parser installed to run $0\n\n";
-- }
-- my $xp = new XML::Parser(Style => 'Tree');
-- $xp->setHandlers(Char => \&intltool_tree_char);
-- $xp->setHandlers(Start => \&intltool_tree_start);
-- $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
-- $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
-- my $tree = $xp->parsefile($filename);
--
--# <foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
--# would be:
--# [foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, [{},
--# 0, "Howdy", ref, [{}]], 0, "do" ] ]
--
-- return $tree;
--}
--
--sub print_header
--{
-- my $infile = shift;
-- my $fh = shift;
-- my $source;
--
-- if(!-f $infile) {
-- die "ERROR Cannot find filename: $infile\n";
-- }
--
-- print $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
-- {
-- local $/;
-- open DOCINPUT, "<${FILE}" or die;
-- $source = <DOCINPUT>;
-- close DOCINPUT;
-- }
-- if ($source =~ /(<!DOCTYPE.*\[.*\]\s*>)/s)
-- {
-- print $fh "$1\n";
-- }
-- elsif ($source =~ /(<!DOCTYPE[^>]*>)/s)
-- {
-- print $fh "$1\n";
-- }
--}
--
--sub parseTree
--{
-- my $fh = shift;
-- my $ref = shift;
-- my $language = shift || "";
--
-- my $name = shift @{ $ref };
-- my $cont = shift @{ $ref };
--
-- while (!$name || "$name" eq "1") {
-- $name = shift @{ $ref };
-- $cont = shift @{ $ref };
-- }
--
-- my $spacepreserve = 0;
-- my $attrs = @{$cont}[0];
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- traverse($fh, $name, $cont, $language, $spacepreserve);
--}
--
--sub xml_merge_output
--{
-- my $source;
--
-- if ($MULTIPLE_OUTPUT) {
-- for my $lang (sort keys %po_files_by_lang) {
-- if ( ! -e $lang ) {
-- mkdir $lang or die "Cannot create subdirectory $lang: $!\n";
-- }
-- open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n";
-- binmode (OUTPUT) if $^O eq 'MSWin32';
-- my $tree = readXml($FILE);
-- print_header($FILE, \*OUTPUT);
-- parseTree(\*OUTPUT, $tree, $lang);
-- close OUTPUT;
-- print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG;
-- }
-- }
-- open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n";
-- binmode (OUTPUT) if $^O eq 'MSWin32';
-- my $tree = readXml($FILE);
-- print_header($FILE, \*OUTPUT);
-- parseTree(\*OUTPUT, $tree);
-- close OUTPUT;
-- print "CREATED $OUTFILE\n" unless $QUIET_ARG;
--}
--
--sub keys_merge_translations
--{
-- open INPUT, "<${FILE}" or die;
-- open OUTPUT, ">${OUTFILE}" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while (<INPUT>)
-- {
-- if (s/^(\s*)_(\w+=(.*))/$1$2/)
-- {
-- my $string = $3;
--
-- print OUTPUT;
--
-- my $non_translated_line = $_;
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $translation = $translations{$lang, $string};
-- next if !$translation;
--
-- $_ = $non_translated_line;
-- s/(\w+)=.*/[$lang]$1=$translation/;
-- print OUTPUT;
-- }
-- }
-- else
-- {
-- print OUTPUT;
-- }
-- }
--
-- close OUTPUT;
-- close INPUT;
--}
--
--sub desktop_merge_translations
--{
-- open INPUT, "<${FILE}" or die;
-- open OUTPUT, ">${OUTFILE}" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while (<INPUT>)
-- {
-- if (s/^(\s*)_(\w+=(.*))/$1$2/)
-- {
-- my $string = $3;
--
-- print OUTPUT;
--
-- my $non_translated_line = $_;
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $translation = $translations{$lang, $string};
-- next if !$translation;
--
-- $_ = $non_translated_line;
-- s/(\w+)=.*/${1}[$lang]=$translation/;
-- print OUTPUT;
-- }
-- }
-- else
-- {
-- print OUTPUT;
-- }
-- }
--
-- close OUTPUT;
-- close INPUT;
--}
--
--sub schemas_merge_translations
--{
-- my $source;
--
-- {
-- local $/; # slurp mode
-- open INPUT, "<$FILE" or die "can't open $FILE: $!";
-- $source = <INPUT>;
-- close INPUT;
-- }
--
-- open OUTPUT, ">$OUTFILE" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- # FIXME: support attribute translations
--
-- # Empty nodes never need translation, so unmark all of them.
-- # For example, <_foo/> is just replaced by <foo/>.
-- $source =~ s|<\s*_($w+)\s*/>|<$1/>|g;
--
-- while ($source =~ s/
-- (.*?)
-- (\s+)(<locale\ name="C">(\s*)
-- (<default>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/default>)?(\s*)
-- (<short>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/short>)?(\s*)
-- (<long>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/long>)?(\s*)
-- <\/locale>)
-- //sx)
-- {
-- print OUTPUT $1;
--
-- my $locale_start_spaces = $2 ? $2 : '';
-- my $default_spaces = $4 ? $4 : '';
-- my $short_spaces = $7 ? $7 : '';
-- my $long_spaces = $10 ? $10 : '';
-- my $locale_end_spaces = $13 ? $13 : '';
-- my $c_default_block = $3 ? $3 : '';
-- my $default_string = $6 ? $6 : '';
-- my $short_string = $9 ? $9 : '';
-- my $long_string = $12 ? $12 : '';
--
-- print OUTPUT "$locale_start_spaces$c_default_block";
--
-- $default_string =~ s/\s+/ /g;
-- $default_string = entity_decode($default_string);
-- $short_string =~ s/\s+/ /g;
-- $short_string = entity_decode($short_string);
-- $long_string =~ s/\s+/ /g;
-- $long_string = entity_decode($long_string);
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $default_translation = $translations{$lang, $default_string};
-- my $short_translation = $translations{$lang, $short_string};
-- my $long_translation = $translations{$lang, $long_string};
--
-- next if (!$default_translation && !$short_translation &&
-- !$long_translation);
--
-- print OUTPUT "\n$locale_start_spaces<locale name=\"$lang\">";
--
-- print OUTPUT "$default_spaces";
--
-- if ($default_translation)
-- {
-- $default_translation = entity_encode($default_translation);
-- print OUTPUT "<default>$default_translation</default>";
-- }
--
-- print OUTPUT "$short_spaces";
--
-- if ($short_translation)
-- {
-- $short_translation = entity_encode($short_translation);
-- print OUTPUT "<short>$short_translation</short>";
-- }
--
-- print OUTPUT "$long_spaces";
--
-- if ($long_translation)
-- {
-- $long_translation = entity_encode($long_translation);
-- print OUTPUT "<long>$long_translation</long>";
-- }
--
-- print OUTPUT "$locale_end_spaces</locale>";
-- }
-- }
--
-- print OUTPUT $source;
--
-- close OUTPUT;
--}
--
--sub rfc822deb_merge_translations
--{
-- my %encodings = ();
-- for my $lang (keys %po_files_by_lang) {
-- $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang}));
-- }
--
-- my $source;
--
-- $Text::Wrap::huge = 'overflow';
-- $Text::Wrap::break = qr/\n|\s(?=\S)/;
--
-- {
-- local $/; # slurp mode
-- open INPUT, "<$FILE" or die "can't open $FILE: $!";
-- $source = <INPUT>;
-- close INPUT;
-- }
--
-- open OUTPUT, ">${OUTFILE}" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg)
-- {
-- my $sep = $1;
-- my $non_translated_line = $3.$4;
-- my $string = $5;
-- my $underscore = length($2);
-- next if $underscore eq 0 && $non_translated_line =~ /^#/;
-- # Remove [] dummy strings
-- my $stripped = $string;
-- $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2;
-- $stripped =~ s/\[\s[^\[\]]*\]$//;
-- $non_translated_line .= $stripped;
--
-- print OUTPUT $sep.$non_translated_line;
--
-- if ($underscore)
-- {
-- my @str_list = rfc822deb_split($underscore, $string);
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $is_translated = 1;
-- my $str_translated = '';
-- my $first = 1;
--
-- for my $str (@str_list)
-- {
-- my $translation = $translations{$lang, $str};
--
-- if (!$translation)
-- {
-- $is_translated = 0;
-- last;
-- }
--
-- # $translation may also contain [] dummy
-- # strings, mostly to indicate an empty string
-- $translation =~ s/\[\s[^\[\]]*\]$//;
--
-- if ($first)
-- {
-- if ($underscore eq 2)
-- {
-- $str_translated .= $translation;
-- }
-- else
-- {
-- $str_translated .=
-- Text::Tabs::expand($translation) .
-- "\n";
-- }
-- }
-- else
-- {
-- if ($underscore eq 2)
-- {
-- $str_translated .= ', ' . $translation;
-- }
-- else
-- {
-- $str_translated .= Text::Tabs::expand(
-- Text::Wrap::wrap(' ', ' ', $translation)) .
-- "\n .\n";
-- }
-- }
-- $first = 0;
--
-- # To fix some problems with Text::Wrap::wrap
-- $str_translated =~ s/(\n )+\n/\n .\n/g;
-- }
-- next unless $is_translated;
--
-- $str_translated =~ s/\n \.\n$//;
-- $str_translated =~ s/\s+$//;
--
-- $_ = $non_translated_line;
-- s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s;
-- print OUTPUT;
-- }
-- }
-- }
-- print OUTPUT "\n";
--
-- close OUTPUT;
-- close INPUT;
--}
--
--sub rfc822deb_split
--{
-- # Debian defines a special way to deal with rfc822-style files:
-- # when a value contain newlines, it consists of
-- # 1. a short form (first line)
-- # 2. a long description, all lines begin with a space,
-- # and paragraphs are separated by a single dot on a line
-- # This routine returns an array of all paragraphs, and reformat
-- # them.
-- # When first argument is 2, the string is a comma separated list of
-- # values.
-- my $type = shift;
-- my $text = shift;
-- $text =~ s/^[ \t]//mg;
-- return (split(/, */, $text, 0)) if $type ne 1;
-- return ($text) if $text !~ /\n/;
--
-- $text =~ s/([^\n]*)\n//;
-- my @list = ($1);
-- my $str = '';
--
-- for my $line (split (/\n/, $text))
-- {
-- chomp $line;
-- if ($line =~ /^\.\s*$/)
-- {
-- # New paragraph
-- $str =~ s/\s*$//;
-- push(@list, $str);
-- $str = '';
-- }
-- elsif ($line =~ /^\s/)
-- {
-- # Line which must not be reformatted
-- $str .= "\n" if length ($str) && $str !~ /\n$/;
-- $line =~ s/\s+$//;
-- $str .= $line."\n";
-- }
-- else
-- {
-- # Continuation line, remove newline
-- $str .= " " if length ($str) && $str !~ /\n$/;
-- $str .= $line;
-- }
-- }
--
-- $str =~ s/\s*$//;
-- push(@list, $str) if length ($str);
--
-- return @list;
--}
--
-diff --git a/intltool-merge.in b/intltool-merge.in
-new file mode 120000
-index d0535ab..2238bbd
---- /dev/null
-+++ b/intltool-merge.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/intltool-merge.in
-\ No newline at end of file
-diff --git a/intltool-update.in b/intltool-update.in
-deleted file mode 100755
-index 661d8fe..0b1800f
---- a/intltool-update.in
-+++ /dev/null
-@@ -1,1089 +0,0 @@
--#!@INTLTOOL_PERL@ -w
--# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
--
--#
--# The Intltool Message Updater
--#
--# Copyright (C) 2000-2003 Free Software Foundation.
--#
--# Intltool is free software; you can redistribute it and/or
--# modify it under the terms of the GNU General Public License
--# version 2 published by the Free Software Foundation.
--#
--# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA.
--#
--# As a special exception to the GNU General Public License, if you
--# distribute this file as part of a program that contains a
--# configuration script generated by Autoconf, you may include it under
--# the same distribution terms that you use for the rest of that program.
--#
--# Authors: Kenneth Christiansen <kenneth@gnu.org>
--# Maciej Stachowiak
--# Darin Adler <darin@bentspoon.com>
--
--## Release information
--my $PROGRAM = "intltool-update";
--my $VERSION = "0.35.0";
--my $PACKAGE = "intltool";
--
--## Loaded modules
--use strict;
--use Getopt::Long;
--use Cwd;
--use File::Copy;
--use File::Find;
--
--## Scalars used by the option stuff
--my $HELP_ARG = 0;
--my $VERSION_ARG = 0;
--my $DIST_ARG = 0;
--my $POT_ARG = 0;
--my $HEADERS_ARG = 0;
--my $MAINTAIN_ARG = 0;
--my $REPORT_ARG = 0;
--my $VERBOSE = 0;
--my $GETTEXT_PACKAGE = "";
--my $OUTPUT_FILE = "";
--
--my @languages;
--my %varhash = ();
--my %po_files_by_lang = ();
--
--# Regular expressions to categorize file types.
--# FIXME: Please check if the following is correct
--
--my $xml_support =
--"xml(?:\\.in)*|". # http://www.w3.org/XML/ (Note: .in is not required)
--"ui|". # Bonobo specific - User Interface desc. files
--"lang|". # ?
--"glade2?(?:\\.in)*|". # Glade specific - User Interface desc. files (Note: .in is not required)
--"scm(?:\\.in)*|". # ? (Note: .in is not required)
--"oaf(?:\\.in)+|". # DEPRECATED: Replaces by Bonobo .server files
--"etspec|". # ?
--"server(?:\\.in)+|". # Bonobo specific
--"sheet(?:\\.in)+|". # ?
--"schemas(?:\\.in)+|". # GConf specific
--"pong(?:\\.in)+|". # DEPRECATED: PONG is not used [by GNOME] any longer.
--"kbd(?:\\.in)+"; # GOK specific.
--
--my $ini_support =
--"icon(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec
--"desktop(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec
--"caves(?:\\.in)+|". # GNOME Games specific
--"directory(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec
--"soundlist(?:\\.in)+|". # GNOME specific
--"keys(?:\\.in)+|". # GNOME Mime database specific
--"theme(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec
--"service(?:\\.in)+"; # DBus specific
--
--my $buildin_gettext_support =
--"c|y|cs|cc|cpp|c\\+\\+|h|hh|gob|py";
--
--## Always flush buffer when printing
--$| = 1;
--
--## Sometimes the source tree will be rooted somewhere else.
--my $SRCDIR = ".";
--my $POTFILES_in;
--
--$SRCDIR = $ENV{"srcdir"} if $ENV{"srcdir"};
--$POTFILES_in = "<$SRCDIR/POTFILES.in";
--
--my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null');
--
--## Handle options
--GetOptions
--(
-- "help" => \$HELP_ARG,
-- "version" => \$VERSION_ARG,
-- "dist|d" => \$DIST_ARG,
-- "pot|p" => \$POT_ARG,
-- "headers|s" => \$HEADERS_ARG,
-- "maintain|m" => \$MAINTAIN_ARG,
-- "report|r" => \$REPORT_ARG,
-- "verbose|x" => \$VERBOSE,
-- "gettext-package|g=s" => \$GETTEXT_PACKAGE,
-- "output-file|o=s" => \$OUTPUT_FILE,
-- ) or &Console_WriteError_InvalidOption;
--
--&Console_Write_IntltoolHelp if $HELP_ARG;
--&Console_Write_IntltoolVersion if $VERSION_ARG;
--
--my $arg_count = ($DIST_ARG > 0)
-- + ($POT_ARG > 0)
-- + ($HEADERS_ARG > 0)
-- + ($MAINTAIN_ARG > 0)
-- + ($REPORT_ARG > 0);
--
--&Console_Write_IntltoolHelp if $arg_count > 1;
--
--# --version and --help don't require a module name
--my $MODULE = $GETTEXT_PACKAGE || &FindPackageName || "unknown";
--
--if ($POT_ARG)
--{
-- &GenerateHeaders;
-- &GeneratePOTemplate;
--}
--elsif ($HEADERS_ARG)
--{
-- &GenerateHeaders;
--}
--elsif ($MAINTAIN_ARG)
--{
-- &FindLeftoutFiles;
--}
--elsif ($REPORT_ARG)
--{
-- &GenerateHeaders;
-- &GeneratePOTemplate;
-- &Console_Write_CoverageReport;
--}
--elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/)
--{
-- my $lang = $ARGV[0];
--
-- ## Report error if the language file supplied
-- ## to the command line is non-existent
-- &Console_WriteError_NotExisting("$SRCDIR/$lang.po")
-- if ! -s "$SRCDIR/$lang.po";
--
-- if (!$DIST_ARG)
-- {
-- print "Working, please wait..." if $VERBOSE;
-- &GenerateHeaders;
-- &GeneratePOTemplate;
-- }
-- &POFile_Update ($lang, $OUTPUT_FILE);
-- &Console_Write_TranslationStatus ($lang, $OUTPUT_FILE);
--}
--else
--{
-- &Console_Write_IntltoolHelp;
--}
--
--exit;
--
--#########
--
--sub Console_Write_IntltoolVersion
--{
-- print <<_EOF_;
--${PROGRAM} (${PACKAGE}) $VERSION
--Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.
--
--Copyright (C) 2000-2003 Free Software Foundation, Inc.
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--_EOF_
-- exit;
--}
--
--sub Console_Write_IntltoolHelp
--{
-- print <<_EOF_;
--Usage: ${PROGRAM} [OPTION]... LANGCODE
--Updates PO template files and merge them with the translations.
--
--Mode of operation (only one is allowed):
-- -p, --pot generate the PO template only
-- -s, --headers generate the header files in POTFILES.in
-- -m, --maintain search for left out files from POTFILES.in
-- -r, --report display a status report for the module
-- -d, --dist merge LANGCODE.po with existing PO template
--
--Extra options:
-- -g, --gettext-package=NAME override PO template name, useful with --pot
-- -o, --output-file=FILE write merged translation to FILE
-- -x, --verbose display lots of feedback
-- --help display this help and exit
-- --version output version information and exit
--
--Examples of use:
--${PROGRAM} --pot just create a new PO template
--${PROGRAM} xy create new PO template and merge xy.po with it
--
--Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
--or send email to <xml-i18n-tools\@gnome.org>.
--_EOF_
-- exit;
--}
--
--sub echo_n
--{
-- my $str = shift;
-- my $ret = `echo "$str"`;
--
-- $ret =~ s/\n$//; # do we need the "s" flag?
--
-- return $ret;
--}
--
--sub POFile_DetermineType ($)
--{
-- my $type = $_;
-- my $gettext_type;
--
-- my $xml_regex = "(?:" . $xml_support . ")";
-- my $ini_regex = "(?:" . $ini_support . ")";
-- my $buildin_regex = "(?:" . $buildin_gettext_support . ")";
--
-- if ($type =~ /\[type: gettext\/([^\]].*)]/)
-- {
-- $gettext_type=$1;
-- }
-- elsif ($type =~ /schemas(\.in)+$/)
-- {
-- $gettext_type="schemas";
-- }
-- elsif ($type =~ /glade2?(\.in)*$/)
-- {
-- $gettext_type="glade";
-- }
-- elsif ($type =~ /scm(\.in)*$/)
-- {
-- $gettext_type="scheme";
-- }
-- elsif ($type =~ /keys(\.in)+$/)
-- {
-- $gettext_type="keys";
-- }
--
-- # bucket types
--
-- elsif ($type =~ /$xml_regex$/)
-- {
-- $gettext_type="xml";
-- }
-- elsif ($type =~ /$ini_regex$/)
-- {
-- $gettext_type="ini";
-- }
-- elsif ($type =~ /$buildin_regex$/)
-- {
-- $gettext_type="buildin";
-- }
-- else
-- {
-- $gettext_type="unknown";
-- }
--
-- return "gettext\/$gettext_type";
--}
--
--sub TextFile_DetermineEncoding ($)
--{
-- my $gettext_code="ASCII"; # All files are ASCII by default
-- my $filetype=`file $_ | cut -d ' ' -f 2`;
--
-- if ($? eq "0")
-- {
-- if ($filetype =~ /^(ISO|UTF)/)
-- {
-- chomp ($gettext_code = $filetype);
-- }
-- elsif ($filetype =~ /^XML/)
-- {
-- $gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8
-- }
-- }
--
-- return $gettext_code;
--}
--
--sub isNotValidMissing
--{
-- my ($file) = @_;
--
-- return if $file =~ /^\{arch\}\/.*$/;
-- return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/;
--}
--
--sub FindLeftoutFiles
--{
-- my (@buf_i18n_plain,
-- @buf_i18n_xml,
-- @buf_i18n_xml_unmarked,
-- @buf_i18n_ini,
-- @buf_potfiles,
-- @buf_potfiles_ignore,
-- @buf_allfiles,
-- @buf_allfiles_sorted,
-- @buf_potfiles_sorted
-- );
--
-- ## Search and find all translatable files
-- find sub {
-- push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/;
-- push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/;
-- push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/;
-- push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/;
-- }, "..";
--
--
-- open POTFILES, $POTFILES_in or die "$PROGRAM: there's no POTFILES.in!\n";
-- @buf_potfiles = grep !/^(#|\s*$)/, <POTFILES>;
-- close POTFILES;
--
-- foreach (@buf_potfiles) {
-- s/^\[.*]\s*//;
-- }
--
-- print "Searching for missing translatable files...\n" if $VERBOSE;
--
-- ## Check if we should ignore some found files, when
-- ## comparing with POTFILES.in
-- foreach my $ignore ("POTFILES.skip", "POTFILES.ignore")
-- {
-- (-s $ignore) or next;
--
-- if ("$ignore" eq "POTFILES.ignore")
-- {
-- print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n".
-- "content of this file to POTFILES.skip.\n";
-- }
--
-- print "Found $ignore: Ignoring files...\n" if $VERBOSE;
-- open FILE, "<$ignore" or die "ERROR: Failed to open $ignore!\n";
--
-- while (<FILE>)
-- {
-- push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/;
-- }
-- close FILE;
--
-- @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles);
-- }
--
-- foreach my $file (@buf_i18n_plain)
-- {
-- my $in_comment = 0;
-- my $in_macro = 0;
--
-- open FILE, "<$file";
-- while (<FILE>)
-- {
-- # Handle continued multi-line comment.
-- if ($in_comment)
-- {
-- next unless s-.*\*/--;
-- $in_comment = 0;
-- }
--
-- # Handle continued macro.
-- if ($in_macro)
-- {
-- $in_macro = 0 unless /\\$/;
-- next;
-- }
--
-- # Handle start of macro (or any preprocessor directive).
-- if (/^\s*\#/)
-- {
-- $in_macro = 1 if /^([^\\]|\\.)*\\$/;
-- next;
-- }
--
-- # Handle comments and quoted text.
-- while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy
-- {
-- my $match = $1;
-- if ($match eq "/*")
-- {
-- if (!s-/\*.*?\*/--)
-- {
-- s-/\*.*--;
-- $in_comment = 1;
-- }
-- }
-- elsif ($match eq "//")
-- {
-- s-//.*--;
-- }
-- else # ' or "
-- {
-- if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-)
-- {
-- warn "mismatched quotes at line $. in $file\n";
-- s-$match.*--;
-- }
-- }
-- }
--
-- if (/\.GetString ?\(QUOTEDTEXT/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- ## Remove the first 3 chars and add newline
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
--
-- if (/_\(QUOTEDTEXT/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- ## Remove the first 3 chars and add newline
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
-- }
-- close FILE;
-- }
--
-- foreach my $file (@buf_i18n_xml)
-- {
-- open FILE, "<$file";
--
-- while (<FILE>)
-- {
-- # FIXME: share the pattern matching code with intltool-extract
-- if (/\s_[-A-Za-z0-9._:]+\s*=\s*\"([^"]+)\"/ || /<_[^>]+>/ || /translatable=\"yes\"/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
-- }
-- close FILE;
-- }
--
-- foreach my $file (@buf_i18n_ini)
-- {
-- open FILE, "<$file";
-- while (<FILE>)
-- {
-- if (/_(.*)=/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
-- }
-- close FILE;
-- }
--
-- foreach my $file (@buf_i18n_xml_unmarked)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- }
--
--
-- @buf_allfiles_sorted = sort (@buf_allfiles);
-- @buf_potfiles_sorted = sort (@buf_potfiles);
--
-- my %in2;
-- foreach (@buf_potfiles_sorted)
-- {
-- $in2{$_} = 1;
-- }
--
-- my @result;
--
-- foreach (@buf_allfiles_sorted)
-- {
-- if (!exists($in2{$_}))
-- {
-- push @result, $_
-- }
-- }
--
-- my @buf_potfiles_notexist;
--
-- foreach (@buf_potfiles_sorted)
-- {
-- chomp (my $dummy = $_);
-- if ("$dummy" ne "" and ! -f "../$dummy")
-- {
-- push @buf_potfiles_notexist, $_;
-- }
-- }
--
-- ## Save file with information about the files missing
-- ## if any, and give information about this procedure.
-- if (@result + @buf_potfiles_notexist > 0)
-- {
-- if (@result)
-- {
-- print "\n" if $VERBOSE;
-- unlink "missing";
-- open OUT, ">missing";
-- print OUT @result;
-- close OUT;
-- warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n".
-- "\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n";
-- print STDERR @result, "\n";
-- warn "If some of these files are left out on purpose then please add them to\n".
-- "POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n".
-- "of left out files has been written in the current directory.\n";
-- }
-- if (@buf_potfiles_notexist)
-- {
-- unlink "notexist";
-- open OUT, ">notexist";
-- print OUT @buf_potfiles_notexist;
-- close OUT;
-- warn "\n" if ($VERBOSE or @result);
-- warn "\e[1mThe following files do not exist anymore:\e[0m\n\n";
-- warn @buf_potfiles_notexist, "\n";
-- warn "Please remove them from POTFILES.in or POTFILES.skip. A file \e[1m'notexist'\e[0m\n".
-- "containing this list of absent files has been written in the current directory.\n";
-- }
-- }
--
-- ## If there is nothing to complain about, notify the user
-- else {
-- print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE;
-- }
--}
--
--sub Console_WriteError_InvalidOption
--{
-- ## Handle invalid arguments
-- print STDERR "Try `${PROGRAM} --help' for more information.\n";
-- exit 1;
--}
--
--sub GenerateHeaders
--{
-- my $EXTRACT = "@INTLTOOL_EXTRACT@";
-- chomp $EXTRACT;
--
-- $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"};
--
-- ## Generate the .h header files, so we can allow glade and
-- ## xml translation support
-- if (! -x "$EXTRACT")
-- {
-- print STDERR "\n *** The intltool-extract script wasn't found!"
-- ."\n *** Without it, intltool-update can not generate files.\n";
-- exit;
-- }
-- else
-- {
-- open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n";
--
-- while (<FILE>)
-- {
-- chomp;
-- next if /^\[\s*encoding/;
--
-- ## Find xml files in POTFILES.in and generate the
-- ## files with help from the extract script
--
-- my $gettext_type= &POFile_DetermineType ($1);
--
-- if (/\.($xml_support|$ini_support)$/ || /^\[/)
-- {
-- s/^\[[^\[].*]\s*//;
--
-- my $filename = "../$_";
--
-- if ($VERBOSE)
-- {
-- system ($EXTRACT, "--update", "--srcdir=$SRCDIR",
-- "--type=$gettext_type", $filename);
-- }
-- else
-- {
-- system ($EXTRACT, "--update", "--type=$gettext_type",
-- "--srcdir=$SRCDIR", "--quiet", $filename);
-- }
-- }
-- }
-- close FILE;
-- }
--}
--
--#
--# Generate .pot file from POTFILES.in
--#
--sub GeneratePOTemplate
--{
-- my $XGETTEXT = $ENV{"XGETTEXT"} || "@INTLTOOL_XGETTEXT@";
-- my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || '';
-- chomp $XGETTEXT;
--
-- if (! -x $XGETTEXT)
-- {
-- print STDERR " *** xgettext is not found on this system!\n".
-- " *** Without it, intltool-update can not extract strings.\n";
-- exit;
-- }
--
-- print "Building $MODULE.pot...\n" if $VERBOSE;
--
-- open INFILE, $POTFILES_in;
-- unlink "POTFILES.in.temp";
-- open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing");
--
-- my $gettext_support_nonascii = 0;
--
-- # checks for GNU gettext >= 0.12
-- my $dummy = `$XGETTEXT --version --from-code=UTF-8 >$devnull 2>$devnull`;
-- if ($? == 0)
-- {
-- $gettext_support_nonascii = 1;
-- }
-- else
-- {
-- # urge everybody to upgrade gettext
-- print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n".
-- " strings. That means you should install a version of gettext\n".
-- " that supports non-ASCII strings (such as GNU gettext >= 0.12),\n".
-- " or have to let non-ASCII strings untranslated. (If there is any)\n";
-- }
--
-- my $encoding = "ASCII";
-- my $forced_gettext_code;
-- my @temp_headers;
-- my $encoding_problem_is_reported = 0;
--
-- while (<INFILE>)
-- {
-- next if (/^#/ or /^\s*$/);
--
-- chomp;
--
-- my $gettext_code;
--
-- if (/^\[\s*encoding:\s*(.*)\s*\]/)
-- {
-- $forced_gettext_code=$1;
-- }
-- elsif (/\.($xml_support|$ini_support)$/ || /^\[/)
-- {
-- s/^\[.*]\s*//;
-- print OUTFILE "../$_.h\n";
-- push @temp_headers, "../$_.h";
-- $gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code);
-- }
-- else
-- {
-- if ($SRCDIR eq ".") {
-- print OUTFILE "../$_\n";
-- } else {
-- print OUTFILE "$SRCDIR/../$_\n";
-- }
-- $gettext_code = &TextFile_DetermineEncoding ("../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code);
-- }
--
-- next if (! $gettext_support_nonascii);
--
-- if (defined $forced_gettext_code)
-- {
-- $encoding=$forced_gettext_code;
-- }
-- elsif (defined $gettext_code and "$encoding" ne "$gettext_code")
-- {
-- if ($encoding eq "ASCII")
-- {
-- $encoding=$gettext_code;
-- }
-- elsif ($gettext_code ne "ASCII")
-- {
-- # Only report once because the message is quite long
-- if (! $encoding_problem_is_reported)
-- {
-- print STDERR "WARNING: You should use the same file encoding for all your project files,\n".
-- " but $PROGRAM thinks that most of the source files are in\n".
-- " $encoding encoding, while \"$_\" is (likely) in\n".
-- " $gettext_code encoding. If you are sure that all translatable strings\n".
-- " are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n".
-- " line to POTFILES.in:\n\n".
-- " [encoding: UTF-8]\n\n".
-- " and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n".
-- "(such warning message will only be reported once.)\n";
-- $encoding_problem_is_reported = 1;
-- }
-- }
-- }
-- }
--
-- close OUTFILE;
-- close INFILE;
--
-- unlink "$MODULE.pot";
-- my @xgettext_argument=("$XGETTEXT",
-- "--add-comments",
-- "--directory\=\.",
-- "--output\=$MODULE\.pot",
-- "--files-from\=\.\/POTFILES\.in\.temp");
-- my $XGETTEXT_KEYWORDS = &FindPOTKeywords;
-- push @xgettext_argument, $XGETTEXT_KEYWORDS;
-- my $MSGID_BUGS_ADDRESS = &FindMakevarsBugAddress;
-- push @xgettext_argument, "--msgid-bugs-address\=$MSGID_BUGS_ADDRESS" if $MSGID_BUGS_ADDRESS;
-- push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii);
-- push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS;
-- my $xgettext_command = join ' ', @xgettext_argument;
--
-- # intercept xgettext error message
-- print "Running $xgettext_command\n" if $VERBOSE;
-- my $xgettext_error_msg = `$xgettext_command 2>\&1`;
-- my $command_failed = $?;
--
-- unlink "POTFILES.in.temp";
--
-- print "Removing generated header (.h) files..." if $VERBOSE;
-- unlink foreach (@temp_headers);
-- print "done.\n" if $VERBOSE;
--
-- if (! $command_failed)
-- {
-- if (! -e "$MODULE.pot")
-- {
-- print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE;
-- }
-- else
-- {
-- print "Wrote $MODULE.pot\n" if $VERBOSE;
-- }
-- }
-- else
-- {
-- if ($xgettext_error_msg =~ /--from-code/)
-- {
-- # replace non-ASCII error message with a more useful one.
-- print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n".
-- " string marked for translation. Please make sure that all strings marked\n".
-- " for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n".
-- " following line to POTFILES.in and rerun $PROGRAM:\n\n".
-- " [encoding: UTF-8]\n\n";
-- }
-- else
-- {
-- print STDERR "$xgettext_error_msg";
-- if (-e "$MODULE.pot")
-- {
-- # is this possible?
-- print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n".
-- " Please consult error message above if there is any.\n";
-- }
-- else
-- {
-- print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n".
-- " error message above if there is any.\n";
-- }
-- }
-- exit (1);
-- }
--}
--
--sub POFile_Update
--{
-- -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n";
--
-- my $MSGMERGE = $ENV{"MSGMERGE"} || "@INTLTOOL_MSGMERGE@";
-- my ($lang, $outfile) = @_;
--
-- print "Merging $SRCDIR/$lang.po with $MODULE.pot..." if $VERBOSE;
--
-- my $infile = "$SRCDIR/$lang.po";
-- $outfile = "$SRCDIR/$lang.po" if ($outfile eq "");
--
-- # I think msgmerge won't overwrite old file if merge is not successful
-- system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot");
--}
--
--sub Console_WriteError_NotExisting
--{
-- my ($file) = @_;
--
-- ## Report error if supplied language file is non-existing
-- print STDERR "$PROGRAM: $file does not exist!\n";
-- print STDERR "Try '$PROGRAM --help' for more information.\n";
-- exit;
--}
--
--sub GatherPOFiles
--{
-- my @po_files = glob ("./*.po");
--
-- @languages = map (&POFile_GetLanguage, @po_files);
--
-- foreach my $lang (@languages)
-- {
-- $po_files_by_lang{$lang} = shift (@po_files);
-- }
--}
--
--sub POFile_GetLanguage ($)
--{
-- s/^(.*\/)?(.+)\.po$/$2/;
-- return $_;
--}
--
--sub Console_Write_TranslationStatus
--{
-- my ($lang, $output_file) = @_;
-- my $MSGFMT = $ENV{"MSGFMT"} || "@INTLTOOL_MSGFMT@";
--
-- $output_file = "$SRCDIR/$lang.po" if ($output_file eq "");
--
-- system ("$MSGFMT", "-o", "$devnull", "--verbose", $output_file);
--}
--
--sub Console_Write_CoverageReport
--{
-- my $MSGFMT = $ENV{"MSGFMT"} || "@INTLTOOL_MSGFMT@";
--
-- &GatherPOFiles;
--
-- foreach my $lang (@languages)
-- {
-- print "$lang: ";
-- &POFile_Update ($lang, "");
-- }
--
-- print "\n\n * Current translation support in $MODULE \n\n";
--
-- foreach my $lang (@languages)
-- {
-- print "$lang: ";
-- system ("$MSGFMT", "-o", "$devnull", "--verbose", "$SRCDIR/$lang.po");
-- }
--}
--
--sub SubstituteVariable
--{
-- my ($str) = @_;
--
-- # always need to rewind file whenever it has been accessed
-- seek (CONF, 0, 0);
--
-- # cache each variable. varhash is global to we can add
-- # variables elsewhere.
-- while (<CONF>)
-- {
-- if (/^(\w+)=(.*)$/)
-- {
-- ($varhash{$1} = $2) =~ s/^["'](.*)["']$/$1/;
-- }
-- }
--
-- if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/)
-- {
-- my $rest = $3;
-- my $untouched = $1;
-- my $sub = "";
-- # Ignore recursive definitions of variables
-- $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\${?$2}?/;
--
-- return SubstituteVariable ("$untouched$sub$rest");
-- }
--
-- # We're using Perl backticks ` and "echo -n" here in order to
-- # expand any shell escapes (such as backticks themselves) in every variable
-- return echo_n ($str);
--}
--
--sub CONF_Handle_Open
--{
-- my $base_dirname = getcwd();
-- $base_dirname =~ s@.*/@@;
--
-- my ($conf_in, $src_dir);
--
-- if ($base_dirname =~ /^po(-.+)?$/)
-- {
-- if (-f "Makevars")
-- {
-- my $makefile_source;
--
-- local (*IN);
-- open (IN, "<Makevars") || die "can't open Makevars: $!";
--
-- while (<IN>)
-- {
-- if (/^top_builddir[ \t]*=/)
-- {
-- $src_dir = $_;
-- $src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
--
-- chomp $src_dir;
-- if (-f "$src_dir" . "/configure.ac") {
-- $conf_in = "$src_dir" . "/configure.ac" . "\n";
-- } else {
-- $conf_in = "$src_dir" . "/configure.in" . "\n";
-- }
-- last;
-- }
-- }
-- close IN;
--
-- $conf_in || die "Cannot find top_builddir in Makevars.";
-- }
-- elsif (-f "../configure.ac")
-- {
-- $conf_in = "../configure.ac";
-- }
-- elsif (-f "../configure.in")
-- {
-- $conf_in = "../configure.in";
-- }
-- else
-- {
-- my $makefile_source;
--
-- local (*IN);
-- open (IN, "<Makefile") || return;
--
-- while (<IN>)
-- {
-- if (/^top_srcdir[ \t]*=/)
-- {
-- $src_dir = $_;
-- $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
--
-- chomp $src_dir;
-- $conf_in = "$src_dir" . "/configure.in" . "\n";
--
-- last;
-- }
-- }
-- close IN;
--
-- $conf_in || die "Cannot find top_srcdir in Makefile.";
-- }
--
-- open (CONF, "<$conf_in");
-- }
-- else
-- {
-- print STDERR "$PROGRAM: Unable to proceed.\n" .
-- "Make sure to run this script inside the po directory.\n";
-- exit;
-- }
--}
--
--sub FindPackageName
--{
-- my $version;
-- my $domain = &FindMakevarsDomain;
-- my $name = $domain || "untitled";
--
-- &CONF_Handle_Open;
--
-- my $conf_source; {
-- local (*IN);
-- open (IN, "<&CONF") || return $name;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $conf_source = <IN>;
-- close IN;
-- }
--
-- # priority for getting package name:
-- # 1. GETTEXT_PACKAGE
-- # 2. first argument of AC_INIT (with >= 2 arguments)
-- # 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument)
--
-- # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m
-- # the \s makes this not work, why?
-- if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m)
-- {
-- ($name, $version) = ($1, $2);
-- $name =~ s/[\[\]\s]//g;
-- $version =~ s/[\[\]\s]//g;
-- $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
-- $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
-- $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
-- $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
-- }
--
-- if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m)
-- {
-- ($name, $version) = ($1, $2);
-- $name =~ s/[\[\]\s]//g;
-- $version =~ s/[\[\]\s]//g;
-- $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
-- $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
-- $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
-- $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
-- }
--
-- # \s makes this not work, why?
-- $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m;
--
-- # m4 macros AC_PACKAGE_NAME, AC_PACKAGE_VERSION etc. have same value
-- # as corresponding $PACKAGE_NAME, $PACKAGE_VERSION etc. shell variables.
-- $name =~ s/\bAC_PACKAGE_/\$PACKAGE_/g;
--
-- $name = $domain if $domain;
--
-- $name = SubstituteVariable ($name);
-- $name =~ s/^["'](.*)["']$/$1/;
--
-- return $name if $name;
--}
--
--
--sub FindPOTKeywords
--{
--
-- my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_";
-- my $varname = "XGETTEXT_OPTIONS";
-- my $make_source; {
-- local (*IN);
-- open (IN, "<Makevars") || (open(IN, "<Makefile.in.in") && ($varname = "XGETTEXT_KEYWORDS")) || return $keywords;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $make_source = <IN>;
-- close IN;
-- }
--
-- $keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m;
--
-- return $keywords;
--}
--
--sub FindMakevarsDomain
--{
--
-- my $domain = "";
-- my $makevars_source; {
-- local (*IN);
-- open (IN, "<Makevars") || return $domain;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $makevars_source = <IN>;
-- close IN;
-- }
--
-- $domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m;
-- $domain =~ s/^\s+//;
-- $domain =~ s/\s+$//;
--
-- return $domain;
--}
--
--sub FindMakevarsBugAddress
--{
--
-- my $address = "";
-- my $makevars_source; {
-- local (*IN);
-- open (IN, "<Makevars") || return undef;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $makevars_source = <IN>;
-- close IN;
-- }
--
-- $address = $1 if $makevars_source =~ /^MSGID_BUGS_ADDRESS[ ]*=\[?([^\n\]\$]+)/m;
-- $address =~ s/^\s+//;
-- $address =~ s/\s+$//;
--
-- return $address;
--}
-diff --git a/intltool-update.in b/intltool-update.in
-new file mode 120000
-index 661d8fe..0b1800f
---- /dev/null
-+++ b/intltool-update.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/intltool-update.in
-\ No newline at end of file
-diff --git a/pixmaps/intlclock-map-location-current.png b/pixmaps/intlclock-map-location-current.png
-new file mode 100644
-index 0000000..5c505d1
-Binary files /dev/null and b/pixmaps/intlclock-map-location-current.png differ
-diff --git a/pixmaps/intlclock-map-location-current.svg b/pixmaps/intlclock-map-location-current.svg
-new file mode 100644
-index 0000000..93b5188
---- /dev/null
-+++ b/pixmaps/intlclock-map-location-current.svg
-@@ -0,0 +1,76 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<!-- Created with Inkscape (http://www.inkscape.org/) -->
-+<svg
-+ xmlns:dc="http://purl.org/dc/elements/1.1/"
-+ xmlns:cc="http://web.resource.org/cc/"
-+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-+ xmlns:svg="http://www.w3.org/2000/svg"
-+ xmlns="http://www.w3.org/2000/svg"
-+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-+ width="10"
-+ height="10"
-+ id="svg2"
-+ sodipodi:version="0.32"
-+ inkscape:version="0.45.1"
-+ sodipodi:docbase="/home/mclasen/Desktop"
-+ sodipodi:docname="star.svg"
-+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
-+ version="1.0">
-+ <defs
-+ id="defs4" />
-+ <sodipodi:namedview
-+ id="base"
-+ pagecolor="#ffffff"
-+ bordercolor="#666666"
-+ borderopacity="1.0"
-+ gridtolerance="10000"
-+ guidetolerance="10"
-+ objecttolerance="10"
-+ inkscape:pageopacity="0.0"
-+ inkscape:pageshadow="2"
-+ inkscape:zoom="1"
-+ inkscape:cx="88.125"
-+ inkscape:cy="-22.797357"
-+ inkscape:document-units="px"
-+ inkscape:current-layer="layer1"
-+ inkscape:window-width="1003"
-+ inkscape:window-height="824"
-+ inkscape:window-x="93"
-+ inkscape:window-y="30"
-+ width="10px"
-+ height="10px" />
-+ <metadata
-+ id="metadata7">
-+ <rdf:RDF>
-+ <cc:Work
-+ rdf:about="">
-+ <dc:format>image/svg+xml</dc:format>
-+ <dc:type
-+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-+ </cc:Work>
-+ </rdf:RDF>
-+ </metadata>
-+ <g
-+ inkscape:label="Layer 1"
-+ inkscape:groupmode="layer"
-+ id="layer1"
-+ transform="translate(-164.31866,-172.88433)">
-+ <path
-+ sodipodi:type="star"
-+ style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:10.30000114;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-+ id="path2160"
-+ sodipodi:sides="5"
-+ sodipodi:cx="311.42856"
-+ sodipodi:cy="320.93362"
-+ sodipodi:r1="121.8637"
-+ sodipodi:r2="42.747437"
-+ sodipodi:arg1="1.0073988"
-+ sodipodi:arg2="1.6371268"
-+ inkscape:flatsided="false"
-+ inkscape:rounded="0"
-+ inkscape:randomized="0"
-+ d="M 376.51129,423.96274 L 308.59518,363.58706 L 233.55372,414.66873 L 269.98717,331.41956 L 198.21652,275.83599 L 288.64975,284.76085 L 319.33452,199.32664 L 338.79187,288.09169 L 429.52674,290.87401 L 351.11882,336.80896 L 376.51129,423.96274 z "
-+ transform="matrix(3.8213745e-2,-2.1588882e-2,2.2396111e-2,3.6200569e-2,150.72076,172.68179)" />
-+ </g>
-+</svg>
-diff --git a/pixmaps/intlclock-map-location-hilight.png b/pixmaps/intlclock-map-location-hilight.png
-new file mode 100644
-index 0000000..d7de5b7
-Binary files /dev/null and b/pixmaps/intlclock-map-location-hilight.png differ
-diff --git a/pixmaps/intlclock-map-location-hilight.svg b/pixmaps/intlclock-map-location-hilight.svg
-new file mode 100644
-index 0000000..4a245e0
---- /dev/null
-+++ b/pixmaps/intlclock-map-location-hilight.svg
-@@ -0,0 +1,90 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<!-- Created with Inkscape (http://www.inkscape.org/) -->
-+<svg
-+ xmlns:dc="http://purl.org/dc/elements/1.1/"
-+ xmlns:cc="http://web.resource.org/cc/"
-+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-+ xmlns:svg="http://www.w3.org/2000/svg"
-+ xmlns="http://www.w3.org/2000/svg"
-+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-+ width="7"
-+ height="7"
-+ id="svg6063"
-+ sodipodi:version="0.32"
-+ inkscape:version="0.45.1"
-+ version="1.0"
-+ sodipodi:docbase="/home/mclasen/Desktop/intlclock/pixmaps"
-+ sodipodi:docname="intlclock-map-location-hilight.svg"
-+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
-+ inkscape:export-filename="/home/garrett/Desktop/dot.png"
-+ inkscape:export-xdpi="90"
-+ inkscape:export-ydpi="90">
-+ <defs
-+ id="defs6065">
-+ <linearGradient
-+ id="linearGradient7251">
-+ <stop
-+ style="stop-color:#e1d9dc;stop-opacity:1;"
-+ offset="0"
-+ id="stop7253" />
-+ <stop
-+ id="stop3143"
-+ offset="0.5"
-+ style="stop-color:#e3bfca;stop-opacity:1;" />
-+ <stop
-+ style="stop-color:#3d0e1a;stop-opacity:1;"
-+ offset="1"
-+ id="stop7255" />
-+ </linearGradient>
-+ </defs>
-+ <sodipodi:namedview
-+ id="base"
-+ pagecolor="#ffffff"
-+ bordercolor="#666666"
-+ borderopacity="1.0"
-+ gridtolerance="10000"
-+ guidetolerance="10"
-+ objecttolerance="10"
-+ inkscape:pageopacity="0.0"
-+ inkscape:pageshadow="2"
-+ inkscape:zoom="22.627417"
-+ inkscape:cx="2.5000319"
-+ inkscape:cy="2.5000319"
-+ inkscape:document-units="px"
-+ inkscape:current-layer="layer1"
-+ inkscape:window-width="872"
-+ inkscape:window-height="750"
-+ inkscape:window-x="0"
-+ inkscape:window-y="30" />
-+ <metadata
-+ id="metadata6068">
-+ <rdf:RDF>
-+ <cc:Work
-+ rdf:about="">
-+ <dc:format>image/svg+xml</dc:format>
-+ <dc:type
-+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-+ </cc:Work>
-+ </rdf:RDF>
-+ </metadata>
-+ <g
-+ inkscape:label="Layer 1"
-+ inkscape:groupmode="layer"
-+ id="layer1"
-+ transform="translate(-474.64282,-409.86216)">
-+ <path
-+ sodipodi:type="arc"
-+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:13.16123206;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-+ id="path7259"
-+ sodipodi:cx="-418.5"
-+ sodipodi:cy="-489.5"
-+ sodipodi:rx="39.5"
-+ sodipodi:ry="39.5"
-+ d="M -379 -489.5 A 39.5 39.5 0 1 1 -458,-489.5 A 39.5 39.5 0 1 1 -379 -489.5 z"
-+ transform="matrix(5.4243529e-2,8.5329805e-4,-8.5329805e-4,5.4243529e-2,499.42608,439.2715)"
-+ inkscape:export-filename="/home/garrett/Desktop/map-new.png"
-+ inkscape:export-xdpi="90"
-+ inkscape:export-ydpi="90" />
-+ </g>
-+</svg>
-diff --git a/pixmaps/intlclock-map-location-marker.png b/pixmaps/intlclock-map-location-marker.png
-new file mode 100644
-index 0000000..48d2184
-Binary files /dev/null and b/pixmaps/intlclock-map-location-marker.png differ
-diff --git a/po/Makefile.in.in b/po/Makefile.in.in
-deleted file mode 100755
-index d2d4e4c..e4713cf
---- a/po/Makefile.in.in
-+++ /dev/null
-@@ -1,221 +0,0 @@
--# Makefile for program source directory in GNU NLS utilities package.
--# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
--#
--# This file file be copied and used freely without restrictions. It can
--# be used in projects which are not available under the GNU Public License
--# but which still want to provide support for the GNU gettext functionality.
--# Please note that the actual code is *not* freely available.
--#
--# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE
--# instead of PACKAGE and to look for po2tbl in ./ not in intl/
--#
--# - Modified by jacob berkman <jacob@ximian.com> to install
--# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
--#
--# - Modified by Rodney Dawes <dobey@novell.com> for use with intltool
--#
--# We have the following line for use by intltoolize:
--# INTLTOOL_MAKEFILE
--
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--PACKAGE = @PACKAGE@
--VERSION = @VERSION@
--
--SHELL = /bin/sh
--
--srcdir = @srcdir@
--top_srcdir = @top_srcdir@
--top_builddir = ..
--VPATH = @srcdir@
--
--prefix = @prefix@
--exec_prefix = @exec_prefix@
--datadir = @datadir@
--datarootdir = @datarootdir@
--libdir = @libdir@
--DATADIRNAME = @DATADIRNAME@
--itlocaledir = $(prefix)/$(DATADIRNAME)/locale
--subdir = po
--install_sh = @install_sh@
--# Automake >= 1.8 provides @mkdir_p@.
--# Until it can be supposed, use the safe fallback:
--mkdir_p = $(install_sh) -d
--
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--
--GMSGFMT = @GMSGFMT@
--MSGFMT = @MSGFMT@
--XGETTEXT = @XGETTEXT@
--INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
--INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
--MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
--GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
--
--ALL_LINGUAS = @ALL_LINGUAS@
--
--PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi)
--
--POFILES=$(shell if test -n "$(PO_LINGUAS)"; then LINGUAS="$(PO_LINGUAS)"; else LINGUAS="$(ALL_LINGUAS)"; fi; for lang in $$LINGUAS; do printf "$$lang.po "; done)
--
--DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES)
--EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS
--
--POTFILES = \
--#This Gets Replace for some reason
--
--CATALOGS=$(shell if test -n "$(PO_LINGUAS)"; then LINGUAS="$(PO_LINGUAS)"; else LINGUAS="$(ALL_LINGUAS)"; fi; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
--
--.SUFFIXES:
--.SUFFIXES: .po .pox .gmo .mo .msg .cat
--
--.po.pox:
-- $(MAKE) $(GETTEXT_PACKAGE).pot
-- $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
--
--.po.mo:
-- $(MSGFMT) -o $@ $<
--
--.po.gmo:
-- file=`echo $* | sed 's,.*/,,'`.gmo \
-- && rm -f $$file && $(GMSGFMT) -o $$file $<
--
--.po.cat:
-- sed -f ../intl/po2msg.sed < $< > $*.msg \
-- && rm -f $@ && gencat $@ $*.msg
--
--
--all: all-@USE_NLS@
--
--all-yes: $(CATALOGS)
--all-no:
--
--$(GETTEXT_PACKAGE).pot: $(POTFILES)
-- $(GENPOT)
--
--install: install-data
--install-data: install-data-@USE_NLS@
--install-data-no: all
--install-data-yes: all
-- $(mkdir_p) $(DESTDIR)$(itlocaledir)
-- if test -n "$(PO_LINGUAS)"; then \
-- linguas="$(PO_LINGUAS)"; \
-- else \
-- linguas="$(ALL_LINGUAS)"; \
-- fi; \
-- for lang in $$linguas; do \
-- dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \
-- $(mkdir_p) $$dir; \
-- if test -r $$lang.gmo; then \
-- $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
-- echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
-- else \
-- $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
-- echo "installing $(srcdir)/$$lang.gmo as" \
-- "$$dir/$(GETTEXT_PACKAGE).mo"; \
-- fi; \
-- if test -r $$lang.gmo.m; then \
-- $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
-- echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
-- else \
-- if test -r $(srcdir)/$$lang.gmo.m ; then \
-- $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
-- $$dir/$(GETTEXT_PACKAGE).mo.m; \
-- echo "installing $(srcdir)/$$lang.gmo.m as" \
-- "$$dir/$(GETTEXT_PACKAGE).mo.m"; \
-- else \
-- true; \
-- fi; \
-- fi; \
-- done
--
--# Empty stubs to satisfy archaic automake needs
--dvi info tags TAGS ID:
--
--# Define this as empty until I found a useful application.
--installcheck:
--
--uninstall:
-- if test -n "$(PO_LINGUAS)"; then \
-- linguas="$(PO_LINGUAS)"; \
-- else \
-- linguas="$(ALL_LINGUAS)"; \
-- fi; \
-- for lang in $$linguas; do \
-- rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
-- rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
-- done
--
--check: all $(GETTEXT_PACKAGE).pot
--
--mostlyclean:
-- rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
-- rm -f .intltool-merge-cache
--
--clean: mostlyclean
--
--distclean: clean
-- rm -f Makefile Makefile.in POTFILES stamp-it
-- rm -f *.mo *.msg *.cat *.cat.m *.gmo
--
--maintainer-clean: distclean
-- @echo "This command is intended for maintainers to use;"
-- @echo "it deletes files that may require special tools to rebuild."
-- rm -f Makefile.in.in
--
--distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
--dist distdir: $(DISTFILES)
-- dists="$(DISTFILES)"; \
-- extra_dists="$(EXTRA_DISTFILES)"; \
-- for file in $$extra_dists; do \
-- test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
-- done; \
-- for file in $$dists; do \
-- test -f $$file || file="$(srcdir)/$$file"; \
-- ln $$file $(distdir) 2> /dev/null \
-- || cp -p $$file $(distdir); \
-- done
--
--update-po: Makefile
-- $(MAKE) $(GETTEXT_PACKAGE).pot
-- tmpdir=`pwd`; \
-- if test -n "$(PO_LINGUAS)"; then \
-- linguas="$(PO_LINGUAS)"; \
-- else \
-- linguas="$(ALL_LINGUAS)"; \
-- fi; \
-- for lang in $$linguas; do \
-- echo "$$lang:"; \
-- result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
-- if $$result; then \
-- if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
-- rm -f $$tmpdir/$$lang.new.po; \
-- else \
-- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
-- :; \
-- else \
-- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
-- rm -f $$tmpdir/$$lang.new.po; \
-- exit 1; \
-- fi; \
-- fi; \
-- else \
-- echo "msgmerge for $$lang.gmo failed!"; \
-- rm -f $$tmpdir/$$lang.new.po; \
-- fi; \
-- done
--
--Makefile POTFILES: stamp-it
-- @if test ! -f $@; then \
-- rm -f stamp-it; \
-- $(MAKE) stamp-it; \
-- fi
--
--stamp-it: Makefile.in.in ../config.status POTFILES.in
-- cd .. \
-- && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
-- $(SHELL) ./config.status
--
--# Tell versions [3.59,3.63) of GNU make not to export all variables.
--# Otherwise a system limit (for SysV at least) may be exceeded.
--.NOEXPORT:
-diff --git a/po/Makefile.in.in b/po/Makefile.in.in
-new file mode 120000
-index d2d4e4c..e4713cf
---- /dev/null
-+++ b/po/Makefile.in.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/Makefile.in.in
-\ No newline at end of file
-diff --git a/src/Makefile.am b/src/Makefile.am
-index 80d1419..d681d39 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -3,7 +3,7 @@
- INCLUDES = \
- $(INTLCLOCK_CFLAGS) \
- -DGNOMELOCALEDIR=\"$(prefix)/$(DATADIRNAME)/locale\" \
-- -DEVOLUTION_TEXTDOMAIN=\"evolution-2.6\" \
-+ -DEVOLUTION_TEXTDOMAIN=\"evolution-2.12\" \
- -DINTLCLOCK_TEXTDOMAIN=\"gnome-panel-2.0\" \
- -DINTLCLOCK_ICONDIR=\"$(pkgdatadir)\" \
- -DINTLCLOCK_DATADIR=\"$(pkgdatadir)\" \
-@@ -60,7 +60,11 @@ COMMON_SOURCES = \
- intlclock-zoneinfo.c \
- intlclock-zoneinfo.h \
- intlclock-zonetable.c \
-- intlclock-zonetable.h
-+ intlclock-zonetable.h \
-+ set-timezone.c \
-+ set-timezone.h \
-+ gweather-xml.c \
-+ gweather-xml.h
-
-
- intlclock_applet_SOURCES = \
-diff --git a/src/gweather-xml.c b/src/gweather-xml.c
-new file mode 100644
-index 0000000..1de649f
---- /dev/null
-+++ b/src/gweather-xml.c
-@@ -0,0 +1,505 @@
-+/* gweather-xml.c - Locations.xml parsing code
-+ *
-+ * Copyright (C) 2005 Ryan Lortie, 2004 Gareth Owen
-+ *
-+ * 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
-+ */
-+
-+
-+/* There is very little error checking in the parsing code below, it relies
-+ * heavily on the locations file being in the correct format. If you have
-+ * <name> elements within a parent element, they must come first and be
-+ * grouped together.
-+ * The format is as follows:
-+ *
-+ * <gweather format="1.0">
-+ * <region>
-+ * <name>Name of the region</name>
-+ * <name xml:lang="xx">Translated Name</name>
-+ * <name xml:lang="zz">Another Translated Name</name>
-+ * <country>
-+ * <name>Name of the country</name>
-+ * <location>
-+ * <name>Name of the location</name>
-+ * <code>IWIN code</code>
-+ * <zone>Forecast code (North America, Australia, UK only)</zone>
-+ * <radar>Weather.com radar map code (North America only)</radar>
-+ * <coordinates>Latitude and longitude as DD-MM[-SS][H] pair</coordinates>
-+ * </location>
-+ * <state>
-+ * <location>
-+ * ....
-+ * </location>
-+ * <city>
-+ * <name>Name of city with multiple locations</city>
-+ * <zone>Forecast code</zone>
-+ * <radar>Radar Map code</radar>
-+ * <location>
-+ * ...
-+ * </location>
-+ * </city>
-+ * </state>
-+ * </country>
-+ * </region>
-+ * <gweather>
-+ *
-+ * The thing to note is that each country can either contain different locations
-+ * or be split into "states" which in turn contain a list of locations.
-+ *
-+ */
-+
-+#include <string.h>
-+#include <math.h>
-+#include <locale.h>
-+#include <gtk/gtk.h>
-+#include <libxml/xmlreader.h>
-+
-+#include "gweather-xml.h"
-+
-+static gint
-+gweather_xml_location_sort_func( GtkTreeModel *model, GtkTreeIter *a,
-+ GtkTreeIter *b, gpointer user_data )
-+{
-+ gint res;
-+ gchar *name_a, *name_b;
-+ gchar *fold_a, *fold_b;
-+
-+ gtk_tree_model_get (model, a, GWEATHER_XML_COL_LOC, &name_a, -1);
-+ gtk_tree_model_get (model, b, GWEATHER_XML_COL_LOC, &name_b, -1);
-+
-+ fold_a = g_utf8_casefold(name_a, -1);
-+ fold_b = g_utf8_casefold(name_b, -1);
-+
-+ res = g_utf8_collate(fold_a, fold_b);
-+
-+ g_free(name_a);
-+ g_free(name_b);
-+ g_free(fold_a);
-+ g_free(fold_b);
-+
-+ return res;
-+}
-+
-+static char*
-+gweather_xml_get_value( xmlTextReaderPtr xml )
-+{
-+ char* value;
-+
-+ /* check for null node */
-+ if ( xmlTextReaderIsEmptyElement( xml ) )
-+ return NULL;
-+
-+ /* the next "node" is the text node containing the value we want to get */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ return NULL;
-+
-+ value = (char *) xmlTextReaderValue( xml );
-+
-+ /* move on to the end of this node */
-+ while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_END_ELEMENT )
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( value );
-+ return NULL;
-+ }
-+
-+ /* consume the end element too */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( value );
-+ return NULL;
-+ }
-+
-+ return value;
-+}
-+
-+static char *
-+gweather_xml_parse_name( xmlTextReaderPtr xml )
-+{
-+ const char * const *locales;
-+ const char *this_language;
-+ int best_match = INT_MAX;
-+ char *lang, *tagname;
-+ gboolean keep_going;
-+ char *name = NULL;
-+ int i;
-+
-+ locales = g_get_language_names();
-+
-+ do
-+ {
-+ /* First let's get the language */
-+ lang = (char *) xmlTextReaderXmlLang( xml );
-+
-+ if( lang == NULL )
-+ this_language = "C";
-+ else
-+ this_language = lang;
-+
-+ /* the next "node" is text node containing the actual name */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( lang );
-+ return NULL;
-+ }
-+
-+ for( i = 0; locales[i] && i < best_match; i++ )
-+ if( !strcmp( locales[i], this_language ) )
-+ {
-+ /* if we've already encounted a less accurate
-+ translation, then free it */
-+ xmlFree( name );
-+
-+ name = (char *) xmlTextReaderValue( xml );
-+ best_match = i;
-+
-+ break;
-+ }
-+
-+ xmlFree( lang );
-+
-+ while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_ELEMENT )
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( name );
-+ return NULL;
-+ }
-+
-+ /* if the next tag is another <name> then keep going */
-+ tagname = (char *) xmlTextReaderName( xml );
-+ keep_going = !strcmp( tagname, "name" );
-+ xmlFree( tagname );
-+
-+ } while( keep_going );
-+
-+ return name;
-+}
-+
-+static int
-+gweather_xml_parse_node (GtkTreeView *view, GtkTreeIter *parent,
-+ xmlTextReaderPtr xml, WeatherLocation *current,
-+ const char *dflt_radar, const char *dflt_zone,
-+ const char *cityname)
-+{
-+ GtkTreeStore *store = GTK_TREE_STORE( gtk_tree_view_get_model( view ) );
-+ char *name, *code, *zone, *radar, *coordinates;
-+ char **city, *nocity = NULL;
-+ GtkTreeIter iter, *self;
-+ gboolean is_location;
-+ char *tagname;
-+ int ret = -1;
-+ int tagtype;
-+
-+ if( (tagname = (char *) xmlTextReaderName( xml )) == NULL )
-+ return -1;
-+
-+ if( !strcmp( tagname, "city" ) )
-+ city = &name;
-+ else
-+ city = &nocity;
-+
-+ is_location = !strcmp( tagname, "location" );
-+
-+ /* if we're processing the top-level, then don't create a new iter */
-+ if( !strcmp( tagname, "gweather" ) )
-+ self = NULL;
-+ else
-+ {
-+ self = &iter;
-+ /* insert this node into the tree */
-+ gtk_tree_store_append( store, self, parent );
-+ }
-+
-+ xmlFree( tagname );
-+
-+ coordinates = NULL;
-+ radar = NULL;
-+ zone = NULL;
-+ code = NULL;
-+ name = NULL;
-+
-+ /* absorb the start tag */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+
-+ /* start parsing the actual contents of the node */
-+ while( (tagtype = xmlTextReaderNodeType( xml )) !=
-+ XML_READER_TYPE_END_ELEMENT )
-+ {
-+
-+ /* skip non-element types */
-+ if( tagtype != XML_READER_TYPE_ELEMENT )
-+ {
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+
-+ continue;
-+ }
-+
-+ tagname = (char *) xmlTextReaderName( xml );
-+
-+ if( !strcmp( tagname, "region" ) || !strcmp( tagname, "country" ) ||
-+ !strcmp( tagname, "state" ) || !strcmp( tagname, "city" ) ||
-+ !strcmp( tagname, "location" ) )
-+ {
-+ /* recursively handle sub-sections */
-+ if( gweather_xml_parse_node( view, self, xml, current,
-+ radar, zone, *city ) )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "name" ) )
-+ {
-+ xmlFree( name );
-+ if( (name = gweather_xml_parse_name( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "code" ) )
-+ {
-+ xmlFree( code );
-+ if( (code = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "zone" ) )
-+ {
-+ xmlFree( zone );
-+ if( (zone = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "radar" ) )
-+ {
-+ xmlFree( radar );
-+ if( (radar = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "coordinates" ) )
-+ {
-+ xmlFree( coordinates );
-+ if( (coordinates = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else /* some strange tag */
-+ {
-+ /* skip past it */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+ }
-+
-+ xmlFree( tagname );
-+ }
-+
-+ if( self )
-+ gtk_tree_store_set( store, self, GWEATHER_XML_COL_LOC, name, -1 );
-+
-+ /* absorb the end tag. in the case of processing a <gweather> then 'self'
-+ is NULL. In this case, we let this fail since we might be at EOF */
-+ if( xmlTextReaderRead( xml ) != 1 && self )
-+ goto error_out;
-+
-+ /* if this is an actual location, setup the WeatherLocation for it */
-+ if( is_location )
-+ {
-+ WeatherLocation *new_loc;
-+
-+ if( cityname == NULL )
-+ cityname = name;
-+
-+ if( radar != NULL )
-+ dflt_radar = radar;
-+
-+ if( zone != NULL )
-+ dflt_zone = zone;
-+
-+ new_loc = weather_location_new( cityname, code, dflt_zone,
-+ dflt_radar, coordinates );
-+
-+ gtk_tree_store_set( store, &iter, GWEATHER_XML_COL_POINTER, new_loc, -1 );
-+
-+ /* If this location is actually the currently selected one, select it */
-+ if( current && weather_location_equal( new_loc, current ) )
-+ {
-+ GtkTreePath *path;
-+
-+ path = gtk_tree_model_get_path( GTK_TREE_MODEL (store), &iter );
-+ gtk_tree_view_expand_to_path( view, path );
-+ gtk_tree_view_set_cursor( view, path, NULL, FALSE );
-+ gtk_tree_view_scroll_to_cell( view, path, NULL, TRUE, 0.5, 0.5 );
-+ gtk_tree_path_free( path );
-+ }
-+ }
-+
-+ ret = 0;
-+
-+error_out:
-+ xmlFree( name );
-+ xmlFree( code );
-+ xmlFree( zone );
-+ xmlFree( radar );
-+ xmlFree( coordinates );
-+
-+ return ret;
-+}
-+
-+/*****************************************************************************
-+ * Func: gweather_xml_load_locations()
-+ * Desc: Main entry point for loading the locations from the XML file
-+ * Parm:
-+ * *tree: tree to view locations
-+ * *current: currently selected location
-+ */
-+int
-+gweather_xml_load_locations( GtkTreeView *tree, WeatherLocation *current )
-+{
-+ char *tagname, *format;
-+ GtkTreeSortable *sortable;
-+ xmlTextReaderPtr xml;
-+ int keep_going;
-+ int ret = -1;
-+
-+ /* Open the xml file containing the different locations */
-+#ifdef GWEATHER_XML_LOCATION
-+ xml = xmlNewTextReaderFilename (GWEATHER_XML_LOCATION "Locations.xml");
-+#else
-+ xml = xmlNewTextReaderFilename ("/usr/share/gnome-applets/gweather/Locations.xml");
-+#endif
-+ if( xml == NULL )
-+ goto error_out;
-+
-+ /* fast forward to the first element */
-+ do
-+ {
-+ /* if we encounter a problem here, exit right away */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+ } while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_ELEMENT );
-+
-+ /* check the name and format */
-+ tagname = (char *) xmlTextReaderName( xml );
-+ keep_going = tagname && !strcmp( tagname, "gweather" );
-+ xmlFree( tagname );
-+
-+ if( !keep_going )
-+ goto error_out;
-+
-+ format = (char *) xmlTextReaderGetAttribute( xml, (xmlChar *) "format" );
-+ keep_going = format && !strcmp( format, "1.0" );
-+ xmlFree( format );
-+
-+ if( !keep_going )
-+ goto error_out;
-+
-+ ret = gweather_xml_parse_node( tree, NULL, xml, current, NULL, NULL, NULL );
-+
-+ if( ret )
-+ goto error_out;
-+
-+ /* Sort the tree */
-+ sortable = GTK_TREE_SORTABLE (gtk_tree_view_get_model( tree ));
-+ gtk_tree_sortable_set_default_sort_func( sortable,
-+ &gweather_xml_location_sort_func,
-+ NULL, NULL);
-+ gtk_tree_sortable_set_sort_column_id( sortable,
-+ GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
-+ GTK_SORT_ASCENDING );
-+error_out:
-+ xmlFreeTextReader( xml );
-+
-+ return ret;
-+}
-+
-+typedef struct {
-+ const gchar *name;
-+ gdouble latitude;
-+ gdouble longitude;
-+ gdouble distance;
-+ WeatherLocation *location;
-+} SearchData;
-+
-+
-+static gdouble
-+distance (gdouble lat1, gdouble lon1,
-+ gdouble lat2, gdouble lon2)
-+{
-+ gdouble radius = 6372.795;
-+
-+ return acos (cos (lat1) * cos (lat2) * cos (lon1 - lon2) + sin (lat1) * sin (lat2)) * radius;
-+}
-+
-+gboolean
-+compare_location (GtkTreeModel *model,
-+ GtkTreePath *path,
-+ GtkTreeIter *iter,
-+ gpointer user_data)
-+{
-+ SearchData *data = user_data;
-+ WeatherLocation *loc;
-+ gdouble d;
-+
-+ gtk_tree_model_get (model, iter, GWEATHER_XML_COL_POINTER, &loc, -1);
-+
-+ if (!loc)
-+ return FALSE;
-+
-+ d = distance (data->latitude, data->longitude, loc->latitude, loc->longitude);
-+
-+ if (d < data->distance) {
-+ data->distance = d;
-+ data->location = loc;
-+ }
-+
-+ return FALSE;
-+}
-+
-+gchar *
-+find_weather_code (const gchar *name,
-+ gdouble lat,
-+ gdouble lon)
-+{
-+ GtkTreeStore *model;
-+ GtkWidget *tv;
-+ GtkTreeViewColumn *column;
-+ GtkCellRenderer *cell_renderer;
-+ SearchData data;
-+ gchar *code;
-+
-+ model = gtk_tree_store_new (GWEATHER_XML_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
-+ tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
-+
-+ cell_renderer = gtk_cell_renderer_text_new ();
-+ column = gtk_tree_view_column_new_with_attributes ("not used", cell_renderer,
-+ "text", GWEATHER_XML_COL_LOC, NULL);
-+ gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
-+ gtk_tree_view_set_expander_column (GTK_TREE_VIEW (tv), column);
-+ gweather_xml_load_locations (GTK_TREE_VIEW (tv), NULL);
-+
-+ data.name = name;
-+ data.latitude = lat;
-+ data.longitude = lon;
-+ data.distance = 1e6;
-+ data.location = NULL;
-+
-+ gtk_tree_model_foreach (GTK_TREE_MODEL (model), compare_location, &data);
-+
-+ if (data.distance < 50)
-+ code = g_strdup (data.location->code);
-+ else
-+ code = g_strdup ("-");
-+
-+ g_debug ("distance: %f\nin: %s\nlat, lon: %f, %f\nout: %s\nDMS: %s\ncode: %s\n",
-+ data.distance, name, lat, lon, data.location->name, data.location->coordinates, code);
-+
-+ gtk_widget_destroy (tv);
-+
-+ return code;
-+}
-diff --git a/src/gweather-xml.h b/src/gweather-xml.h
-new file mode 100644
-index 0000000..6d012c4
---- /dev/null
-+++ b/src/gweather-xml.h
-@@ -0,0 +1,37 @@
-+/* gweather-xml.h
-+ *
-+ * Copyright (C) 2004 Gareth Owen
-+ *
-+ * 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
-+ */
-+
-+#ifndef __GWEATHER_XML_H__
-+#define __GWEATHER_XML_H__
-+
-+#include <gtk/gtk.h>
-+#include <libgweather/weather.h>
-+
-+enum
-+{
-+ GWEATHER_XML_COL_LOC = 0,
-+ GWEATHER_XML_COL_POINTER,
-+ GWEATHER_XML_NUM_COLUMNS
-+};
-+
-+int gweather_xml_load_locations( GtkTreeView *tree, WeatherLocation *current );
-+gchar *find_weather_code (const gchar *name, gdouble lat, gdouble lon);
-+
-+
-+#endif /* __GWEATHER_XML_H__ */
-diff --git a/src/intlclock-events-popup.c b/src/intlclock-events-popup.c
-index 4276f81..a54f6e3 100644
---- a/src/intlclock-events-popup.c
-+++ b/src/intlclock-events-popup.c
-@@ -1,6 +1,8 @@
- #include <gtk/gtk.h>
- #include <string.h>
- #include <time.h>
-+#include <gconf/gconf-client.h>
-+#include <panel-applet-gconf.h>
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
-@@ -11,12 +13,18 @@
- #endif
-
- #include "intlclock-events-popup.h"
-+#include "intlclock-ui.h"
-+
-+#define KEY_EXPAND_LOCATIONS "expand_locations"
-+#define KEY_EXPAND_TASKS "expand_tasks"
-+#define KEY_EXPAND_APPOINTMENTS "expand_appointments"
-
- G_DEFINE_TYPE (IntlClockEventsPopup, intlclock_events_popup, GTK_TYPE_WINDOW)
-
- typedef struct {
- IntlClock *clock;
- PanelApplet *panel_applet;
-+ IntlClockUI *ui;
-
- GtkWidget *calendar;
- GtkWidget *main_section;
-@@ -126,7 +134,7 @@ intlclock_events_popup_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc
- }
-
- IntlClockEventsPopup *
--intlclock_events_popup_new (IntlClock *clock, PanelApplet *panel_applet)
-+intlclock_events_popup_new (IntlClock *clock, PanelApplet *panel_applet, IntlClockUI *ui)
- {
- IntlClockEventsPopup *this;
- IntlClockEventsPopupPrivate *priv;
-@@ -138,6 +146,7 @@ intlclock_events_popup_new (IntlClock *clock, PanelApplet *panel_applet)
-
- priv->clock = g_object_ref (clock);
- priv->panel_applet = panel_applet;
-+ priv->ui = ui;
-
- gtk_widget_set_name (GTK_WIDGET (this), "intlclock-events-window");
- gtk_container_set_border_width (GTK_CONTAINER (this), 0);
-@@ -275,6 +284,21 @@ intlclock_events_popup_tick (IntlClock *clock, IntlClockEventsPopup *this)
- gmtime (&priv->current_time);
- }
-
-+static GtkWidget * create_hig_frame (IntlClockEventsPopup *this,
-+ const char *title,
-+ const char *button_label,
-+ const char *key,
-+ GCallback callback);
-+
-+
-+static void
-+edit_locations (IntlClockEventsPopup *this)
-+{
-+ IntlClockEventsPopupPrivate *priv = PRIVATE (this);
-+
-+ intlclock_ui_edit_locations (priv->ui);
-+}
-+
- static void
- intlclock_events_popup_fill (IntlClockEventsPopup *this)
- {
-@@ -296,7 +320,10 @@ intlclock_events_popup_fill (IntlClockEventsPopup *this)
-
- orient = panel_applet_get_orient (priv->panel_applet);
-
-- priv->clock_container = gtk_vbox_new (FALSE, 0);
-+ priv->clock_container = create_hig_frame (this,
-+ _("Locations"), _("Edit"),
-+ KEY_EXPAND_LOCATIONS,
-+ G_CALLBACK (edit_locations));
-
- switch (orient) {
- case PANEL_APPLET_ORIENT_UP:
-@@ -642,28 +669,167 @@ modify_task_text_attributes (GtkTreeModel *model,
- g_value_take_boxed (value, attr_list);
- }
-
-+static void
-+expand_collapse_child (GtkWidget *child,
-+ gpointer data)
-+{
-+ gboolean expanded;
-+
-+ if (data == child || gtk_widget_is_ancestor (data, child))
-+ return;
-+
-+ expanded = gtk_expander_get_expanded (GTK_EXPANDER (data));
-+ g_object_set (child, "visible", expanded, NULL);
-+}
-+
-+static void
-+expand_collapse (GtkWidget *expander,
-+ GParamSpec *pspec,
-+ gpointer data)
-+{
-+ GtkWidget *box = data;
-+
-+ gtk_container_foreach (GTK_CONTAINER (box),
-+ (GtkCallback)expand_collapse_child,
-+ expander);
-+}
-+
-+static void
-+expander_activated (GtkExpander *expander,
-+ gpointer data)
-+{
-+ IntlClockEventsPopup *this = data;
-+ IntlClockEventsPopupPrivate *priv = PRIVATE (this);
-+ const gchar *key;
-+ gboolean expanded;
-+
-+ key = (const gchar*)g_object_get_data (G_OBJECT (expander), "gconf-key");
-+ expanded = gtk_expander_get_expanded (expander);
-+
-+ panel_applet_gconf_set_bool (priv->panel_applet, key, expanded, NULL);
-+}
-+
-+static void
-+expanded_changed (GConfClient *client,
-+ guint cnxn_id,
-+ GConfEntry *entry,
-+ GtkExpander *expander)
-+{
-+ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-+ return;
-+
-+ gtk_expander_set_expanded (expander,
-+ gconf_value_get_bool (entry->value));
-+}
-+
-+static void
-+remove_listener (gpointer data)
-+{
-+ GConfClient *client;
-+
-+ client = gconf_client_get_default ();
-+ gconf_client_notify_remove (client, GPOINTER_TO_UINT (data));
-+ g_object_unref (client);
-+}
-+
-+static void
-+connect_expander_with_gconf (IntlClockEventsPopup *this,
-+ GtkWidget *expander,
-+ const gchar *key)
-+{
-+ IntlClockEventsPopupPrivate *priv = PRIVATE (this);
-+ GConfClient *client;
-+ gboolean expanded;
-+ guint listener;
-+ gchar *full_key;
-+
-+ g_object_set_data (G_OBJECT (expander), "gconf-key", (gpointer)key);
-+
-+ expanded = panel_applet_gconf_get_bool (priv->panel_applet, key, NULL);
-+ gtk_expander_set_expanded (GTK_EXPANDER (expander), expanded);
-+
-+ g_signal_connect_after (expander, "activate",
-+ G_CALLBACK (expander_activated),
-+ this);
-+
-+ client = gconf_client_get_default ();
-+ full_key = panel_applet_gconf_get_full_key (priv->panel_applet, key);
-+ listener = gconf_client_notify_add (client, full_key,
-+ (GConfClientNotifyFunc)expanded_changed,
-+ expander, NULL, NULL);
-+ g_object_set_data_full (G_OBJECT (expander), "listener-id",
-+ GUINT_TO_POINTER (listener), remove_listener);
-+ g_object_unref (client);
-+}
-+
-+static void add_child (GtkContainer *container,
-+ GtkWidget *child,
-+ GtkExpander *expander)
-+{
-+ gboolean expanded;
-+
-+ expanded = gtk_expander_get_expanded (expander);
-+ g_object_set (child, "visible", expanded, NULL);
-+}
-+
- static GtkWidget *
--create_hig_frame (const char *title)
-+create_hig_frame (IntlClockEventsPopup *this,
-+ const char *title,
-+ const char *button_label,
-+ const char *key,
-+ GCallback callback)
- {
- GtkWidget *vbox;
- GtkWidget *alignment;
- GtkWidget *label;
-+ GtkWidget *hbox;
-+ GtkWidget *button;
- char *bold_title;
-+ char *text;
-+ GtkWidget *expander;
-
- vbox = gtk_vbox_new (FALSE, 6);
-
- bold_title = g_strdup_printf ("<b>%s</b>", title);
--
-- alignment = gtk_alignment_new (0, 0.5, 0, 0);
-- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
-- gtk_widget_show (alignment);
--
-- label = gtk_label_new (bold_title);
-- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-- gtk_container_add (GTK_CONTAINER (alignment), label);
-- gtk_widget_show (label);
--
-+ expander = gtk_expander_new ("");
-+ gtk_expander_set_label (GTK_EXPANDER (expander), bold_title);
- g_free (bold_title);
-+ gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
-+
-+ hbox = gtk_hbox_new (FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (hbox), expander, FALSE, FALSE, 0);
-+ gtk_widget_show_all (vbox);
-+
-+ g_signal_connect (expander, "notify::expanded",
-+ G_CALLBACK (expand_collapse), hbox);
-+ g_signal_connect (expander, "notify::expanded",
-+ G_CALLBACK (expand_collapse), vbox);
-+
-+ /* FIXME: this doesn't really work, since "add" does not
-+ * get emitted for e.g. gtk_box_pack_start
-+ */
-+ g_signal_connect (vbox, "add", G_CALLBACK (add_child), expander);
-+ g_signal_connect (hbox, "add", G_CALLBACK (add_child), expander);
-+
-+ if (button_label) {
-+ button = gtk_button_new ();
-+ text = g_markup_printf_escaped ("<small>%s</small>", button_label);
-+ label = gtk_label_new (text);
-+ g_free (text);
-+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-+ gtk_container_add (GTK_CONTAINER (button), label);
-+
-+ alignment = gtk_alignment_new (1, 0, 0, 0);
-+ gtk_container_add (GTK_CONTAINER (alignment), button);
-+ gtk_widget_show_all (alignment);
-+
-+ gtk_container_add (GTK_CONTAINER (hbox), alignment);
-+
-+ g_signal_connect_swapped (button, "clicked", callback, this);
-+ }
-+
-+ connect_expander_with_gconf (this, expander, key);
-
- return vbox;
- }
-@@ -791,6 +957,12 @@ compare_tasks (GtkTreeModel *model,
- }
- }
-
-+static void
-+edit_tasks (IntlClockEventsPopup *this)
-+{
-+ clock_launch_evolution (this, "--component=tasks");
-+}
-+
- static GtkWidget *
- create_task_list (IntlClockEventsPopup *this,
- GtkWidget **tree_view,
-@@ -804,7 +976,9 @@ create_task_list (IntlClockEventsPopup *this,
- GtkCellRenderer *cell;
- GtkTreeViewColumn *column;
-
-- vbox = create_hig_frame (_("Tasks"));
-+ vbox = create_hig_frame (this, _("Tasks"), _("Edit"),
-+ KEY_EXPAND_TASKS,
-+ G_CALLBACK (edit_tasks));
-
- *scrolled_window = scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
-@@ -812,8 +986,8 @@ create_task_list (IntlClockEventsPopup *this,
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
-- gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
- gtk_widget_show (scrolled);
-+ gtk_container_add (GTK_CONTAINER (vbox), scrolled);
-
- if (!priv->tasks_model) {
- GType column_types [N_TASK_COLUMNS] = {
-@@ -984,6 +1158,12 @@ handle_appointments_changed (IntlClockEventsPopup *this)
- update_frame_visibility (priv->appointment_list, GTK_TREE_MODEL (priv->appointments_model));
- }
-
-+static void
-+edit_appointments (IntlClockEventsPopup *this)
-+{
-+ clock_launch_evolution (this, "--component=calendar");
-+}
-+
- static GtkWidget *
- create_appointment_list (IntlClockEventsPopup *this,
- GtkWidget **tree_view,
-@@ -997,7 +1177,9 @@ create_appointment_list (IntlClockEventsPopup *this,
- GtkCellRenderer *cell;
- GtkTreeViewColumn *column;
-
-- vbox = create_hig_frame ( _("Appointments"));
-+ vbox = create_hig_frame (this, _("Appointments"), _("Edit"),
-+ KEY_EXPAND_APPOINTMENTS,
-+ G_CALLBACK (edit_appointments));
-
- *scrolled_window = scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
-@@ -1005,8 +1187,8 @@ create_appointment_list (IntlClockEventsPopup *this,
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
-- gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
- gtk_widget_show (scrolled);
-+ gtk_container_add (GTK_CONTAINER (vbox), scrolled);
-
- if (!priv->appointments_model) {
- priv->appointments_model =
-diff --git a/src/intlclock-events-popup.h b/src/intlclock-events-popup.h
-index 84a5183..b88e4c7 100644
---- a/src/intlclock-events-popup.h
-+++ b/src/intlclock-events-popup.h
-@@ -2,6 +2,7 @@
- #define __INTLCLOCK_EVENTS_POPUP_H__
-
- #include "intlclock.h"
-+#include "intlclock-ui.h"
-
- #include <glib.h>
- #include <gtk/gtk.h>
-@@ -29,7 +30,8 @@ typedef struct
- GType intlclock_events_popup_get_type (void);
-
- IntlClockEventsPopup *intlclock_events_popup_new (IntlClock *clock,
-- PanelApplet *panel_applet);
-+ PanelApplet *panel_applet,
-+ IntlClockUI *ui);
- void intlclock_events_popup_set_date (IntlClockEventsPopup *this,
- guint year, guint month, guint mday);
- GtkWidget *intlclock_events_popup_get_clock_container (IntlClockEventsPopup *this);
-diff --git a/src/intlclock-location-tile.c b/src/intlclock-location-tile.c
-index 40d96e3..412ad22 100644
---- a/src/intlclock-location-tile.c
-+++ b/src/intlclock-location-tile.c
-@@ -23,9 +23,18 @@ typedef struct {
-
- IntlClockFaceSize size;
-
-+ GtkWidget *box;
- GtkWidget *clock_face;
- GtkWidget *city_label;
- GtkWidget *time_label;
-+
-+ GtkWidget *current_button;
-+ GtkWidget *current_label;
-+ GtkWidget *current_marker;
-+ GtkSizeGroup *button_group;
-+
-+ GtkWidget *weather_icon;
-+
- } IntlClockLocationTilePrivate;
-
- static void intlclock_location_tile_finalize (GObject *);
-@@ -36,6 +45,12 @@ static void intlclock_location_tile_refresh (IntlClockLocationTile *this);
- #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_LOCATION_TILE_TYPE, IntlClockLocationTilePrivate))
-
- static void intlclock_location_tile_fill (IntlClockLocationTile *this);
-+static void update_weather_icon (IntlClockLocation *loc, WeatherInfo *info, gpointer data);
-+static gboolean weather_tooltip (GtkWidget *widget,
-+ gint x, gint y,
-+ gboolean keyboard_mode,
-+ GtkTooltip *tooltip,
-+ gpointer data);
-
- IntlClockLocationTile *
- intlclock_location_tile_new (IntlClock *clock, IntlClockUI *ui,
-@@ -56,13 +71,17 @@ intlclock_location_tile_new (IntlClock *clock, IntlClockUI *ui,
- priv->location = g_object_ref (loc);
- priv->size = size;
-
-- gtk_alignment_set (GTK_ALIGNMENT (this), 0.0, 0.0, 0.0, 0.0);
-- gtk_alignment_set_padding (GTK_ALIGNMENT (this), 3, 3, 3, 3);
--
- intlclock_location_tile_fill (this);
-
-- g_signal_connect (G_OBJECT (priv->clock), "tick",
-- G_CALLBACK (intlclock_location_tile_tick), this);
-+ update_weather_icon (loc, intlclock_location_get_weather_info (loc), this);
-+ gtk_widget_set_has_tooltip (priv->weather_icon, TRUE);
-+
-+ g_signal_connect (priv->weather_icon, "query-tooltip",
-+ G_CALLBACK (weather_tooltip), this);
-+ g_signal_connect (G_OBJECT (loc), "weather-updated",
-+ G_CALLBACK (update_weather_icon), this);
-+ g_signal_connect (G_OBJECT (priv->clock), "tick",
-+ G_CALLBACK (intlclock_location_tile_tick), this);
-
- return this;
- }
-@@ -133,13 +152,99 @@ intlclock_location_tile_finalize (GObject *g_obj)
- priv->location = NULL;
- }
-
-+ if (priv->button_group) {
-+ g_object_unref (priv->button_group);
-+ priv->button_group = NULL;
-+ }
-+
- G_OBJECT_CLASS (intlclock_location_tile_parent_class)->finalize (g_obj);
- }
-
-+static gboolean
-+press_on_tile (GtkWidget *widget,
-+ GdkEventButton *event,
-+ IntlClockLocationTile *tile)
-+{
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+
-+ intlclock_blink_location (priv->clock, priv->location);
-+
-+ return TRUE;
-+}
-+
-+static void
-+make_current (GtkWidget *widget, IntlClockLocationTile *tile)
-+{
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+ GError *error = NULL;
-+ GtkWidget *dialog;
-+
-+ if (intlclock_location_make_current (priv->location, &error)) {
-+ g_signal_emit_by_name (priv->clock, "current-timezone-changed", 0);
-+ }
-+ else if (error) {
-+ dialog = gtk_message_dialog_new (NULL,
-+ 0,
-+ GTK_MESSAGE_ERROR,
-+ GTK_BUTTONS_OK,
-+ _("Failed to set the system timezone"));
-+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), error->message);
-+ g_signal_connect (dialog, "response",
-+ G_CALLBACK (gtk_widget_destroy), NULL);
-+ gtk_window_present (GTK_WINDOW (dialog));
-+
-+ g_error_free (error);
-+ }
-+}
-+
-+static gboolean
-+enter_or_leave_tile (GtkWidget *widget,
-+ GdkEventCrossing *event,
-+ IntlClockLocationTile *tile)
-+{
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+
-+ if (event->type == GDK_ENTER_NOTIFY) {
-+ gint can_set;
-+
-+ can_set = can_set_system_timezone ();
-+ if (!intlclock_location_is_current (priv->location) &&
-+ can_set != 0) {
-+ gtk_label_set_markup (GTK_LABEL (priv->current_label),
-+ can_set == 1 ?
-+ _("<small>Set...</small>") :
-+ _("<small>Set</small>"));
-+ gtk_widget_show (priv->current_button);
-+ }
-+ }
-+ else {
-+ if (event->detail != GDK_NOTIFY_INFERIOR)
-+ gtk_widget_hide (priv->current_button);
-+ }
-+
-+ return TRUE;
-+}
-+
- static void
- intlclock_location_tile_fill (IntlClockLocationTile *this)
- {
- IntlClockLocationTilePrivate *priv = PRIVATE (this);
-+ GtkWidget *align;
-+ GtkWidget *strut;
-+ GtkWidget *box;
-+
-+ priv->box = gtk_event_box_new ();
-+
-+ gtk_widget_add_events (priv->box, GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-+ g_signal_connect (priv->box, "button-press-event",
-+ G_CALLBACK (press_on_tile), this);
-+ g_signal_connect (priv->box, "enter-notify-event",
-+ G_CALLBACK (enter_or_leave_tile), this);
-+ g_signal_connect (priv->box, "leave-notify-event",
-+ G_CALLBACK (enter_or_leave_tile), this);
-+
-+ GtkWidget *alignment = gtk_alignment_new (0, 0, 1, 0);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 0);
-
- GtkWidget *tile = gtk_hbox_new (FALSE, 6);
- GtkWidget *head_section = gtk_vbox_new (FALSE, 0);
-@@ -147,21 +252,55 @@ intlclock_location_tile_fill (IntlClockLocationTile *this)
- priv->city_label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (priv->city_label), 0, 0);
-
-+ align = gtk_alignment_new (0, 0, 0, 0);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 0, 3);
-+ gtk_container_add (GTK_CONTAINER (align), priv->city_label);
-+ gtk_box_pack_start (GTK_BOX (head_section), align, FALSE, FALSE, 0);
-+
- priv->time_label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (priv->time_label), 0, 0);
-
-- gtk_box_pack_start (GTK_BOX (head_section), priv->city_label,
-- FALSE, FALSE, 0);
-- gtk_box_pack_start (GTK_BOX (head_section), priv->time_label,
-- FALSE, FALSE, 0);
-+ priv->weather_icon = gtk_image_new ();
-+ align = gtk_alignment_new (0, 0, 0, 0);
-+ gtk_container_add (GTK_CONTAINER (align), priv->weather_icon);
-+
-+ box = gtk_hbox_new (FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (head_section), box, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), align, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), priv->time_label, FALSE, FALSE, 0);
-+
-+ priv->current_button = gtk_button_new ();
-+ priv->current_label = gtk_label_new ("");
-+ gtk_widget_show (priv->current_label);
-+ gtk_widget_set_no_show_all (priv->current_button, TRUE);
-+ gtk_container_add (GTK_CONTAINER (priv->current_button), priv->current_label);
-+ gtk_widget_set_tooltip_text (priv->current_button, _("Set as current timezone for this computer"));
-+
-+ priv->current_marker = gtk_image_new_from_icon_name ("go-home", GTK_ICON_SIZE_BUTTON);
-+ gtk_widget_set_no_show_all (priv->current_marker, TRUE);
-+
-+ align = gtk_alignment_new (1, 1, 0, 0);
-+ strut = gtk_event_box_new ();
-+ gtk_box_pack_start (GTK_BOX (box), strut, TRUE, TRUE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), priv->current_button, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), priv->current_marker, FALSE, FALSE, 0);
-+ priv->button_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
-+ gtk_size_group_set_ignore_hidden (priv->button_group, FALSE);
-+ gtk_size_group_add_widget (priv->button_group, strut);
-+ gtk_size_group_add_widget (priv->button_group, priv->current_button);
-+
-+ g_signal_connect (priv->current_button, "clicked",
-+ G_CALLBACK (make_current), this);
-
- priv->clock_face = intlclock_face_new_with_location (
- priv->size, priv->location, head_section);
-
- gtk_box_pack_start (GTK_BOX (tile), priv->clock_face, FALSE, FALSE, 0);
-- gtk_box_pack_start (GTK_BOX (tile), head_section, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (tile), head_section, TRUE, TRUE, 0);
-
-- gtk_container_add (GTK_CONTAINER (this), tile);
-+ gtk_container_add (GTK_CONTAINER (alignment), tile);
-+ gtk_container_add (GTK_CONTAINER (priv->box), alignment);
-+ gtk_container_add (GTK_CONTAINER (this), priv->box);
-
- intlclock_location_tile_refresh (this);
- }
-@@ -231,6 +370,21 @@ intlclock_location_tile_refresh (IntlClockLocationTile *this)
- char buf[256];
- struct tm now;
-
-+ if (intlclock_location_is_current (priv->location)) {
-+ if (!GTK_WIDGET_VISIBLE (priv->current_marker)) {
-+ GdkPixbuf *pixbuf;
-+
-+ pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (priv->weather_icon));
-+ intlclock_ui_update_weather_icon (priv->ui, pixbuf);
-+ }
-+
-+ gtk_widget_hide (priv->current_button);
-+ gtk_widget_show (priv->current_marker);
-+ }
-+ else {
-+ gtk_widget_hide (priv->current_marker);
-+ }
-+
- if (intlclock_needs_face_refresh (this)) {
- intlclock_face_refresh (INTLCLOCK_FACE (priv->clock_face));
- }
-@@ -271,3 +425,86 @@ intlclock_location_tile_tick (IntlClock *clock,
-
- intlclock_location_tile_refresh (this);
- }
-+
-+static gboolean
-+weather_tooltip (GtkWidget *widget,
-+ gint x,
-+ gint y,
-+ gboolean keyboard_mode,
-+ GtkTooltip *tooltip,
-+ gpointer data)
-+{
-+ IntlClockLocationTile *tile = data;
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+ WeatherInfo *info;
-+ GdkPixbuf *pixbuf = NULL;
-+ gchar *conditions, *temp, *apparent, *wind;
-+ gchar *line1, *line2, *line3, *line4, *tip;
-+
-+ info = intlclock_location_get_weather_info (priv->location);
-+
-+ if (!info || !weather_info_is_valid (info))
-+ return FALSE;
-+
-+ weather_info_get_pixbuf (info, &pixbuf);
-+ if (pixbuf)
-+ gtk_tooltip_set_icon (tooltip, pixbuf);
-+
-+ conditions = weather_info_get_conditions (info);
-+ if (strcmp (conditions, "-") != 0)
-+ line1 = g_strdup_printf (_("%s, %s"),
-+ conditions,
-+ weather_info_get_sky (info));
-+ else
-+ line1 = g_strdup (weather_info_get_sky (info));
-+
-+ temp = weather_info_get_temp (info);
-+ apparent = weather_info_get_apparent (info);
-+ if (strcmp (apparent, temp) != 0 &&
-+ /* FIXME libgweather needs some real api */
-+ strcmp (apparent, dgettext ("gnome-applets-2.0", "Unknown")) != 0)
-+ line2 = g_strdup_printf (_("%s, feels like %s"), temp, apparent);
-+ else
-+ line2 = g_strdup (temp);
-+
-+ wind = weather_info_get_wind (info);
-+ if (strcmp (apparent, dgettext ("gnome-applets-2.0", "Unknown")) != 0)
-+ line3 = g_strdup_printf ("%s\n", wind);
-+ else
-+ line3 = g_strdup ("");
-+
-+ line4 = g_strdup_printf (_("Sunrise: %s / Sunset: %s"),
-+ weather_info_get_sunrise (info),
-+ weather_info_get_sunset (info));
-+
-+ tip = g_strdup_printf ("<b>%s</b>\n%s\n%s%s", line1, line2, line3, line4);
-+ gtk_tooltip_set_markup (tooltip, tip);
-+ g_free (line1);
-+ g_free (line2);
-+ g_free (line3);
-+ g_free (line4);
-+ g_free (tip);
-+
-+ return TRUE;
-+}
-+
-+
-+static void
-+update_weather_icon (IntlClockLocation *loc, WeatherInfo *info, gpointer data)
-+{
-+ IntlClockLocationTile *tile = data;
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+ GdkPixbuf *pixbuf = NULL;
-+
-+ if (!info || !weather_info_is_valid (info))
-+ return;
-+
-+ weather_info_get_pixbuf_mini (info, &pixbuf);
-+
-+ if (pixbuf) {
-+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->weather_icon), pixbuf);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (gtk_widget_get_parent (priv->weather_icon)), 0, 0, 0, 6);
-+ intlclock_ui_update_weather_icon (priv->ui, pixbuf);
-+ }
-+}
-+
-diff --git a/src/intlclock-location.c b/src/intlclock-location.c
-index 384b2aa..911505c 100644
---- a/src/intlclock-location.c
-+++ b/src/intlclock-location.c
-@@ -1,4 +1,3 @@
--#include "intlclock-location.h"
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
-@@ -13,9 +12,16 @@
- #include <sys/stat.h>
- #include <time.h>
- #include <unistd.h>
-+#include <math.h>
-
- #include <glib.h>
- #include <libgnome/gnome-i18n.h>
-+#include <libgnomevfs/gnome-vfs.h>
-+
-+#include "intlclock-location.h"
-+#include "intlclock-marshallers.h"
-+#include "set-timezone.h"
-+#include "gweather-xml.h"
-
- G_DEFINE_TYPE (IntlClockLocation, intlclock_location, G_TYPE_OBJECT)
-
-@@ -29,17 +35,31 @@ typedef struct {
-
- gfloat latitude;
- gfloat longitude;
-+
-+ gchar *weather_code;
-+ WeatherInfo *weather_info;
-+ guint weather_timeout;
-+
- } IntlClockLocationPrivate;
-
-+enum {
-+ WEATHER_UPDATED,
-+ LAST_SIGNAL
-+};
-+
-+static guint location_signals[LAST_SIGNAL] = { 0 };
-+
- static void intlclock_location_finalize (GObject *);
- static void intlclock_location_set_tz (IntlClockLocation *this);
- static void intlclock_location_unset_tz (IntlClockLocation *this);
-+static void setup_weather_updates (IntlClockLocation *loc);
-
- #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_LOCATION_TYPE, IntlClockLocationPrivate))
-
- IntlClockLocation *
- intlclock_location_new (const gchar *name, const gchar *timezone,
-- gfloat latitude, gfloat longitude)
-+ gfloat latitude, gfloat longitude,
-+ const gchar *code)
- {
- IntlClockLocation *this;
- IntlClockLocationPrivate *priv;
-@@ -62,6 +82,14 @@ intlclock_location_new (const gchar *name, const gchar *timezone,
- priv->latitude = latitude;
- priv->longitude = longitude;
-
-+ if (code)
-+ priv->weather_code = g_strdup (code);
-+ else
-+ priv->weather_code = find_weather_code (name,
-+ latitude * M_PI/180.0,
-+ longitude * M_PI/180.0);
-+ setup_weather_updates (this);
-+
- return this;
- }
-
-@@ -193,6 +221,77 @@ guess_zone_from_tree (const gchar *localtime, IntlClockZoneTable *zones)
- return ret;
- }
-
-+static const gchar *current_zone = NULL;
-+static GnomeVFSMonitorHandle *monitor = NULL;
-+
-+static void
-+parse_etc_sysconfig_clock (void)
-+{
-+ gchar *data;
-+ gsize len;
-+ gchar **lines;
-+ gchar *res;
-+ gint i;
-+ gchar *p, *q;
-+
-+ lines = NULL;
-+ res = NULL;
-+ if (g_file_test ("/etc/sysconfig/clock",
-+ G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-+ if (!g_file_get_contents ("/etc/sysconfig/clock",
-+ &data, &len, NULL))
-+ goto out;
-+
-+ lines = g_strsplit (data, "\n", 0);
-+ g_free (data);
-+
-+ for (i = 0; lines[i] && !res; i++) {
-+ if (g_str_has_prefix (lines[i], "ZONE=")) {
-+ p = lines[i] + strlen ("ZONE=");
-+ if (p[0] != '\"')
-+ goto out;
-+ p++;
-+ q = strchr (p, '\"');
-+ q[0] = '\0';
-+ res = g_strdup (p);
-+ }
-+ }
-+ }
-+
-+out:
-+ if (lines)
-+ g_strfreev (lines);
-+
-+ g_free (current_zone);
-+ current_zone = res;
-+}
-+
-+static void
-+monitor_etc_sysconfig_clock (GnomeVFSMonitorHandle *handle,
-+ const gchar *monitor_uri,
-+ const gchar *info_uri,
-+ GnomeVFSMonitorEventType event_type,
-+ gpointer user_data)
-+{
-+ parse_etc_sysconfig_clock ();
-+}
-+
-+static const gchar *
-+zone_from_etc_sysconfig_clock (void)
-+{
-+ if (monitor == NULL) {
-+ parse_etc_sysconfig_clock ();
-+
-+ gnome_vfs_monitor_add (&monitor,
-+ "/etc/sysconfig/clock",
-+ GNOME_VFS_MONITOR_FILE,
-+ monitor_etc_sysconfig_clock,
-+ NULL);
-+ }
-+
-+ return current_zone;
-+}
-+
- static gchar *
- intlclock_location_guess_zone (IntlClockZoneTable *zones)
- {
-@@ -200,6 +299,12 @@ intlclock_location_guess_zone (IntlClockZoneTable *zones)
- const char *localtime = "/etc/localtime";
- gchar *linkfile = NULL;
- GError *err = NULL;
-+ gchar *zone;
-+
-+ /* look for /etc/sysconfig/clock */
-+ if ((zone = zone_from_etc_sysconfig_clock ())) {
-+ return g_strdup (zone);
-+ }
-
- /* guess the current time zone by readlink() on /etc/localtime */
- linkfile = g_file_read_link (localtime, &err);
-@@ -235,14 +340,14 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
-
- if (zone == NULL) {
- /* make a fake location with a null TZ */
-- return intlclock_location_new (_("Unknown Location"), NULL, 0.0, 0.0);
-+ return intlclock_location_new (_("Unknown Location"), NULL, 0.0, 0.0, NULL);
- }
-
- info = intlclock_zonetable_get_zone (zones, zone);
-
- if (info == NULL) {
- /* make a fake location with the current TZ */
-- return intlclock_location_new (_("Unknown Location"), zone, 0.0, 0.0);
-+ return intlclock_location_new (_("Unknown Location"), zone, 0.0, 0.0, NULL);
- }
-
- g_free (zone);
-@@ -260,7 +365,7 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
- }
-
- ret = intlclock_location_new (name, intlclock_zoneinfo_get_name (info),
-- lat, lon);
-+ lat, lon, NULL);
-
- g_free (name);
-
-@@ -274,6 +379,15 @@ intlclock_location_class_init (IntlClockLocationClass *this_class)
-
- g_obj_class->finalize = intlclock_location_finalize;
-
-+ location_signals[WEATHER_UPDATED] =
-+ g_signal_new ("weather-updated",
-+ G_OBJECT_CLASS_TYPE (g_obj_class),
-+ G_SIGNAL_RUN_FIRST,
-+ G_STRUCT_OFFSET (IntlClockLocationClass, weather_updated),
-+ NULL, NULL,
-+ _intlclock_marshal_VOID__POINTER,
-+ G_TYPE_NONE, 1, G_TYPE_POINTER);
-+
- g_type_class_add_private (this_class, sizeof (IntlClockLocationPrivate));
- }
-
-@@ -318,6 +432,21 @@ intlclock_location_finalize (GObject *g_obj)
- priv->tzname = NULL;
- }
-
-+ if (priv->weather_code) {
-+ g_free (priv->weather_code);
-+ priv->weather_code = NULL;
-+ }
-+
-+ if (priv->weather_info) {
-+ weather_info_free (priv->weather_info);
-+ priv->weather_info = NULL;
-+ }
-+
-+ if (priv->weather_timeout) {
-+ g_source_remove (priv->weather_timeout);
-+ priv->weather_timeout = 0;
-+ }
-+
- G_OBJECT_CLASS (intlclock_location_parent_class)->finalize (g_obj);
- }
-
-@@ -467,3 +596,156 @@ intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm)
-
- intlclock_location_unset_tz (loc);
- }
-+
-+gboolean
-+intlclock_location_is_current (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ gboolean current;
-+ long sys_timezone;
-+ const char *zone;
-+
-+ if ((zone = zone_from_etc_sysconfig_clock ()))
-+ return strcmp (zone, priv->timezone) == 0;
-+
-+ unsetenv ("TZ");
-+ tzset ();
-+ sys_timezone = timezone;
-+
-+ setenv ("TZ", priv->timezone, 1);
-+ tzset();
-+
-+ current = sys_timezone == timezone;
-+
-+ if (priv->sys_timezone) {
-+ setenv ("TZ", priv->sys_timezone, 1);
-+ } else {
-+ unsetenv ("TZ");
-+ }
-+ tzset();
-+
-+ return current;
-+}
-+
-+gboolean
-+intlclock_location_make_current (IntlClockLocation *loc, GError **error)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ gchar *filename;
-+ gboolean ret;
-+
-+ filename = g_build_filename (SYSTEM_ZONEINFODIR, priv->timezone, NULL);
-+ ret = set_system_timezone (filename, error);
-+ g_free (filename);
-+
-+ /* FIXME this ugly shortcut is necessary until we move the
-+ * current timezone tracking to intlclock.c and emit the
-+ * signal from there
-+ */
-+ g_free (current_zone);
-+ current_zone = g_strdup (priv->timezone);
-+
-+ return ret;
-+}
-+
-+const gchar *
-+intlclock_location_get_weather_code (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ return priv->weather_code;
-+}
-+
-+WeatherInfo *
-+intlclock_location_get_weather_info (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ return priv->weather_info;
-+}
-+
-+static void
-+weather_info_updated (WeatherInfo *info, gpointer data)
-+{
-+ IntlClockLocation *loc = data;
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ g_signal_emit (loc, location_signals[WEATHER_UPDATED],
-+ 0, priv->weather_info);
-+}
-+
-+static gboolean
-+update_weather_info (gpointer data)
-+{
-+ IntlClockLocation *loc = data;
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ WeatherPrefs prefs = {
-+ FORECAST_STATE,
-+ FALSE,
-+ NULL,
-+ TEMP_UNIT_CENTIGRADE,
-+ SPEED_UNIT_MS,
-+ PRESSURE_UNIT_MB,
-+ DISTANCE_UNIT_KM
-+ };
-+
-+ weather_info_update (priv->weather_info,
-+ &prefs, weather_info_updated, loc);
-+
-+ return TRUE;
-+}
-+
-+static gchar *
-+rad2dms (gfloat lat, gfloat lon)
-+{
-+ gchar h, h2;
-+ gfloat d, deg, min, d2, deg2, min2;
-+
-+ h = lat > 0 ? 'N' : 'S';
-+ d = fabs (lat);
-+ deg = floor (d);
-+ min = floor (60 * (d - deg));
-+ h2 = lon > 0 ? 'E' : 'W';
-+ d2 = fabs (lon);
-+ deg2 = floor (d2);
-+ min2 = floor (60 * (d2 - deg2));
-+ return g_strdup_printf ("%02d-%02d%c %02d-%02d%c",
-+ (int)deg, (int)min, h,
-+ (int)deg2, (int)min2, h2);
-+}
-+
-+static void
-+setup_weather_updates (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ const gchar *code;
-+ WeatherLocation *wl;
-+ WeatherPrefs prefs = {
-+ FORECAST_STATE,
-+ FALSE,
-+ NULL,
-+ TEMP_UNIT_CENTIGRADE,
-+ SPEED_UNIT_MS,
-+ PRESSURE_UNIT_MB,
-+ DISTANCE_UNIT_KM
-+ };
-+ gfloat lat, lon;
-+ gchar *dms;
-+
-+ if (!priv->weather_code || strcmp (priv->weather_code, "-") == 0)
-+ return;
-+
-+ dms = rad2dms (priv->latitude, priv->longitude);
-+ wl = weather_location_new (priv->name, priv->weather_code,
-+ NULL, NULL, dms);
-+
-+ priv->weather_info =
-+ weather_info_new (wl, &prefs, weather_info_updated, loc);
-+
-+ priv->weather_timeout =
-+ g_timeout_add_seconds (1800, update_weather_info, loc);
-+
-+ weather_location_free (wl);
-+ g_free (dms);
-+}
-+
-diff --git a/src/intlclock-location.h b/src/intlclock-location.h
-index 824ee3c..a3856e7 100644
---- a/src/intlclock-location.h
-+++ b/src/intlclock-location.h
-@@ -4,6 +4,7 @@
- #include <time.h>
- #include <glib.h>
- #include <glib-object.h>
-+#include <libgweather/weather.h>
-
- #include "intlclock-zonetable.h"
-
-@@ -24,12 +25,16 @@ typedef struct
- typedef struct
- {
- GObjectClass g_object_class;
-+
-+ void (* weather_updated) (IntlClockLocation *location, WeatherInfo *info);
-+
- } IntlClockLocationClass;
-
- GType intlclock_location_get_type (void);
-
- IntlClockLocation *intlclock_location_new (const gchar *name, const gchar *timezone,
-- gfloat latitude, gfloat longitude);
-+ gfloat latitude, gfloat longitude,
-+ const gchar *code);
-
- IntlClockLocation *intlclock_location_new_from_env (IntlClockZoneTable *zones);
-
-@@ -46,5 +51,11 @@ void intlclock_location_set_coords (IntlClockLocation *loc, gfloat latitude, gfl
-
- void intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm);
-
-+gboolean intlclock_location_is_current (IntlClockLocation *loc);
-+gboolean intlclock_location_make_current (IntlClockLocation *loc, GError **error);
-+
-+const gchar *intlclock_location_get_weather_code (IntlClockLocation *loc);
-+WeatherInfo *intlclock_location_get_weather_info (IntlClockLocation *loc);
-+
- G_END_DECLS
- #endif /* __INTLCLOCK_LOCATION_H__ */
-diff --git a/src/intlclock-map.c b/src/intlclock-map.c
-index 2d72975..9ded127 100644
---- a/src/intlclock-map.c
-+++ b/src/intlclock-map.c
-@@ -25,7 +25,7 @@ typedef struct {
- gint height;
-
- GdkPixbuf *stock_map_pixbuf;
-- GdkPixbuf *location_marker_pixbuf;
-+ GdkPixbuf *location_marker_pixbuf[3];
-
- GdkPixbuf *location_map_pixbuf;
-
-@@ -54,6 +54,7 @@ static void intlclock_map_display (IntlClockMap *this);
-
-
- static void intlclock_map_locations_changed (IntlClock *clock, IntlClockMap *this);
-+static void intlclock_map_blink_location (IntlClock *clock, IntlClockLocation *loc, IntlClockMap *this);
- static void intlclock_map_tick (IntlClock *clock, IntlClockMap *this);
-
- #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_MAP_TYPE, IntlClockMapPrivate))
-@@ -69,8 +70,12 @@ intlclock_map_new (IntlClock *clock)
-
- priv->clock = g_object_ref (clock);
-
-- priv->location_marker_pixbuf = rsvg_pixbuf_from_file
-- (INTLCLOCK_ICONDIR "/intlclock-map-location-marker.svg", NULL);
-+ priv->location_marker_pixbuf[0] = gdk_pixbuf_new_from_file
-+ (INTLCLOCK_ICONDIR "/intlclock-map-location-marker.png", NULL);
-+ priv->location_marker_pixbuf[1] = gdk_pixbuf_new_from_file
-+ (INTLCLOCK_ICONDIR "/intlclock-map-location-hilight.png", NULL);
-+ priv->location_marker_pixbuf[2] = gdk_pixbuf_new_from_file
-+ (INTLCLOCK_ICONDIR "/intlclock-map-location-current.png", NULL);
-
- g_signal_connect (G_OBJECT (priv->clock), "tick",
- G_CALLBACK (intlclock_map_tick), this);
-@@ -78,6 +83,12 @@ intlclock_map_new (IntlClock *clock)
- g_signal_connect (G_OBJECT (priv->clock), "locations_changed",
- G_CALLBACK (intlclock_map_locations_changed), this);
-
-+ g_signal_connect (G_OBJECT (priv->clock), "current_timezone_changed",
-+ G_CALLBACK (intlclock_map_locations_changed), this);
-+
-+ g_signal_connect (G_OBJECT (priv->clock), "blink_location",
-+ G_CALLBACK (intlclock_map_blink_location), this);
-+
- intlclock_map_refresh (this);
-
- return this;
-@@ -109,13 +120,16 @@ intlclock_map_init (IntlClockMap *this)
- priv->clock = NULL;
-
- priv->stock_map_pixbuf = NULL;
-- priv->location_marker_pixbuf = NULL;
-+ priv->location_marker_pixbuf[0] = NULL;
-+ priv->location_marker_pixbuf[1] = NULL;
-+ priv->location_marker_pixbuf[2] = NULL;
- }
-
- static void
- intlclock_map_finalize (GObject *g_obj)
- {
- IntlClockMapPrivate *priv = PRIVATE (g_obj);
-+ int i;
-
- g_signal_handlers_disconnect_by_func
- (priv->clock, G_CALLBACK (intlclock_map_tick), g_obj);
-@@ -130,10 +144,12 @@ intlclock_map_finalize (GObject *g_obj)
- priv->stock_map_pixbuf = NULL;
- }
-
-- if (priv->location_marker_pixbuf) {
-- gdk_pixbuf_unref (priv->location_marker_pixbuf);
-- priv->location_marker_pixbuf = NULL;
-- }
-+ for (i = 0; i < 3; i++) {
-+ if (priv->location_marker_pixbuf[i]) {
-+ gdk_pixbuf_unref (priv->location_marker_pixbuf[i]);
-+ priv->location_marker_pixbuf[i] = NULL;
-+ }
-+ }
-
- if (priv->location_map_pixbuf) {
- gdk_pixbuf_unref (priv->location_map_pixbuf);
-@@ -164,12 +180,13 @@ intlclock_map_refresh (IntlClockMap *this)
- IntlClockMapPrivate *priv = PRIVATE (this);
- GtkWidget *widget = GTK_WIDGET (this);
- GtkWidget *parent = gtk_widget_get_parent (widget);
-+ GtkRequisition req;
- gint width;
- gint height;
-
-- gtk_widget_size_request (widget, &(widget->requisition));
-- width = widget->requisition.width;
-- height = widget->requisition.height;
-+ gtk_widget_size_request (widget, &req);
-+ width = req.width;
-+ height = req.height;
-
- if (parent) {
- if (widget->allocation.width != 1) {
-@@ -276,10 +293,10 @@ intlclock_map_size_allocate (GtkWidget *this, GtkAllocation *allocation)
- }
-
- static void
--intlclock_map_mark (IntlClockMap *this, gfloat latitude, gfloat longitude)
-+intlclock_map_mark (IntlClockMap *this, gfloat latitude, gfloat longitude, gint mark)
- {
- IntlClockMapPrivate *priv = PRIVATE (this);
-- GdkPixbuf *marker = priv->location_marker_pixbuf;
-+ GdkPixbuf *marker = priv->location_marker_pixbuf[mark];
- GdkPixbuf *partial = NULL;
-
- int x, y;
-@@ -395,14 +412,22 @@ intlclock_map_mark (IntlClockMap *this, gfloat latitude, gfloat longitude)
- }
-
- static void
--intlclock_map_place_location (IntlClockMap *this, IntlClockLocation *loc)
-+intlclock_map_place_location (IntlClockMap *this, IntlClockLocation *loc, gboolean hilight)
- {
- IntlClockMapPrivate *priv = PRIVATE (this);
- gfloat latitude, longitude;
-+ gint marker;
-
- intlclock_location_get_coords (loc, &latitude, &longitude);
-
-- intlclock_map_mark (this, latitude, longitude);
-+ if (hilight)
-+ marker = 1;
-+ else if (intlclock_location_is_current (loc))
-+ marker = 2;
-+ else
-+ marker = 0;
-+
-+ intlclock_map_mark (this, latitude, longitude, marker);
- }
-
- static void
-@@ -428,7 +453,7 @@ intlclock_map_place_locations (IntlClockMap *this)
- while (locs) {
- loc = INTLCLOCK_LOCATION (locs->data);
-
-- intlclock_map_place_location (this, loc);
-+ intlclock_map_place_location (this, loc, FALSE);
-
- locs = locs->next;
- }
-@@ -633,16 +658,12 @@ intlclock_map_rotate (IntlClockMap *this)
- static void
- intlclock_map_display (IntlClockMap *this)
- {
-- IntlClockMapPrivate *priv = PRIVATE (this);
--
- gtk_widget_queue_draw (GTK_WIDGET (this));
- }
-
- static void
- intlclock_map_locations_changed (IntlClock *clock, IntlClockMap *this)
- {
-- IntlClockMapPrivate *priv = PRIVATE (this);
--
- intlclock_map_place_locations (this);
-
- intlclock_map_render_shadow (this);
-@@ -651,6 +672,49 @@ intlclock_map_locations_changed (IntlClock *clock, IntlClockMap *this)
- intlclock_map_display (this);
- }
-
-+typedef struct {
-+ IntlClockMap *map;
-+ IntlClockLocation *location;
-+ int count;
-+} BlinkData;
-+
-+static gboolean
-+highlight (gpointer user_data)
-+{
-+ BlinkData *data = user_data;
-+
-+ if (data->count == 6) {
-+ g_free (data);
-+ return FALSE;
-+ }
-+
-+ if (data->count % 2 == 0)
-+ intlclock_map_place_location (data->map, data->location, TRUE);
-+ else
-+ intlclock_map_place_locations (data->map);
-+ intlclock_map_render_shadow (data->map);
-+ intlclock_map_rotate (data->map);
-+ intlclock_map_display (data->map);
-+
-+ data->count++;
-+
-+ return TRUE;
-+}
-+
-+static void
-+intlclock_map_blink_location (IntlClock *clock, IntlClockLocation *loc, IntlClockMap *this)
-+{
-+ BlinkData *data;
-+
-+ data = g_new0 (BlinkData, 1);
-+ data->map = this;
-+ data->location = loc;
-+
-+ highlight (data);
-+
-+ g_timeout_add (300, highlight, data);
-+}
-+
- static gboolean
- intlclock_map_needs_refresh (IntlClockMap *this)
- {
-diff --git a/src/intlclock-marshallers.c b/src/intlclock-marshallers.c
-deleted file mode 100644
-index 8f01ab8..0000000
---- a/src/intlclock-marshallers.c
-+++ /dev/null
-@@ -1,51 +0,0 @@
--
--#include <glib-object.h>
--
--
--#ifdef G_ENABLE_DEBUG
--#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
--#define g_marshal_value_peek_char(v) g_value_get_char (v)
--#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
--#define g_marshal_value_peek_int(v) g_value_get_int (v)
--#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
--#define g_marshal_value_peek_long(v) g_value_get_long (v)
--#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
--#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
--#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
--#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
--#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
--#define g_marshal_value_peek_float(v) g_value_get_float (v)
--#define g_marshal_value_peek_double(v) g_value_get_double (v)
--#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
--#define g_marshal_value_peek_param(v) g_value_get_param (v)
--#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
--#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
--#define g_marshal_value_peek_object(v) g_value_get_object (v)
--#else /* !G_ENABLE_DEBUG */
--/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
-- * Do not access GValues directly in your code. Instead, use the
-- * g_value_get_*() functions
-- */
--#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
--#define g_marshal_value_peek_char(v) (v)->data[0].v_int
--#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
--#define g_marshal_value_peek_int(v) (v)->data[0].v_int
--#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
--#define g_marshal_value_peek_long(v) (v)->data[0].v_long
--#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
--#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
--#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
--#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
--#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
--#define g_marshal_value_peek_float(v) (v)->data[0].v_float
--#define g_marshal_value_peek_double(v) (v)->data[0].v_double
--#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
--#endif /* !G_ENABLE_DEBUG */
--
--
--/* VOID:VOID (intlclock-marshallers.list:1) */
--
-diff --git a/src/intlclock-marshallers.h b/src/intlclock-marshallers.h
-deleted file mode 100644
-index c022a3e..0000000
---- a/src/intlclock-marshallers.h
-+++ /dev/null
-@@ -1,15 +0,0 @@
--
--#ifndef ___intlclock_marshal_MARSHAL_H__
--#define ___intlclock_marshal_MARSHAL_H__
--
--#include <glib-object.h>
--
--G_BEGIN_DECLS
--
--/* VOID:VOID (intlclock-marshallers.list:1) */
--#define _intlclock_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
--
--G_END_DECLS
--
--#endif /* ___intlclock_marshal_MARSHAL_H__ */
--
-diff --git a/src/intlclock-marshallers.list b/src/intlclock-marshallers.list
-index 5b76282..e737cac 100644
---- a/src/intlclock-marshallers.list
-+++ b/src/intlclock-marshallers.list
-@@ -1 +1,3 @@
- VOID:VOID
-+VOID:OBJECT
-+VOID:POINTER
-diff --git a/src/intlclock-sunpos.c b/src/intlclock-sunpos.c
-index 942617b..89d4cc1 100644
---- a/src/intlclock-sunpos.c
-+++ b/src/intlclock-sunpos.c
-@@ -1,348 +1,196 @@
- /*
-- * sunpos.c
-- * kirk johnson
-- * july 1993
-+ * Copyright (C) 2007 Red Hat, Inc.
- *
-- * includes revisions from Frank T. Solensky, february 1999
-+ * 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.
- *
-- * code for calculating the position on the earth's surface for which
-- * the sun is directly overhead (adapted from _practical astronomy
-- * with your calculator, third edition_, peter duffett-smith,
-- * cambridge university press, 1988.)
-+ * 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.
- *
-- * Copyright (C) 1989, 1990, 1993-1995, 1999 Kirk Lauritz Johnson
-+ * 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.
- *
-- * Parts of the source code (as marked) are:
-- * Copyright (C) 1989, 1990, 1991 by Jim Frost
-- * Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
-- *
-- * Permission to use, copy, modify and freely distribute xearth for
-- * non-commercial and not-for-profit purposes is hereby granted
-- * without fee, provided that both the above copyright notice and this
-- * permission notice appear in all copies and in supporting
-- * documentation.
-- *
-- * Unisys Corporation holds worldwide patent rights on the Lempel Zev
-- * Welch (LZW) compression technique employed in the CompuServe GIF
-- * image file format as well as in other formats. Unisys has made it
-- * clear, however, that it does not require licensing or fees to be
-- * paid for freely distributed, non-commercial applications (such as
-- * xearth) that employ LZW/GIF technology. Those wishing further
-- * information about licensing the LZW patent should contact Unisys
-- * directly at (lzw_info@unisys.com) or by writing to
-- *
-- * Unisys Corporation
-- * Welch Licensing Department
-- * M/S-C1SW19
-- * P.O. Box 500
-- * Blue Bell, PA 19424
-- *
-- * The author makes no representations about the suitability of this
-- * software for any purpose. It is provided "as is" without express or
-- * implied warranty.
-- *
-- * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
-- * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ * Authors:
-+ * Jonathan Blandford <jrb@redhat.com>
-+ * Matthias Clasen <mclasen@redhat.com>
- */
--
--#include <assert.h>
--#include <math.h>
-+
- #include <time.h>
-+#include <gtk/gtk.h>
-+#include <math.h>
-
--#include "intlclock-sunpos.h"
--
--#define TWOPI (2*M_PI)
--#define DegsToRads(x) ((x)*(TWOPI/360))
--
--/*
-- * the epoch upon which these astronomical calculations are based is
-- * 1990 january 0.0, 631065600 seconds since the beginning of the
-- * "unix epoch" (00:00:00 GMT, Jan. 1, 1970)
-- *
-- * given a number of seconds since the start of the unix epoch,
-- * DaysSinceEpoch() computes the number of days since the start of the
-- * astronomical epoch (1990 january 0.0)
-- */
--
--#define EpochStart (631065600)
--#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
--
--/*
-- * assuming the apparent orbit of the sun about the earth is circular,
-- * the rate at which the orbit progresses is given by RadsPerDay --
-- * TWOPI radians per orbit divided by 365.242191 days per year:
-- */
--
--#define RadsPerDay (TWOPI/365.242191)
--
--/*
-- * details of sun's apparent orbit at epoch 1990.0 (after
-- * duffett-smith, table 6, section 46)
-- *
-- * Epsilon_g (ecliptic longitude at epoch 1990.0) 279.403303 degrees
-- * OmegaBar_g (ecliptic longitude of perigee) 282.768422 degrees
-- * Eccentricity (eccentricity of orbit) 0.016713
-+/* Calculated with the methods and figures from "Practical Astronomy With Your
-+ * Calculator, version 3" by Peter Duffet-Smith.
- */
-+/* Table 6. Details of the Sun's apparent orbit at epoch 1990.0 */
-
--#define Epsilon_g (DegsToRads(279.403303))
--#define OmegaBar_g (DegsToRads(282.768422))
--#define Eccentricity (0.016713)
-+#define EPOCH 2447891.5 /* days */ /* epoch 1990 */
-+#define UNIX_EPOCH 2440586.5 /* days */ /* epoch 1970 */
-+#define EPSILON_G 279.403303 /* degrees */ /* ecliptic longitude at epoch 1990.0 */
-+#define MU_G 282.768422 /* degrees */ /* ecliptic longitude at perigree */
-+#define ECCENTRICITY 0.016713 /* eccentricity of orbit */
-+#define R_0 149598500 /* km */ /* semi-major access */
-+#define THETA_0 0.533128 /* degrees */ /* angular diameter at r = r_0 */
-+#define MEAN_OBLIQUITY 23.440592 /* degrees */ /* mean obliquity of earths axis at epoch 1990.0 */
-
--/*
-- * MeanObliquity gives the mean obliquity of the earth's axis at epoch
-- * 1990.0 (computed as 23.440592 degrees according to the method given
-- * in duffett-smith, section 27)
-- */
--#define MeanObliquity (23.440592*(TWOPI/360))
-+#define NORMALIZE(x) \
-+ while (x>360) x-=360; while (x<0) x+= 360;
-
--/*
-- * Lunar parameters, epoch January 0, 1990.0
-- */
--#define MoonMeanLongitude DegsToRads(318.351648)
--#define MoonMeanLongitudePerigee DegsToRads( 36.340410)
--#define MoonMeanLongitudeNode DegsToRads(318.510107)
--#define MoonInclination DegsToRads( 5.145396)
-+#define DEG_TO_RADS(x) \
-+ (x * G_PI/180.0)
-
--#define SideralMonth (27.3217)
-+#define RADS_TO_DEG(x) \
-+ (x * 180.0/G_PI)
-
--/*
-- * Force an angular value into the range [-PI, +PI]
-+/* Calculate number of days since 4713BC.
- */
--#define Normalize(x) \
-- do { \
-- if ((x) < -M_PI) \
-- do (x) += TWOPI; while ((x) < -M_PI); \
-- else if ((x) > M_PI) \
-- do (x) -= TWOPI; while ((x) > M_PI); \
-- } while (0)
--
--static double solve_keplers_equation (double);
--static double mean_sun (double);
--static double sun_ecliptic_longitude (time_t);
--static void ecliptic_to_equatorial (double, double, double *, double *);
--static double julian_date (int, int, int);
--static double GST (time_t);
--
--/*
-- * solve Kepler's equation via Newton's method
-- * (after duffett-smith, section 47)
-- */
--static double solve_keplers_equation(M)
-- double M;
-+static gdouble
-+unix_time_to_julian_date (gint unix_time)
- {
-- double E;
-- double delta;
--
-- E = M;
-- while (1)
-- {
-- delta = E - Eccentricity*sin(E) - M;
-- if (fabs(delta) <= 1e-10) break;
-- E -= delta / (1 - Eccentricity*cos(E));
-- }
--
-- return E;
-+ return UNIX_EPOCH + (double) unix_time / (60 * 60 * 24);
- }
-
-+/* Finds an iterative solution for [ E - e sin (E) = M ] for values of e less
-+ than 0.1. Page 90 */
-
--/*
-- * Calculate the position of the mean sun: where the sun would
-- * be if the earth's orbit were circular instead of ellipictal.
-- */
-+#define ERROR_ACCURACY 1e-6 /* radians */
-
--static double mean_sun (D)
-- double D; /* days since ephemeris epoch */
-+static gdouble
-+solve_keplers_equation (gdouble e,
-+ gdouble M)
- {
-- double N, M;
-+ gdouble d, E;
-
-- N = RadsPerDay * D;
-- N = fmod(N, TWOPI);
-- if (N < 0) N += TWOPI;
-+ /* start with an initial estimate */
-+ E = M;
-+
-+ d = E - e * sin (E) - M;
-+
-+ while (ABS (d) > ERROR_ACCURACY)
-+ {
-+ E = E - (d / (1 - e * cos (E)));
-+ d = E - e * sin (E) - M;
-+ }
-
-- M = N + Epsilon_g - OmegaBar_g;
-- if (M < 0) M += TWOPI;
-- return M;
-+ return E;
- }
-
--/*
-- * compute ecliptic longitude of sun (in radians)
-- * (after duffett-smith, section 47)
-- */
--static double sun_ecliptic_longitude(ssue)
-- time_t ssue; /* seconds since unix epoch */
-+ /* convert the ecliptic longitude to right ascension and declination. Section 27. */
-+static void
-+ecliptic_to_equatorial (gdouble lambda,
-+ gdouble beta,
-+ gdouble *ra,
-+ gdouble *dec)
- {
-- double D;
-- double M_sun, E;
-- double v;
-+ gdouble cos_mo;
-+ gdouble sin_mo;
-
-- D = DaysSinceEpoch(ssue);
-- M_sun = mean_sun(D);
-+ g_assert (ra != NULL);
-+ g_assert (dec != NULL);
-
-- E = solve_keplers_equation(M_sun);
-- v = 2 * atan(sqrt((1+Eccentricity)/(1-Eccentricity)) * tan(E/2));
-+ sin_mo = sin (DEG_TO_RADS (MEAN_OBLIQUITY));
-+ cos_mo = cos (DEG_TO_RADS (MEAN_OBLIQUITY));
-
-- return (v + OmegaBar_g);
-+ *ra = atan2 (sin (lambda) * cos_mo - tan (beta) * sin_mo, cos (lambda));
-+ *dec = asin (sin (beta) * cos_mo + cos (beta) * sin_mo * sin (lambda));
- }
-
--
--/*
-- * convert from ecliptic to equatorial coordinates
-- * (after duffett-smith, section 27)
-- */
--static void ecliptic_to_equatorial(lambda, beta, alpha, delta)
-- double lambda; /* ecliptic longitude */
-- double beta; /* ecliptic latitude */
-- double *alpha; /* (return) right ascension */
-- double *delta; /* (return) declination */
-+/* calculate GST. Section 12 */
-+static gdouble
-+greenwich_sidereal_time (gdouble unix_time)
- {
-- double sin_e, cos_e;
-+ gdouble u, JD, T, T0, UT;
-
-- sin_e = sin(MeanObliquity);
-- cos_e = cos(MeanObliquity);
-+ u = fmod (unix_time, 24 * 60 * 60);
-+ JD = unix_time_to_julian_date (unix_time - u);
-+ T = (JD - 2451545) / 36525;
-+ T0 = 6.697374558 + (2400.051336 * T) + (0.000025862 * T * T);
-+ T0 = fmod (T0, 24);
-+ UT = u / (60 * 60);
-+ T0 = T0 + UT * 1.002737909;
-+ T0 = fmod (T0, 24);
-
-- *alpha = atan2(sin(lambda)*cos_e - tan(beta)*sin_e, cos(lambda));
-- *delta = asin(sin(beta)*cos_e + cos(beta)*sin_e*sin(lambda));
-+ return T0;
- }
-
--
--/*
-- * computing julian dates (assuming gregorian calendar, thus this is
-- * only valid for dates of 1582 oct 15 or later)
-- * (after duffett-smith, section 4)
-- */
--static double julian_date(y, m, d)
-- int y; /* year (e.g. 19xx) */
-- int m; /* month (jan=1, feb=2, ...) */
-- int d; /* day of month */
-+/* Calculate the position of the sun at a given time. pages 89-91 */
-+void
-+sun_position (gint unix_time, gdouble *lat, gdouble *lon)
- {
-- int A, B, C, D;
-- double JD;
-+ gdouble jd, D, N, M, E, x, v, lambda;
-+ gdouble ra, dec;
-+ jd = unix_time_to_julian_date (unix_time);
-
-- /* lazy test to ensure gregorian calendar */
-- assert(y >= 1583);
-+ /* Calculate number of days since the epoch */
-+ D = jd - EPOCH;
-
-- if ((m == 1) || (m == 2))
-- {
-- y -= 1;
-- m += 12;
-- }
-+ N = D*360/365.242191;
-
-- A = y / 100;
-- B = 2 - A + (A / 4);
-- C = 365.25 * y;
-- D = 30.6001 * (m + 1);
-+ /* normalize to 0 - 360 degrees */
-+ NORMALIZE (N);
-
-- JD = B + C + D + d + 1720994.5;
-+ /* Step 4: */
-+ M = N + EPSILON_G - MU_G;
-+ NORMALIZE (M);
-
-- return JD;
--}
--
--
--/*
-- * compute greenwich mean sidereal time (GST) corresponding to a given
-- * number of seconds since the unix epoch
-- * (after duffett-smith, section 12)
-- */
--static double GST(ssue)
-- time_t ssue; /* seconds since unix epoch */
--{
-- double JD;
-- double T, T0;
-- double UT;
-- struct tm *tm;
-+ /* Step 5: convert to radians */
-+ M = DEG_TO_RADS (M);
-
-- tm = gmtime(&ssue);
-+ /* Step 6: */
-+ E = solve_keplers_equation (ECCENTRICITY, M);
-
-- JD = julian_date(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
-- T = (JD - 2451545) / 36525;
-+ /* Step 7: */
-+ x = sqrt ((1 + ECCENTRICITY)/(1 - ECCENTRICITY)) * tan (E/2);
-
-- T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
-+ /* Step 8, 9 */
-+ v = 2 * RADS_TO_DEG (atan (x));
-+ NORMALIZE (v);
-
-- T0 = fmod(T0, 24.0);
-- if (T0 < 0) T0 += 24;
-+ /* Step 10 */
-+ lambda = v + MU_G;
-+ NORMALIZE (lambda);
-
-- UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
-+ /* convert the ecliptic longitude to right ascension and declination */
-+ ecliptic_to_equatorial (DEG_TO_RADS (lambda), 0.0, &ra, &dec);
-
-- T0 += UT * 1.002737909;
-- T0 = fmod(T0, 24.0);
-- if (T0 < 0) T0 += 24;
-+ ra = ra - (G_PI/12) * greenwich_sidereal_time (unix_time);
-+ ra = RADS_TO_DEG (ra);
-+ dec = RADS_TO_DEG (dec);
-+ NORMALIZE (ra);
-+ NORMALIZE (dec);
-
-- return T0;
-+ *lat = dec;
-+ *lon = ra;
- }
-
-
--/*
-- * given a particular time (expressed in seconds since the unix
-- * epoch), compute position on the earth (lat, lon) such that sun is
-- * directly overhead.
-- */
--void sun_position(ssue, lat, lon)
-- time_t ssue; /* seconds since unix epoch */
-- double *lat; /* (return) latitude */
-- double *lon; /* (return) longitude */
-+#if 0
-+int
-+main (int argc, char *argv[])
- {
-- double lambda;
-- double alpha, delta;
-- double tmp;
-+ gint i;
-+ gint now;
-+ GTimeVal timeval;
-+ gdouble lat, lon;
-
-- lambda = sun_ecliptic_longitude(ssue);
-- ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta);
-+ gtk_init (&argc, &argv);
-
-- tmp = alpha - (TWOPI/24)*GST(ssue);
-- Normalize(tmp);
-- *lon = tmp * (360/TWOPI);
-- *lat = delta * (360/TWOPI);
--}
-+ g_get_current_time (&timeval);
-+ now = timeval.tv_sec;
-
-+ for (i = 0; i < now; i += 15 * 60)
-+ {
-+ sun_position (i, &lat, &lon);
-+ g_print ("%d: %f %f\n", lat, lon);
-+ }
-
--/*
-- * given a particular time (expressed in seconds since the unix
-- * epoch), compute position on the earth (lat, lon) such that the
-- * moon is directly overhead.
-- *
-- * Based on duffett-smith **2nd ed** section 61; combines some steps
-- * into single expressions to reduce the number of extra variables.
-- */
--void moon_position(ssue, lat, lon)
-- time_t ssue; /* seconds since unix epoch */
-- double *lat; /* (return) latitude */
-- double *lon; /* (return) longitude */
--{
-- double lambda, beta;
-- double D, L, Ms, Mm, N, Ev, Ae, Ec, alpha, delta;
--
-- D = DaysSinceEpoch(ssue);
-- lambda = sun_ecliptic_longitude(ssue);
-- Ms = mean_sun(D);
--
-- L = fmod(D/SideralMonth, 1.0)*TWOPI + MoonMeanLongitude;
-- Normalize(L);
-- Mm = L - DegsToRads(0.1114041*D) - MoonMeanLongitudePerigee;
-- Normalize(Mm);
-- N = MoonMeanLongitudeNode - DegsToRads(0.0529539*D);
-- Normalize(N);
-- Ev = DegsToRads(1.2739) * sin(2.0*(L-lambda)-Mm);
-- Ae = DegsToRads(0.1858) * sin(Ms);
-- Mm += Ev - Ae - DegsToRads(0.37)*sin(Ms);
-- Ec = DegsToRads(6.2886) * sin(Mm);
-- L += Ev + Ec - Ae + DegsToRads(0.214) * sin(2.0*Mm);
-- L += DegsToRads(0.6583) * sin(2.0*(L-lambda));
-- N -= DegsToRads(0.16) * sin(Ms);
--
-- L -= N;
-- lambda =(fabs(cos(L)) < 1e-12) ?
-- (N + sin(L) * cos(MoonInclination) * M_PI/2) :
-- (N + atan2(sin(L) * cos(MoonInclination), cos(L)));
-- Normalize(lambda);
-- beta = asin(sin(L) * sin(MoonInclination));
-- ecliptic_to_equatorial(lambda, beta, &alpha, &delta);
-- alpha -= (TWOPI/24)*GST(ssue);
-- Normalize(alpha);
-- *lon = alpha * (360/TWOPI);
-- *lat = delta * (360/TWOPI);
-+ return 0;
- }
-+
-+#endif
-diff --git a/src/intlclock-ui.c b/src/intlclock-ui.c
-index f51e4de..a856aef 100644
---- a/src/intlclock-ui.c
-+++ b/src/intlclock-ui.c
-@@ -14,6 +14,7 @@
- #include <libgnome/gnome-i18n.h>
- #include <locale.h>
- #include <math.h>
-+#include <time.h>
- #include <panel-applet-gconf.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -26,18 +27,17 @@
- #include "intlclock-map.h"
- #include "intlclock-zoneinfo.h"
- #include "intlclock-zonetable.h"
-+#include "set-timezone.h"
-
- G_DEFINE_TYPE (IntlClockUI, intlclock_ui, G_TYPE_OBJECT)
-
- /* GConf keys for compatibility with the older GNOME clock */
--#define N_GCONF_PREFS 7
-+#define N_GCONF_PREFS 5
- static const char *KEY_CITIES = "cities";
- static const char *KEY_FORMAT = "format";
- static const char *KEY_SHOW_SECONDS = "show_seconds";
- static const char *KEY_SHOW_DATE = "show_date";
- static const char *KEY_SHOW_WEEK = "show_week_numbers";
--static const char *KEY_SHOW_LOCATIONS = "show_locations";
--static const char *KEY_SHOW_MAP = "show_map";
-
- /* Needs to match the indices in the combo */
- typedef enum {
-@@ -78,12 +78,14 @@ typedef struct {
- GtkWidget *panel_box;
- GtkWidget *panel_button;
- GtkWidget *panel_label;
-+ GtkWidget *panel_weather_icon;
-
- GtkTooltips *panel_tips;
-
- GtkWidget *panel_button_popup;
-
- GtkWidget *clock_vbox;
-+ GtkSizeGroup *clock_group;
-
- GtkWidget *main_section;
- GtkWidget *clock_calendar;
-@@ -97,12 +99,20 @@ typedef struct {
-
- GtkListStore *cities_store;
-
-- gboolean show_locations;
-- gboolean show_map;
--
- GtkWidget *prefs_window;
- GtkTreeView *prefs_locations;
-
-+ GtkWidget *prefs_location_add_button;
-+ GtkWidget *prefs_location_edit_button;
-+ GtkWidget *prefs_location_remove_button;
-+
-+ GtkWidget *hours_spin;
-+ GtkWidget *minutes_spin;
-+ GtkWidget *seconds_spin;
-+ GtkWidget *calendar;
-+ GtkWidget *current_time_label;
-+ GtkWidget *set_time_button;
-+
- gboolean format_12hr;
- gboolean format_show_seconds;
- gboolean format_show_date;
-@@ -118,9 +128,6 @@ static gboolean update_panel_label (gpointer this);
- static void setup_gconf (IntlClockUI *this);
- static void load_gconf_settings (IntlClockUI *this);
-
--static void bonobo_run_time_configuration (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname);
- static void bonobo_display_properties_dialog (BonoboUIComponent *uic,
- IntlClockUI *this,
- const gchar *verbname);
-@@ -141,9 +148,8 @@ static void position_popup_window (IntlClockUI *this,
- GtkWindow *window,
- GtkWidget *origin);
-
-+static void display_prefs_window (IntlClockUI *this, gboolean locations);
- static void display_prefs_window_cb (GtkButton *button, gpointer this);
--static void run_time_configuration (IntlClockUI *this);
--static void run_time_configuration_cb (GtkButton *button, gpointer this);
- static void run_prefs_locations_add (GtkButton *button, gpointer this);
- static void run_prefs_locations_edit (GtkButton *button, gpointer this);
- static void run_prefs_locations_remove (GtkButton *button, gpointer this);
-@@ -162,7 +168,6 @@ static void zone_combo_changed (GtkComboBox *widget, gpointer this);
-
- static const BonoboUIVerb intlclock_menu_verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("IntlClockPreferences", bonobo_display_properties_dialog),
-- BONOBO_UI_UNSAFE_VERB ("IntlClockConfig", bonobo_run_time_configuration),
- BONOBO_UI_VERB_END
- };
-
-@@ -206,7 +211,9 @@ intlclock_ui_reset_timeout (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-
-- if (GTK_WIDGET_VISIBLE (priv->events_window) || priv->format_show_seconds) {
-+ if (GTK_WIDGET_VISIBLE (priv->events_window) ||
-+ (priv->prefs_window && GTK_WIDGET_VISIBLE (priv->prefs_window)) ||
-+ priv->format_show_seconds) {
- intlclock_set_tick_timeout (INTLCLOCK (priv->clock), 1);
- } else {
- intlclock_set_tick_timeout (INTLCLOCK (priv->clock), 60);
-@@ -435,22 +442,20 @@ intlclock_window_expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer u
-
- /* draw map pane background */
-
-- if (priv->show_map) {
-- cairo_rectangle (
-- cr,
-- priv->map_section->allocation.x + 0.5,
-- priv->map_section->allocation.y + 0.5,
-- priv->map_section->allocation.width - 1,
-- priv->map_section->allocation.height - 1);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->bg [GTK_STATE_NORMAL].red / 65535.0,
-- widget->style->bg [GTK_STATE_NORMAL].green / 65535.0,
-- widget->style->bg [GTK_STATE_NORMAL].blue / 65535.0);
--
-- cairo_fill (cr);
-- }
-+ cairo_rectangle (
-+ cr,
-+ priv->map_section->allocation.x + 0.5,
-+ priv->map_section->allocation.y + 0.5,
-+ priv->map_section->allocation.width - 1,
-+ priv->map_section->allocation.height - 1);
-+
-+ cairo_set_source_rgb (
-+ cr,
-+ widget->style->bg [GTK_STATE_NORMAL].red / 65535.0,
-+ widget->style->bg [GTK_STATE_NORMAL].green / 65535.0,
-+ widget->style->bg [GTK_STATE_NORMAL].blue / 65535.0);
-+
-+ cairo_fill (cr);
-
- /* draw internal window outline */
-
-@@ -469,47 +474,43 @@ intlclock_window_expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer u
-
- /* draw map/cities pane separator */
-
-- if (priv->show_map) {
-- cairo_move_to (
-- cr,
-- priv->map_section->allocation.x + 0.5,
-- priv->map_section->allocation.y + priv->map_section->allocation.height - 0.5);
-+ cairo_move_to (
-+ cr,
-+ priv->map_section->allocation.x + 0.5,
-+ priv->map_section->allocation.y + priv->map_section->allocation.height - 0.5);
-
-- cairo_line_to (
-- cr,
-- priv->map_section->allocation.x + priv->map_section->allocation.width - 0.5,
-- priv->map_section->allocation.y + priv->map_section->allocation.height - 0.5);
-+ cairo_line_to (
-+ cr,
-+ priv->map_section->allocation.x + priv->map_section->allocation.width - 0.5,
-+ priv->map_section->allocation.y + priv->map_section->allocation.height - 0.5);
-
-- cairo_set_source_rgb (
-- cr,
-- widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
-+ cairo_set_source_rgb (
-+ cr,
-+ widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-+ widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-+ widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
-
-- cairo_stroke (cr);
-- }
-+ cairo_stroke (cr);
-
- /* draw cities/main pane separator */
-
-- if (priv->show_locations) {
-- cairo_move_to (
-- cr,
-- priv->cities_section->allocation.x + 0.5,
-- priv->cities_section->allocation.y + priv->cities_section->allocation.height - 0.5);
-+ cairo_move_to (
-+ cr,
-+ priv->cities_section->allocation.x + 0.5,
-+ priv->cities_section->allocation.y + priv->cities_section->allocation.height - 0.5);
-
-- cairo_line_to (
-- cr,
-- priv->cities_section->allocation.x + priv->cities_section->allocation.width - 0.5,
-- priv->cities_section->allocation.y + priv->cities_section->allocation.height - 0.5);
-+ cairo_line_to (
-+ cr,
-+ priv->cities_section->allocation.x + priv->cities_section->allocation.width - 0.5,
-+ priv->cities_section->allocation.y + priv->cities_section->allocation.height - 0.5);
-
-- cairo_set_source_rgb (
-- cr,
-- widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
-+ cairo_set_source_rgb (
-+ cr,
-+ widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-+ widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-+ widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
-
-- cairo_stroke (cr);
-- }
-+ cairo_stroke (cr);
-
- cairo_destroy (cr);
-
-@@ -532,7 +533,6 @@ intlclock_ui_locations_changed (IntlClock *clock, IntlClockUI *this)
- IntlClockUIPrivate *priv = PRIVATE (this);
-
- create_cities_section (this);
-- intlclock_map_refresh (INTLCLOCK_MAP (priv->map_widget));
- }
-
- static gboolean
-@@ -550,12 +550,20 @@ update_panel_label (gpointer this)
- time (&now_t);
- localtime_r (&now_t, &now);
-
-+ if (priv->current_time_label &&
-+ GTK_WIDGET_VISIBLE (priv->current_time_label)) {
-+ date = intlclock_format_time (priv->clock, &now,
-+ FALSE, FALSE, TRUE,
-+ FALSE, FALSE, NULL, TRUE);
-+ gtk_label_set_markup (GTK_LABEL (priv->current_time_label), date);
-+ g_free (date);
-+ }
-+
- date = intlclock_format_time (priv->clock, &now,
- priv->format_show_date,
- priv->format_12hr,
- priv->format_show_seconds,
- FALSE, priv->format_show_date, NULL, TRUE);
--
- gtk_label_set_markup (GTK_LABEL (priv->panel_label), date);
- g_free (date);
-
-@@ -583,6 +591,7 @@ create_panel_buttons (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
- PanelAppletOrient orient;
-+ GtkWidget *box;
-
- orient = panel_applet_get_orient (priv->panel_applet);
-
-@@ -590,13 +599,16 @@ create_panel_buttons (IntlClockUI *this)
- case PANEL_APPLET_ORIENT_UP:
- case PANEL_APPLET_ORIENT_DOWN:
- priv->panel_box = gtk_hbox_new (FALSE, 0);
-+ box = gtk_hbox_new (FALSE, 6);
- break;
- case PANEL_APPLET_ORIENT_RIGHT:
- case PANEL_APPLET_ORIENT_LEFT:
- priv->panel_box = gtk_vbox_new (FALSE, 0);
-+ box = gtk_vbox_new (FALSE, 6);
- break;
- }
- priv->panel_label = gtk_label_new (NULL);
-+ priv->panel_weather_icon = gtk_image_new ();
- priv->panel_button = gtk_toggle_button_new ();
- priv->panel_tips = gtk_tooltips_new ();
-
-@@ -626,8 +638,9 @@ create_panel_buttons (IntlClockUI *this)
- gtk_button_set_relief (GTK_BUTTON (priv->panel_button),
- GTK_RELIEF_NONE);
-
-- gtk_container_add (GTK_CONTAINER (priv->panel_button),
-- priv->panel_label);
-+ gtk_container_add (GTK_CONTAINER (priv->panel_button), box);
-+ gtk_container_add (GTK_CONTAINER (box), priv->panel_weather_icon);
-+ gtk_container_add (GTK_CONTAINER (box), priv->panel_label);
-
- g_signal_connect (
- G_OBJECT (priv->panel_button), "clicked",
-@@ -655,12 +668,13 @@ create_panel_buttons (IntlClockUI *this)
- );
-
- gtk_widget_show (priv->panel_label);
-+ gtk_widget_show (priv->panel_weather_icon);
-+ gtk_widget_show (box);
-
- gtk_box_pack_start (GTK_BOX (priv->panel_box), priv->panel_button,
- FALSE, FALSE, 0);
-
-- gtk_container_add (GTK_CONTAINER (priv->panel_applet),
-- priv->panel_box);
-+ gtk_container_add (GTK_CONTAINER (priv->panel_applet), priv->panel_box);
-
- gtk_widget_show_all (priv->panel_box);
- }
-@@ -671,10 +685,16 @@ intlclock_ui_change_orient (PanelApplet *applet,
- IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- if (GTK_IS_WIDGET (priv->panel_box))
-- gtk_widget_destroy (priv->panel_box);
-+ GdkPixbuf *pixbuf = NULL;
-+
-+ if (GTK_IS_WIDGET (priv->panel_box)) {
-+ pixbuf = g_object_ref (gtk_image_get_pixbuf (GTK_IMAGE (priv->panel_weather_icon)));
-+ gtk_widget_destroy (priv->panel_box);
-+ }
- create_panel_buttons (this);
-+ intlclock_ui_update_weather_icon (this, pixbuf);
-+ if (pixbuf)
-+ g_object_unref (pixbuf);
- }
-
- static void
-@@ -714,7 +734,7 @@ create_events_window (IntlClockUI *this)
- IntlClockUIPrivate *priv = PRIVATE (this);
-
- priv->events_window =
-- GTK_WIDGET (intlclock_events_popup_new (priv->clock, priv->panel_applet));
-+ GTK_WIDGET (intlclock_events_popup_new (priv->clock, priv->panel_applet, this));
-
- g_signal_connect (G_OBJECT (priv->events_window), "size-allocate",
- G_CALLBACK (intlclock_events_window_size_allocate_cb), this);
-@@ -723,17 +743,35 @@ create_events_window (IntlClockUI *this)
- }
-
- static void
-+add_to_group (GtkWidget *child, gpointer data)
-+{
-+ GtkSizeGroup *group = data;
-+
-+ gtk_size_group_add_widget (group, child);
-+}
-+
-+static void
- create_clock_window (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
- GtkSettings *settings;
- GtkStyle *style;
-+ GtkWidget *clock_container;
-
-- priv->clock_vbox = intlclock_events_popup_get_clock_container
-+ clock_container = intlclock_events_popup_get_clock_container
- (INTLCLOCK_EVENTS_POPUP (priv->events_window));
-- gtk_widget_show (priv->clock_vbox);
--}
-+ gtk_widget_show (clock_container);
-
-+ priv->clock_vbox = gtk_vbox_new (FALSE, 6);
-+ gtk_container_add (GTK_CONTAINER (clock_container), priv->clock_vbox);
-+
-+ priv->clock_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-+ gtk_size_group_set_ignore_hidden (priv->clock_group, FALSE);
-+
-+ gtk_container_foreach (GTK_CONTAINER (clock_container),
-+ (GtkCallback)add_to_group,
-+ priv->clock_group);
-+}
- static void
- create_main_section (IntlClockUI *this)
- {
-@@ -750,7 +788,6 @@ create_main_section (IntlClockUI *this)
- MAIN_SECTION_PADDING);
- gtk_box_pack_end (GTK_BOX (priv->clock_vbox),
- priv->main_section, FALSE, FALSE, 0);
--
- } else {
- gtk_container_foreach (GTK_CONTAINER (priv->main_section),
- (GtkCallback)gtk_widget_destroy,
-@@ -824,7 +861,7 @@ create_cities_section (IntlClockUI *this)
- IntlClockUIPrivate *priv = PRIVATE (this);
- GList *node;
- IntlClockLocationTile *city;
-- GtkWidget *header, *subheader, *image;;
-+ GtkWidget *header, *subheader, *image;
- GList *cities;
-
- if (priv->cities_section) {
-@@ -832,12 +869,8 @@ create_cities_section (IntlClockUI *this)
- priv->cities_section = NULL;
- }
-
-- if (!priv->show_locations) {
-- return;
-- }
--
- priv->cities_section = gtk_vbox_new (FALSE, 6);
-- gtk_container_set_border_width (GTK_CONTAINER (priv->cities_section), 8);
-+ gtk_container_set_border_width (GTK_CONTAINER (priv->cities_section), 0);
-
- cities = intlclock_get_locations (priv->clock);
- if (g_list_length (cities) == 0) {
-@@ -884,10 +917,6 @@ create_map_section (IntlClockUI *this)
- priv->map_widget = NULL;
- }
-
-- if (!priv->show_map) {
-- return;
-- }
--
- map = intlclock_map_new (priv->clock);
-
- priv->map_section = gtk_alignment_new (0, 0, 1, 1);
-@@ -895,11 +924,10 @@ create_map_section (IntlClockUI *this)
-
- gtk_container_add (GTK_CONTAINER (priv->map_section), priv->map_widget);
-
-- gtk_box_pack_start (GTK_BOX (priv->clock_vbox),
-- priv->map_section, FALSE, FALSE, 0);
--
- gtk_alignment_set_padding (GTK_ALIGNMENT (priv->map_section),
- 1, 1, 1, 1);
-+ gtk_box_pack_start (GTK_BOX (priv->clock_vbox),
-+ priv->map_section, FALSE, FALSE, 0);
-
- gtk_widget_show (priv->map_widget);
- gtk_widget_show (priv->map_section);
-@@ -959,6 +987,8 @@ intlclock_prefs_hide (GtkWidget *widget, IntlClockUI *this)
-
- gtk_tree_selection_unselect_all
- (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)));
-+
-+ intlclock_ui_reset_timeout (this);
- }
-
- static gboolean
-@@ -1057,28 +1087,6 @@ set_seconds_check_cb (GtkWidget *widget, IntlClockUI *this)
- }
-
- static void
--set_locations_check_cb (GtkWidget *widget, IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- panel_applet_gconf_set_bool (PANEL_APPLET (priv->panel_applet),
-- KEY_SHOW_LOCATIONS,
-- GTK_TOGGLE_BUTTON (widget)->active,
-- NULL);
--}
--
--static void
--set_map_check_cb (GtkWidget *widget, IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- panel_applet_gconf_set_bool (PANEL_APPLET (priv->panel_applet),
-- KEY_SHOW_MAP,
-- GTK_TOGGLE_BUTTON (widget)->active,
-- NULL);
--}
--
--static void
- fill_prefs_window (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-@@ -1087,6 +1095,9 @@ fill_prefs_window (IntlClockUI *this)
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *col;
-
-+ time_t now_t;
-+ struct tm now;
-+
- /* Set the 12 hour / 24 hour widget */
- widget = glade_xml_get_widget (priv->glade_xml, "12hr_radio");
- g_signal_connect (widget, "toggled",
-@@ -1109,18 +1120,6 @@ fill_prefs_window (IntlClockUI *this)
- g_signal_connect (widget, "toggled", G_CALLBACK (set_seconds_check_cb),
- this);
-
-- /* Set the "Show Locations" checkbox */
-- widget = glade_xml_get_widget (priv->glade_xml, "show_locations_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), priv->show_locations);
-- g_signal_connect (widget, "toggled", G_CALLBACK (set_locations_check_cb),
-- this);
--
-- /* Set the "Show Map" checkbox */
-- widget = glade_xml_get_widget (priv->glade_xml, "show_map_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), priv->show_map);
-- g_signal_connect (widget, "toggled", G_CALLBACK (set_map_check_cb),
-- this);
--
- /* Fill the Cities list */
- widget = glade_xml_get_widget (priv->glade_xml, "cities_list");
-
-@@ -1136,6 +1135,15 @@ fill_prefs_window (IntlClockUI *this)
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
- GTK_TREE_MODEL (priv->cities_store));
-+
-+ /* Fill the time settings */
-+ tzset ();
-+ time (&now_t);
-+ localtime_r (&now_t, &now);
-+
-+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->seconds_spin), now.tm_sec);
-+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->minutes_spin), now.tm_min);
-+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->hours_spin), now.tm_hour);
- }
-
- static gint
-@@ -1150,19 +1158,139 @@ sort_zoneinfo_by_l10n_name (gconstpointer a, gconstpointer b)
- return strcmp (name_a, name_b);
- }
-
-+static void
-+intlclock_prefs_locations_changed (GtkTreeSelection *selection,
-+ IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ gint n;
-+
-+ n = gtk_tree_selection_count_selected_rows (selection);
-+ gtk_widget_set_sensitive (priv->prefs_location_edit_button, n > 0);
-+ gtk_widget_set_sensitive (priv->prefs_location_remove_button, n > 0);
-+}
-+
-+static void
-+wrap_cb (GtkSpinButton *spin,
-+ IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ gdouble value;
-+ gdouble min, max;
-+ GtkWidget *next;
-+ GtkSpinType direction;
-+
-+ value = gtk_spin_button_get_value (spin);
-+ gtk_spin_button_get_range (spin, &min, &max);
-+
-+ if (value == min)
-+ direction = GTK_SPIN_STEP_FORWARD;
-+ else
-+ direction = GTK_SPIN_STEP_BACKWARD;
-+
-+ if (spin == (GtkSpinButton *)priv->seconds_spin)
-+ gtk_spin_button_spin (GTK_SPIN_BUTTON (priv->minutes_spin),
-+ direction, 1.0);
-+ else if (spin == (GtkSpinButton *)priv->minutes_spin)
-+ gtk_spin_button_spin (GTK_SPIN_BUTTON (priv->hours_spin),
-+ direction, 1.0);
-+ else {
-+ guint year, month, day;
-+ GDate *date;
-+
-+ gtk_calendar_get_date (GTK_CALENDAR (priv->calendar),
-+ &year, &month, &day);
-+
-+ date = g_date_new_dmy (day, month + 1, year);
-+
-+ if (direction == GTK_SPIN_STEP_FORWARD)
-+ g_date_add_days (date, 1);
-+ else
-+ g_date_subtract_days (date, 1);
-+
-+ year = g_date_get_year (date);
-+ month = g_date_get_month (date) - 1;
-+ day = g_date_get_day (date);
-+
-+ gtk_calendar_select_month (GTK_CALENDAR (priv->calendar),
-+ month, year);
-+ gtk_calendar_select_day (GTK_CALENDAR (priv->calendar),
-+ day);
-+
-+ g_date_free (date);
-+ }
-+}
-+
-+static void
-+update_set_time_button (IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ gint can_set;
-+ GtkWidget *box;
-+
-+ can_set = can_set_system_time ();
-+ box = glade_xml_get_widget (priv->glade_xml, "time_settings_box");
-+
-+ gtk_widget_set_sensitive (box, can_set != 0);
-+ gtk_button_set_label (GTK_BUTTON (priv->set_time_button),
-+ can_set == 1 ?
-+ _("Set System Time...") :
-+ _("Set System Time"));
-+}
-+
-+static void
-+set_time_callback (IntlClockUI *this, GError *error)
-+{
-+ GtkWidget *dialog;
-+
-+ if (error) {
-+ dialog = gtk_message_dialog_new (NULL,
-+ 0,
-+ GTK_MESSAGE_ERROR,
-+ GTK_BUTTONS_OK,
-+ _("Failed to set the system time"));
-+
-+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), error->message);
-+ g_signal_connect (dialog, "response",
-+ G_CALLBACK (gtk_widget_destroy), NULL);
-+ gtk_window_present (GTK_WINDOW (dialog));
-+
-+ g_error_free (error);
-+ }
-+ else
-+ update_set_time_button (this);
-+}
-+
- static void
--display_prefs_window (IntlClockUI *this)
-+set_time (GtkWidget *widget, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ struct tm t;
-+ gint64 time;
-+
-+ t.tm_sec = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->seconds_spin));
-+ t.tm_min = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->minutes_spin));
-+ t.tm_hour = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->hours_spin));
-+ gtk_calendar_get_date (GTK_CALENDAR (priv->calendar),
-+ &t.tm_year, &t.tm_mon, &t.tm_mday);
-+ t.tm_year -= 1900;
-+
-+ time = mktime (&t);
-+
-+ set_system_time_async (time, (GFunc)set_time_callback, this, NULL);
-+}
-+
-+static void
-+display_prefs_window (IntlClockUI *this, gboolean locations)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
- GtkWidget *edit_window;
- GtkWidget *prefs_window;
- GtkWidget *prefs_close_button;
-- GtkWidget *prefs_settings_button;
- GtkWidget *edit_cancel_button;
- GtkWidget *edit_ok_button;
- GtkWidget *zone_combo;
--
-- GtkWidget *tmp_button;
-+ GtkTreeSelection *selection;
-
- if (!priv->prefs_window) {
- priv->prefs_window =
-@@ -1170,38 +1298,36 @@ display_prefs_window (IntlClockUI *this)
-
- prefs_close_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-close-button");
--
-- prefs_settings_button =
-- glade_xml_get_widget (priv->glade_xml, "prefs-time-settings-button");
--
- priv->prefs_locations =
- GTK_TREE_VIEW (glade_xml_get_widget (priv->glade_xml, "cities_list"));
-
-+ selection = gtk_tree_view_get_selection (priv->prefs_locations);
-+ g_signal_connect (G_OBJECT (selection), "changed",
-+ G_CALLBACK (intlclock_prefs_locations_changed), this);
-+
-+
- g_signal_connect (G_OBJECT (priv->prefs_window), "delete_event",
- G_CALLBACK (intlclock_prefs_hide_event), this);
-
- g_signal_connect (G_OBJECT (prefs_close_button), "clicked",
- G_CALLBACK (intlclock_prefs_hide), this);
-
-- g_signal_connect (G_OBJECT (prefs_settings_button), "clicked",
-- G_CALLBACK (run_time_configuration_cb), this);
--
-- tmp_button =
-+ priv->prefs_location_remove_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-locations-remove-button");
-
-- g_signal_connect (G_OBJECT (tmp_button), "clicked",
-+ g_signal_connect (G_OBJECT (priv->prefs_location_remove_button), "clicked",
- G_CALLBACK (run_prefs_locations_remove), this);
--
-- tmp_button =
-+
-+ priv->prefs_location_add_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-locations-add-button");
-
-- g_signal_connect (G_OBJECT (tmp_button), "clicked",
-+ g_signal_connect (G_OBJECT (priv->prefs_location_add_button), "clicked",
- G_CALLBACK (run_prefs_locations_add), this);
-
-- tmp_button =
-+ priv->prefs_location_edit_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-locations-edit-button");
-
-- g_signal_connect (G_OBJECT (tmp_button), "clicked",
-+ g_signal_connect (G_OBJECT (priv->prefs_location_edit_button), "clicked",
- G_CALLBACK (run_prefs_locations_edit), this);
-
- edit_window = glade_xml_get_widget (priv->glade_xml,
-@@ -1234,11 +1360,48 @@ display_prefs_window (IntlClockUI *this)
- item. */
- gtk_combo_box_remove_text (GTK_COMBO_BOX (zone_combo), 0);
-
-+ /* Set up the time setting section */
-+ priv->current_time_label = glade_xml_get_widget (priv->glade_xml, "current_time_label");
-+ priv->set_time_button = glade_xml_get_widget (priv->glade_xml, "set_time_button");
-+ g_signal_connect (priv->set_time_button, "clicked", G_CALLBACK (set_time), this);
-+
-+ priv->calendar = glade_xml_get_widget (priv->glade_xml, "calendar");
-+ priv->hours_spin = glade_xml_get_widget (priv->glade_xml, "hours_spin");
-+ priv->minutes_spin = glade_xml_get_widget (priv->glade_xml, "minutes_spin");
-+ priv->seconds_spin = glade_xml_get_widget (priv->glade_xml, "seconds_spin");
-+
-+ gtk_entry_set_width_chars (GTK_ENTRY (priv->hours_spin), 2);
-+ gtk_entry_set_width_chars (GTK_ENTRY (priv->minutes_spin), 2);
-+ gtk_entry_set_width_chars (GTK_ENTRY (priv->seconds_spin), 2);
-+
-+ gtk_entry_set_alignment (GTK_ENTRY (priv->hours_spin), 1.0);
-+ gtk_entry_set_alignment (GTK_ENTRY (priv->minutes_spin), 1.0);
-+ gtk_entry_set_alignment (GTK_ENTRY (priv->seconds_spin), 1.0);
-+ g_signal_connect (priv->seconds_spin, "wrapped", G_CALLBACK (wrap_cb), this);
-+ g_signal_connect (priv->minutes_spin, "wrapped", G_CALLBACK (wrap_cb), this);
-+ g_signal_connect (priv->hours_spin, "wrapped", G_CALLBACK (wrap_cb), this);
-+
- /* fill it with the current preferences */
- fill_prefs_window (this);
- }
-
-+ if (locations) {
-+ GtkWidget *notebook =
-+ glade_xml_get_widget (priv->glade_xml, "notebook");
-+ gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
-+ }
-+
-+ update_set_time_button (this);
-+
- gtk_window_present (GTK_WINDOW (priv->prefs_window));
-+
-+ intlclock_ui_reset_timeout (this);
-+}
-+
-+void
-+intlclock_ui_edit_locations (IntlClockUI *ui)
-+{
-+ display_prefs_window (ui, TRUE);
- }
-
- static void
-@@ -1306,16 +1469,11 @@ intlclock_ui_new (IntlClock *clock, PanelApplet *applet)
- create_events_window (this);
- create_clock_window (this);
- create_cities_store (this);
--
-- if (priv->show_locations) {
-- create_cities_section (this);
-- }
--
-- if (priv->show_map) {
-- create_map_section (this);
-- intlclock_map_refresh (INTLCLOCK_MAP (priv->map_widget));
-- }
--
-+ create_cities_section (this);
-+ create_map_section (this);
-+
-+ intlclock_map_refresh (INTLCLOCK_MAP (priv->map_widget));
-+
- intlclock_ui_reset_timeout (this);
-
- return this;
-@@ -1365,9 +1523,6 @@ intlclock_ui_init (IntlClockUI *this)
-
- priv->cities_store = NULL;
-
-- priv->show_locations = TRUE;
-- priv->show_map = TRUE;
--
- priv->prefs_window = NULL;
-
- priv->format_12hr = TRUE;
-@@ -1547,56 +1702,6 @@ gconf_show_week_changed (GConfClient *client,
- }
-
- static void
--gconf_show_locations_changed (GConfClient *client,
-- guint cnxn_id,
-- GConfEntry *entry,
-- IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
-- GtkWidget *widget;
--
-- gboolean value;
--
-- if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-- return;
--
-- value = gconf_value_get_bool (entry->value);
--
-- priv->show_locations = (value != 0);
--
-- widget = glade_xml_get_widget (priv->glade_xml, "show_locations_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
-- priv->show_locations);
--
-- create_cities_section (this);
--}
--
--static void
--gconf_show_map_changed (GConfClient *client,
-- guint cnxn_id,
-- GConfEntry *entry,
-- IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
-- GtkWidget *widget;
--
-- gboolean value;
--
-- if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-- return;
--
-- value = gconf_value_get_bool (entry->value);
--
-- priv->show_map = (value != 0);
--
-- widget = glade_xml_get_widget (priv->glade_xml, "show_map_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
-- priv->show_map);
--
-- create_map_section (this);
--}
--
--static void
- location_start_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
-@@ -1614,6 +1719,7 @@ location_start_element (GMarkupParseContext *context,
- gchar *timezone = NULL;
- gfloat latitude = 0.0;
- gfloat longitude = 0.0;
-+ gchar *code = NULL;
-
- int index = 0;
-
-@@ -1633,6 +1739,8 @@ location_start_element (GMarkupParseContext *context,
- sscanf (attribute_values[index], "%f", &latitude);
- } else if (strcmp (att_name, "longitude") == 0) {
- sscanf (attribute_values[index], "%f", &longitude);
-+ } else if (strcmp (att_name, "code") == 0) {
-+ code = (gchar *)attribute_values[index];
- }
- }
-
-@@ -1642,7 +1750,7 @@ location_start_element (GMarkupParseContext *context,
- return;
- }
-
-- loc = intlclock_location_new (name, timezone, latitude, longitude);
-+ loc = intlclock_location_new (name, timezone, latitude, longitude, code);
-
- *(GList **)user_data = g_list_append (ret, loc);
- }
-@@ -1713,10 +1821,11 @@ gconf_loc_to_string (IntlClockLocation *loc)
- prev_locale = setlocale (LC_NUMERIC, "POSIX");
-
- ret = g_markup_printf_escaped
-- ("<location name=\"%s\" timezone=\"%s\" latitude=\"%f\" longitude=\"%f\" />",
-+ ("<location name=\"%s\" timezone=\"%s\" latitude=\"%f\" longitude=\"%f\" code=\"%s\"/>",
- intlclock_location_get_name (loc),
- intlclock_location_get_timezone (loc),
-- latitude, longitude);
-+ latitude, longitude,
-+ intlclock_location_get_weather_code (loc));
-
- setlocale (LC_NUMERIC, "");
-
-@@ -1803,24 +1912,6 @@ setup_gconf (IntlClockUI *this)
- g_free (key);
-
- key = panel_applet_gconf_get_full_key
-- (PANEL_APPLET (priv->panel_applet), KEY_SHOW_LOCATIONS);
-- priv->listeners [index++] =
-- gconf_client_notify_add (
-- client, key,
-- (GConfClientNotifyFunc) gconf_show_locations_changed,
-- this, NULL, NULL);
-- g_free (key);
--
-- key = panel_applet_gconf_get_full_key
-- (PANEL_APPLET (priv->panel_applet), KEY_SHOW_MAP);
-- priv->listeners [index++] =
-- gconf_client_notify_add (
-- client, key,
-- (GConfClientNotifyFunc) gconf_show_map_changed,
-- this, NULL, NULL);
-- g_free (key);
--
-- key = panel_applet_gconf_get_full_key
- (PANEL_APPLET (priv->panel_applet), KEY_CITIES);
- priv->listeners [index++] =
- gconf_client_notify_add (
-@@ -1868,14 +1959,6 @@ load_gconf_settings (IntlClockUI *this)
- panel_applet_gconf_get_bool (priv->panel_applet,
- KEY_SHOW_WEEK, NULL);
-
-- priv->show_locations =
-- panel_applet_gconf_get_bool (priv->panel_applet,
-- KEY_SHOW_LOCATIONS, NULL);
--
-- priv->show_map =
-- panel_applet_gconf_get_bool (priv->panel_applet,
-- KEY_SHOW_MAP, NULL);
--
- values = panel_applet_gconf_get_list (priv->panel_applet, KEY_CITIES,
- GCONF_VALUE_STRING, NULL);
-
-@@ -1894,90 +1977,14 @@ static void bonobo_display_properties_dialog (BonoboUIComponent *uic,
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-
-- display_prefs_window (this);
--}
--
--static void bonobo_run_time_configuration (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- run_time_configuration (this);
-+ display_prefs_window (this, FALSE);
- }
-
- static void display_prefs_window_cb (GtkButton *button, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-
-- display_prefs_window (this);
--}
--
--static void
--run_time_configuration_cb (GtkButton *button, gpointer this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- run_time_configuration (this);
--}
--
--static void
--run_time_configuration (IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- GtkWidget *dialog;
-- GError *err;
-- char **argv;
-- char *path;
--
-- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (priv->events_window));
-- gchar *tool = "/opt/gnome/bin/gnomesu /sbin/yast2 timezone";
--
-- if (!tool || tool[0] == '\0')
-- return;
--
-- if (!g_shell_parse_argv (tool, NULL, &argv, NULL))
-- return;
--
-- if (!(path = g_find_program_in_path (argv [0]))) {
-- g_strfreev (argv);
-- return;
-- }
--
-- g_free (path);
--
-- err = NULL;
-- if (gdk_spawn_on_screen (screen,
-- NULL,
-- argv,
-- NULL,
-- G_SPAWN_SEARCH_PATH,
-- NULL,
-- NULL,
-- NULL,
-- &err)) {
-- g_strfreev (argv);
-- return;
-- }
--
-- g_strfreev (argv);
--
-- dialog = gtk_message_dialog_new (NULL,
-- GTK_DIALOG_DESTROY_WITH_PARENT,
-- GTK_MESSAGE_ERROR,
-- GTK_BUTTONS_OK,
-- _("Failed to launch time configuration tool: %s"),
-- err->message);
-- g_error_free (err);
--
-- g_signal_connect (dialog, "response",
-- G_CALLBACK (gtk_widget_destroy), NULL);
--
-- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-- gtk_window_set_screen (GTK_WINDOW (dialog), screen);
--
-- gtk_widget_show_all (dialog);
-+ display_prefs_window (this, FALSE);
- }
-
- static void
-@@ -2205,7 +2212,7 @@ static void
- run_prefs_locations_remove (GtkButton *button, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-- GtkTreeModel *model = gtk_tree_view_get_model (priv->prefs_locations);;
-+ GtkTreeModel *model = gtk_tree_view_get_model (priv->prefs_locations);
- GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->prefs_locations));
-
- gtk_tree_selection_selected_foreach (sel, remove_tree_row, this);
-@@ -2230,7 +2237,7 @@ run_prefs_locations_edit (GtkButton *button, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-
-- GtkTreeModel *model = gtk_tree_view_get_model (priv->prefs_locations);;
-+ GtkTreeModel *model = gtk_tree_view_get_model (priv->prefs_locations);
- GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->prefs_locations));
-
- gtk_tree_selection_selected_foreach (sel, edit_tree_row, this);
-@@ -2283,7 +2290,7 @@ run_prefs_edit_save (GtkButton *button, gpointer this)
- intlclock_location_set_coords (loc, lat, lon);
- } else {
- GList *locs;
-- loc = intlclock_location_new (name, intlclock_zoneinfo_get_name (info), lat, lon);
-+ loc = intlclock_location_new (name, intlclock_zoneinfo_get_name (info), lat, lon, NULL);
-
- locs = g_list_copy (intlclock_get_locations (priv->clock));
- locs = g_list_append (locs, loc);
-@@ -2294,3 +2301,11 @@ run_prefs_edit_save (GtkButton *button, gpointer this)
-
- intlclock_edit_hide (edit_window, this);
- }
-+
-+void
-+intlclock_ui_update_weather_icon (IntlClockUI *ui, GdkPixbuf *pixbuf)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (ui));
-+
-+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->panel_weather_icon), pixbuf);
-+}
-diff --git a/src/intlclock-ui.h b/src/intlclock-ui.h
-index ecbee03..a10099a 100644
---- a/src/intlclock-ui.h
-+++ b/src/intlclock-ui.h
-@@ -29,6 +29,8 @@ GType intlclock_ui_get_type (void);
-
- IntlClockUI *intlclock_ui_new (IntlClock *clock, PanelApplet *applet);
- gboolean intlclock_ui_is_12hr (IntlClockUI *ui);
-+void intlclock_ui_edit_locations (IntlClockUI *ui);
-+void intlclock_ui_update_weather_icon (IntlClockUI *ui, GdkPixbuf *pixbuf);
-
- G_END_DECLS
- #endif /* __INTLCLOCK_UI_H__ */
-diff --git a/src/intlclock.c b/src/intlclock.c
-index 02f5b0a..552c45c 100644
---- a/src/intlclock.c
-+++ b/src/intlclock.c
-@@ -32,6 +32,8 @@ typedef struct {
- enum {
- TICK,
- LOCATIONS_CHANGED,
-+ BLINK_LOCATION,
-+ CURRENT_TIMEZONE_CHANGED,
- LAST_SIGNAL
- };
-
-@@ -87,7 +89,25 @@ intlclock_class_init (IntlClockClass *this_class)
- _intlclock_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
-- g_type_class_add_private (this_class, sizeof (IntlClockPrivate));
-+ intlclock_signals[BLINK_LOCATION] = g_signal_new
-+ ("blink-location",
-+ G_OBJECT_CLASS_TYPE (obj_class),
-+ G_SIGNAL_RUN_FIRST,
-+ G_STRUCT_OFFSET (IntlClockClass, blink_location),
-+ NULL, NULL,
-+ _intlclock_marshal_VOID__OBJECT,
-+ G_TYPE_NONE, 1, INTLCLOCK_LOCATION_TYPE);
-+
-+ intlclock_signals[CURRENT_TIMEZONE_CHANGED] = g_signal_new
-+ ("current-timezone-changed",
-+ G_OBJECT_CLASS_TYPE (obj_class),
-+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-+ G_STRUCT_OFFSET (IntlClockClass, current_timezone_changed),
-+ NULL, NULL,
-+ _intlclock_marshal_VOID__VOID,
-+ G_TYPE_NONE, 0);
-+
-+ g_type_class_add_private (this_class, sizeof (IntlClockPrivate));
- }
-
- static void
-@@ -133,7 +153,7 @@ intlclock_set_locations (IntlClock *this, GList *locations)
-
- priv->locations = locations;
-
-- g_signal_emit_by_name (this, "locations-changed");
-+ g_signal_emit (this, intlclock_signals[LOCATIONS_CHANGED], 0);
- }
-
- GList *
-@@ -202,7 +222,7 @@ intlclock_emit_tick (gpointer data)
- IntlClock *this = INTLCLOCK (data);
- IntlClockPrivate *priv = PRIVATE (this);
-
-- g_signal_emit_by_name (this, "tick");
-+ g_signal_emit (this, intlclock_signals[TICK], 0);
-
- if (priv->in_partial_timeout) {
- intlclock_reset_timeout (this);
-@@ -353,3 +373,9 @@ intlclock_free_locations (IntlClock *this)
- g_list_free (priv->locations);
- priv->locations = NULL;
- }
-+
-+void
-+intlclock_blink_location (IntlClock *this, IntlClockLocation *loc)
-+{
-+ g_signal_emit (this, intlclock_signals[BLINK_LOCATION], 0, loc);
-+}
-diff --git a/src/intlclock.h b/src/intlclock.h
-index 3b0012c..20c681d 100644
---- a/src/intlclock.h
-+++ b/src/intlclock.h
-@@ -27,6 +27,9 @@ typedef struct
-
- void (* tick) (IntlClock *clock);
- void (* locations_changed) (IntlClock *clock);
-+ void (* blink_location) (IntlClock *clock, IntlClockLocation *loc);
-+ void (* current_timezone_changed) (IntlClock *clock);
-+
- } IntlClockClass;
-
- GType intlclock_get_type (void);
-@@ -35,6 +38,7 @@ IntlClock *intlclock_new (void);
-
- void intlclock_set_locations (IntlClock *this, GList *list);
- GList *intlclock_get_locations (IntlClock *this);
-+void intlclock_blink_location (IntlClock *this, IntlClockLocation *loc);
-
- IntlClockZoneTable *intlclock_get_zonetable (IntlClock *this);
- gchar *intlclock_format_time (IntlClock *this, struct tm *now,
-diff --git a/src/set-timezone.c b/src/set-timezone.c
-new file mode 100644
-index 0000000..3233ce3
---- /dev/null
-+++ b/src/set-timezone.c
-@@ -0,0 +1,432 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
-+ *
-+ * Copyright (C) 2007 David Zeuthen <david@fubar.dk>
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include "config.h"
-+#endif
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <sys/wait.h>
-+
-+#include <dbus/dbus-glib.h>
-+#include <dbus/dbus-glib-lowlevel.h>
-+
-+#include <polkit/polkit.h>
-+#include <polkit-dbus/polkit-dbus.h>
-+
-+static DBusGConnection *
-+get_session_bus (void)
-+{
-+ GError *error;
-+ static DBusGConnection *bus = NULL;
-+
-+ if (bus == NULL) {
-+ error = NULL;
-+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-+ if (bus == NULL) {
-+ g_warning ("Couldn't connect to session bus: %s",
-+ error->message);
-+ g_error_free (error);
-+ }
-+ }
-+
-+ return bus;
-+}
-+
-+static DBusGConnection *
-+get_system_bus (void)
-+{
-+ GError *error;
-+ static DBusGConnection *bus = NULL;
-+
-+ if (bus == NULL) {
-+ error = NULL;
-+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-+ if (bus == NULL) {
-+ g_warning ("Couldn't connect to system bus: %s",
-+ error->message);
-+ g_error_free (error);
-+ }
-+ }
-+
-+ return bus;
-+}
-+
-+static PolKitContext *
-+get_pk_context (void)
-+{
-+ static PolKitContext *pk_context = NULL;
-+
-+ if (pk_context == NULL) {
-+ pk_context = polkit_context_new ();
-+ if (!polkit_context_init (pk_context, NULL)) {
-+ polkit_context_unref (pk_context);
-+ pk_context = NULL;
-+ }
-+ }
-+
-+ return pk_context;
-+}
-+
-+gboolean
-+set_system_timezone (const char *filename, GError **err)
-+{
-+ DBusGConnection *session_bus;
-+ DBusGConnection *system_bus;
-+ DBusGProxy *mechanism_proxy;
-+ DBusGProxy *polkit_gnome_proxy;
-+ gboolean ret = FALSE;
-+
-+ session_bus = get_session_bus ();
-+ if (session_bus == NULL)
-+ goto out;
-+
-+ system_bus = get_system_bus ();
-+ if (system_bus == NULL)
-+ goto out;
-+
-+ mechanism_proxy = dbus_g_proxy_new_for_name (system_bus,
-+ "org.gnome.ClockApplet.Mechanism",
-+ "/",
-+ "org.gnome.ClockApplet.Mechanism");
-+
-+ polkit_gnome_proxy = dbus_g_proxy_new_for_name (session_bus,
-+ "org.gnome.PolicyKit",
-+ "/org/gnome/PolicyKit/Manager",
-+ "org.gnome.PolicyKit.Manager");
-+
-+ if (filename != NULL) {
-+ GError *error;
-+
-+ g_debug ("Trying to set timezone '%s'", filename);
-+ try_again:
-+ error = NULL;
-+ /* first, try to call into the mechanism */
-+ if (!dbus_g_proxy_call_with_timeout (mechanism_proxy,
-+ "SetTimezone",
-+ INT_MAX,
-+ &error,
-+ /* parameters: */
-+ G_TYPE_STRING, filename,
-+ G_TYPE_INVALID,
-+ /* return values: */
-+ G_TYPE_INVALID)) {
-+ if (dbus_g_error_has_name (error, "org.gnome.ClockApplet.Mechanism.NotPrivileged")) {
-+ char **tokens;
-+ char *polkit_result_textual;
-+ char *polkit_action;
-+ gboolean gained_privilege;
-+
-+ tokens = g_strsplit (error->message, " ", 2);
-+ g_error_free (error);
-+ if (g_strv_length (tokens) != 2) {
-+ g_warning ("helper return string malformed");
-+ g_strfreev (tokens);
-+ goto out;
-+ }
-+ polkit_action = tokens[0];
-+ polkit_result_textual = tokens[1];
-+
-+ g_debug ("helper refused; returned polkit_result='%s' and polkit_action='%s'",
-+ polkit_result_textual, polkit_action);
-+
-+ /* Now ask the user for auth... */
-+ if (!dbus_g_proxy_call_with_timeout (polkit_gnome_proxy,
-+ "ShowDialog",
-+ INT_MAX,
-+ &error,
-+ /* parameters: */
-+ G_TYPE_STRING, polkit_action,
-+ G_TYPE_UINT, 0, /* X11 window ID; none */
-+ G_TYPE_INVALID,
-+ /* return values: */
-+ G_TYPE_BOOLEAN, &gained_privilege,
-+ G_TYPE_INVALID)) {
-+ g_propagate_error (err, error);
-+ g_strfreev (tokens);
-+ goto out;
-+ }
-+ g_strfreev (tokens);
-+
-+ if (gained_privilege) {
-+ g_debug ("Gained privilege; trying to set timezone again");
-+ goto try_again;
-+ }
-+
-+ } else {
-+ g_propagate_error (err, error);
-+ }
-+ goto out;
-+ }
-+
-+ g_debug ("Successfully set time zone to '%s'", filename);
-+ }
-+
-+ ret = TRUE;
-+out:
-+ g_object_unref (mechanism_proxy);
-+ g_object_unref (polkit_gnome_proxy);
-+
-+ return ret;
-+}
-+
-+static gint
-+can_do (const gchar *pk_action_id)
-+{
-+ DBusConnection *system_bus;
-+ PolKitCaller *pk_caller;
-+ PolKitAction *pk_action;
-+ PolKitResult pk_result;
-+ PolKitContext *pk_context;
-+ DBusError dbus_error;
-+ gint res = 0;
-+
-+ system_bus = dbus_g_connection_get_connection (get_system_bus ());
-+ if (system_bus == NULL)
-+ goto out;
-+
-+ pk_context = get_pk_context ();
-+ if (pk_context == NULL)
-+ goto out;
-+
-+ pk_caller = NULL;
-+ pk_action = NULL;
-+
-+ pk_action = polkit_action_new ();
-+ polkit_action_set_action_id (pk_action, pk_action_id);
-+
-+ dbus_error_init (&dbus_error);
-+ pk_caller = polkit_caller_new_from_pid (system_bus, getpid (), &dbus_error);
-+ if (pk_caller == NULL) {
-+ fprintf (stderr, "cannot get caller from dbus name\n");
-+ goto out;
-+ }
-+
-+ pk_result = polkit_context_can_caller_do_action (pk_context, pk_action, pk_caller);
-+
-+ switch (pk_result) {
-+ default:
-+ case POLKIT_RESULT_UNKNOWN:
-+ case POLKIT_RESULT_NO:
-+ res = 0;
-+ break;
-+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
-+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
-+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
-+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
-+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
-+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
-+ res = 1;
-+ break;
-+ case POLKIT_RESULT_YES:
-+ res = 2;
-+ break;
-+ }
-+
-+out:
-+ if (pk_action != NULL)
-+ polkit_action_unref (pk_action);
-+ if (pk_caller != NULL)
-+ polkit_caller_unref (pk_caller);
-+
-+ return res;
-+}
-+
-+gint
-+can_set_system_timezone (void)
-+{
-+ return can_do ("org.gnome.clockapplet.mechanism.settimezone");
-+}
-+
-+gint
-+can_set_system_time (void)
-+{
-+ return can_do ("org.gnome.clockapplet.mechanism.settime");
-+}
-+
-+typedef struct {
-+ gint ref_count;
-+ gint64 time;
-+ GFunc callback;
-+ gpointer data;
-+ GDestroyNotify notify;
-+} SetTimeCallbackData;
-+
-+static void
-+free_data (gpointer d)
-+{
-+ SetTimeCallbackData *data = d;
-+
-+ data->ref_count--;
-+ if (data->ref_count == 0) {
-+ if (data->notify)
-+ data->notify (data->data);
-+ g_free (data);
-+ }
-+}
-+
-+static void set_time_async (SetTimeCallbackData *data);
-+
-+static void
-+auth_notify (DBusGProxy *proxy,
-+ DBusGProxyCall *call,
-+ void *user_data)
-+{
-+ SetTimeCallbackData *data = user_data;
-+ GError *error = NULL;
-+ gboolean gained_privilege;
-+
-+ g_print ("ending async ShowDialog call\n");
-+ if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &gained_privilege, G_TYPE_INVALID)) {
-+ g_print ("result: %d\n", gained_privilege);
-+ if (gained_privilege)
-+ set_time_async (data);
-+ }
-+ else {
-+ if (data->callback)
-+ data->callback (data->data, error);
-+ else
-+ g_error_free (error);
-+ }
-+}
-+
-+static void
-+do_auth_async (const gchar *action,
-+ const gchar *result,
-+ SetTimeCallbackData *data)
-+{
-+ DBusGConnection *bus;
-+ DBusGProxy *proxy;
-+
-+ g_debug ("helper refused; returned polkit_result='%s' and polkit_action='%s'",
-+ result, action);
-+
-+ /* Now ask the user for auth... */
-+ bus = get_session_bus ();
-+ if (bus == NULL)
-+ return;
-+
-+ proxy = dbus_g_proxy_new_for_name (bus,
-+ "org.gnome.PolicyKit",
-+ "/org/gnome/PolicyKit/Manager",
-+ "org.gnome.PolicyKit.Manager");
-+
-+ g_print ("beginning async ShowDialog call\n");
-+ data->ref_count++;
-+ dbus_g_proxy_begin_call_with_timeout (proxy,
-+ "ShowDialog",
-+ auth_notify,
-+ data, free_data,
-+ INT_MAX,
-+ G_TYPE_STRING, action,
-+ G_TYPE_UINT, 0,
-+ G_TYPE_INVALID);
-+}
-+
-+static void
-+set_time_notify (DBusGProxy *proxy,
-+ DBusGProxyCall *call,
-+ void *user_data)
-+{
-+ SetTimeCallbackData *data = user_data;
-+ GError *error = NULL;
-+
-+ g_print ("ending async SetTime call\n");
-+ if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
-+ g_print ("calling user callback\n");
-+ if (data->callback)
-+ data->callback (data->data, NULL);
-+ }
-+ else {
-+ if (dbus_g_error_has_name (error, "org.gnome.ClockApplet.Mechanism.NotPrivileged")) {
-+ gchar **tokens;
-+
-+ tokens = g_strsplit (error->message, " ", 2);
-+ g_error_free (error);
-+ if (g_strv_length (tokens) == 2)
-+ do_auth_async (tokens[0], tokens[1], data);
-+ else
-+ g_warning ("helper return string malformed");
-+ g_strfreev (tokens);
-+ }
-+ else {
-+ if (data->callback)
-+ data->callback (data->data, error);
-+ else
-+ g_error_free (error);
-+ }
-+ }
-+}
-+
-+static void
-+set_time_async (SetTimeCallbackData *data)
-+{
-+ DBusGConnection *bus;
-+ DBusGProxy *proxy;
-+ DBusGProxyCall *call;
-+
-+ bus = get_system_bus ();
-+ if (bus == NULL)
-+ return;
-+
-+ proxy = dbus_g_proxy_new_for_name (bus,
-+ "org.gnome.ClockApplet.Mechanism",
-+ "/",
-+ "org.gnome.ClockApplet.Mechanism");
-+
-+ g_print ("beginning async SetTime call\n");
-+ data->ref_count++;
-+ dbus_g_proxy_begin_call_with_timeout (proxy,
-+ "SetTime",
-+ set_time_notify,
-+ data, free_data,
-+ INT_MAX,
-+ /* parameters: */
-+ G_TYPE_INT64, data->time,
-+ G_TYPE_INVALID,
-+ /* return values: */
-+ G_TYPE_INVALID);
-+}
-+
-+void
-+set_system_time_async (gint64 time,
-+ GFunc callback,
-+ gpointer d,
-+ GDestroyNotify notify)
-+{
-+ SetTimeCallbackData *data;
-+
-+ if (time == -1)
-+ return;
-+
-+ data = g_new (SetTimeCallbackData, 1);
-+ data->ref_count = 1;
-+ data->time = time;
-+ data->callback = callback;
-+ data->data = d;
-+ data->notify = notify;
-+
-+ set_time_async (data);
-+ free_data (data);
-+}
-diff --git a/src/set-timezone.h b/src/set-timezone.h
-new file mode 100644
-index 0000000..c71622c
---- /dev/null
-+++ b/src/set-timezone.h
-@@ -0,0 +1,36 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
-+ *
-+ * Copyright (C) 2007 David Zeuthen <david@fubar.dk>
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#ifndef __SET_SYSTEM_TIMEZONE_H__
-+
-+#include <time.h>
-+
-+gboolean set_system_timezone (const char *filename,
-+ GError **err);
-+gint can_set_system_timezone (void);
-+
-+gint can_set_system_time (void);
-+
-+void set_system_time_async (gint64 time,
-+ GFunc callback,
-+ gpointer data,
-+ GDestroyNotify notify);
-+
-+#endif
diff --git a/intlclock-changes-20071009.patch b/intlclock-changes-20071009.patch
deleted file mode 100644
index 911110a..0000000
--- a/intlclock-changes-20071009.patch
+++ /dev/null
@@ -1,10832 +0,0 @@
-diff --git a/configure.in b/configure.in
-index 4e818da..6c75db1 100644
---- a/configure.in
-+++ b/configure.in
-@@ -59,7 +59,7 @@ if test -n "$LIBECAL_REQUIREMENT"; then
- fi
- AM_CONDITIONAL(HAVE_LIBECAL, test -n "$LIBECAL_REQUIREMENT")
-
--PKG_CHECK_MODULES(INTLCLOCK, [ glib-2.0 gobject-2.0 gtk+-2.0 gdk-2.0 librsvg-2.0 libpanelapplet-2.0 libgnome-2.0 gconf-2.0 $LIBECAL_REQUIREMENT ])
-+PKG_CHECK_MODULES(INTLCLOCK, [ glib-2.0 gobject-2.0 gtk+-2.0 gdk-2.0 librsvg-2.0 libpanelapplet-2.0 libgnome-2.0 gconf-2.0 $LIBECAL_REQUIREMENT dbus-glib-1 gweather libxml-2.0 polkit polkit-dbus ])
-
- AC_SUBST(INTLCLOCK_CFLAGS)
- AC_SUBST(INTLCLOCK_LIBS)
-diff --git a/data/GNOME_IntlClockApplet.xml b/data/GNOME_IntlClockApplet.xml
-index dd2e8b8..a88dc3d 100644
---- a/data/GNOME_IntlClockApplet.xml
-+++ b/data/GNOME_IntlClockApplet.xml
-@@ -1,9 +1,14 @@
- <Root>
- <popups>
- <popup name="button3">
-+ <menuitem name="Clock Copy Time Item" verb="ClockCopyTime" _label="Copy _Time"
-+ pixtype="stock" pixname="gtk-copy"/>
-+ <menuitem name="Clock Copy Date Item" verb="ClockCopyDate" _label="Copy _Date"
-+ pixtype="stock" pixname="gtk-copy"/>
-+ <separator/>
- <menuitem name="Clock Configure Item" verb="IntlClockConfig"
-- _label="Cha_nge Date or Time"
-- pixtype="stock" pixname="gtk-preferences"/>
-+ _label="Ad_just Date &amp; Time"
-+ pixtype="stock" pixname="gtk-preferences"/>
- <menuitem name="Clock Preferences Item" verb="IntlClockPreferences" _label="_Preferences"
- pixtype="stock" pixname="gtk-properties"/>
- </popup>
-diff --git a/data/GNOME_IntlClockApplet_Factory.server.in.in b/data/GNOME_IntlClockApplet_Factory.server.in.in
-index 1446822..705fb76 100644
---- a/data/GNOME_IntlClockApplet_Factory.server.in.in
-+++ b/data/GNOME_IntlClockApplet_Factory.server.in.in
-@@ -20,7 +20,7 @@
- </oaf_attribute>
- <oaf_attribute name="name" type="string" value="International Clock"/>
- <oaf_attribute name="description" type="string" value="International Clock applet for the GNOME panel"/>
-- <oaf_attribute name="panel:icon" type="string" value="clock.png"/>
-+ <oaf_attribute name="panel:icon" type="string" value="gnome-panel-clock"/>
- </oaf_server>
-
- <oaf_server iid="OAFIID:GNOME_ClockApplet"
-diff --git a/data/intlclock.glade b/data/intlclock.glade
-index e7b8c01..626d835 100644
---- a/data/intlclock.glade
-+++ b/data/intlclock.glade
-@@ -21,12 +21,13 @@
-
- <child>
- <widget class="GtkVBox" id="vbox1">
-+ <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
-- <widget class="GtkNotebook" id="notebook1">
-+ <widget class="GtkNotebook" id="notebook">
- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
-@@ -37,194 +38,35 @@
- <property name="enable_popup">False</property>
-
- <child>
-- <widget class="GtkTable" id="table1">
-- <property name="border_width">6</property>
-+ <widget class="GtkVBox" id="vbox17">
-+ <property name="border_width">12</property>
- <property name="visible">True</property>
-- <property name="n_rows">4</property>
-- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
-- <property name="row_spacing">6</property>
-- <property name="column_spacing">6</property>
-+ <property name="spacing">18</property>
-
- <child>
-- <widget class="GtkLabel" id="label11">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">Clock options:</property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label12">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label13">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">3</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label14">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">3</property>
-- <property name="bottom_attach">4</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label15">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">3</property>
-- <property name="bottom_attach">4</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkCheckButton" id="seconds_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">Show s_econds</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">3</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkHBox" id="hbox3">
-+ <widget class="GtkVBox" id="vbox18">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkRadioButton" id="12hr_radio">
-+ <widget class="GtkLabel" id="label210">
- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">12 _hour format</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-+ <property name="label" translatable="yes">&lt;b&gt;Clock Options&lt;/b&gt;</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">True</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
-@@ -234,138 +76,150 @@
- </child>
-
- <child>
-- <widget class="GtkRadioButton" id="24hr_radio">
-+ <widget class="GtkHBox" id="hbox48">
- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">24 h_our format</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- <property name="group">12hr_radio</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label211">
-+ <property name="visible">True</property>
-+ <property name="label"> </property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox19">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox49">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">13</property>
-+
-+ <child>
-+ <widget class="GtkRadioButton" id="12hr_radio">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">12 _hour format</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkRadioButton" id="24hr_radio">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">24 h_our format</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
-+ <property name="group">12hr_radio</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkCheckButton" id="date_check">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Show the _date</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkCheckButton" id="seconds_check">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Show _seconds</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ <property name="active">False</property>
-+ <property name="inconsistent">False</property>
-+ <property name="draw_indicator">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
- </widget>
- <packing>
- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options">fill</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkCheckButton" id="date_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">Show the _date</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label16">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label17">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label201">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">3</property>
-- <property name="bottom_attach">4</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">True</property>
- </packing>
- </child>
- </widget>
-@@ -376,7 +230,7 @@
- </child>
-
- <child>
-- <widget class="GtkLabel" id="label1">
-+ <widget class="GtkLabel" id="label209">
- <property name="visible">True</property>
- <property name="label" translatable="yes">General</property>
- <property name="use_underline">False</property>
-@@ -399,332 +253,105 @@
- </child>
-
- <child>
-- <widget class="GtkTable" id="table5">
-- <property name="border_width">6</property>
-+ <widget class="GtkVBox" id="vbox24">
-+ <property name="border_width">12</property>
- <property name="visible">True</property>
-- <property name="n_rows">8</property>
-- <property name="n_columns">4</property>
- <property name="homogeneous">False</property>
-- <property name="row_spacing">6</property>
-- <property name="column_spacing">6</property>
--
-- <child>
-- <widget class="GtkLabel" id="label36">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">3</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label37">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">3</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
-+ <property name="spacing">18</property>
-
- <child>
-- <widget class="GtkScrolledWindow" id="scrolledwindow2">
-+ <widget class="GtkHBox" id="hbox54">
- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
-- <property name="vscrollbar_policy">GTK_POLICY_NEVER</property>
-- <property name="shadow_type">GTK_SHADOW_IN</property>
-- <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">12</property>
-
- <child>
-- <widget class="GtkTreeView" id="cities_list">
-+ <widget class="GtkScrolledWindow" id="scrolledwindow10">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
-- <property name="headers_visible">False</property>
-- <property name="rules_hint">False</property>
-- <property name="reorderable">False</property>
-- <property name="enable_search">True</property>
-- <property name="fixed_height_mode">False</property>
-- <property name="hover_selection">False</property>
-- <property name="hover_expand">True</property>
-+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
-+ <property name="vscrollbar_policy">GTK_POLICY_NEVER</property>
-+ <property name="shadow_type">GTK_SHADOW_IN</property>
-+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+
-+ <child>
-+ <widget class="GtkTreeView" id="cities_list">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="headers_visible">False</property>
-+ <property name="rules_hint">False</property>
-+ <property name="reorderable">False</property>
-+ <property name="enable_search">True</property>
-+ <property name="fixed_height_mode">False</property>
-+ <property name="hover_selection">False</property>
-+ <property name="hover_expand">True</property>
-+ </widget>
-+ </child>
- </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
- </child>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">8</property>
-- <property name="x_options">fill</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkAlignment" id="alignment6">
-- <property name="visible">True</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xscale">0</property>
-- <property name="yscale">1</property>
-- <property name="top_padding">0</property>
-- <property name="bottom_padding">0</property>
-- <property name="left_padding">0</property>
-- <property name="right_padding">0</property>
-
- <child>
-- <widget class="GtkVBox" id="vbox2">
-+ <widget class="GtkVButtonBox" id="vbuttonbox2">
- <property name="visible">True</property>
-- <property name="homogeneous">False</property>
-+ <property name="layout_style">GTK_BUTTONBOX_START</property>
- <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkLabel" id="label39">
-+ <widget class="GtkButton" id="prefs-locations-add-button">
-+ <property name="width_request">24</property>
-+ <property name="height_request">25</property>
- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-add</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
- </child>
-
- <child>
-- <widget class="GtkVButtonBox" id="vbuttonbox1">
-+ <widget class="GtkButton" id="prefs-locations-edit-button">
-+ <property name="width_request">24</property>
-+ <property name="height_request">24</property>
- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_START</property>
-- <property name="spacing">6</property>
--
-- <child>
-- <widget class="GtkButton" id="prefs-locations-add-button">
-- <property name="width_request">24</property>
-- <property name="height_request">25</property>
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-add</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
--
-- <child>
-- <widget class="GtkButton" id="prefs-locations-edit-button">
-- <property name="width_request">24</property>
-- <property name="height_request">24</property>
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-edit</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
--
-- <child>
-- <widget class="GtkButton" id="prefs-locations-remove-button">
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-remove</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-edit</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
- </child>
-
- <child>
-- <widget class="GtkLabel" id="label38">
-+ <widget class="GtkButton" id="prefs-locations-remove-button">
- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-remove</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
- </child>
- </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
- </child>
- </widget>
- <packing>
-- <property name="left_attach">3</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">2</property>
-- <property name="bottom_attach">8</property>
-- <property name="x_options"></property>
-- <property name="y_options">fill</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkCheckButton" id="show_map_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">Show the world _map in the clock</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label41">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">2</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label160">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes"></property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">2</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkCheckButton" id="show_locations_check">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="label" translatable="yes">S_how locations in the clock</property>
-- <property name="use_underline">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- <property name="active">False</property>
-- <property name="inconsistent">False</property>
-- <property name="draw_indicator">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">3</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
- </packing>
- </child>
- </widget>
-@@ -735,7 +362,7 @@
- </child>
-
- <child>
-- <widget class="GtkLabel" id="label2">
-+ <widget class="GtkLabel" id="label220">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Locations</property>
- <property name="use_underline">False</property>
-@@ -772,95 +399,20 @@
- <property name="spacing">0</property>
-
- <child>
-- <widget class="GtkHButtonBox" id="hbuttonbox2">
-- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
-- <property name="spacing">0</property>
-- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkHButtonBox" id="hbuttonbox3">
-+ <widget class="GtkHButtonBox" id="hbuttonbox22">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
- <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkButton" id="prefs-time-settings-button">
-+ <widget class="GtkButton" id="time-settings-button">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Time Settings</property>
-+ <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
--
-- <child>
-- <widget class="GtkAlignment" id="alignment5">
-- <property name="visible">True</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xscale">0</property>
-- <property name="yscale">0</property>
-- <property name="top_padding">0</property>
-- <property name="bottom_padding">0</property>
-- <property name="left_padding">0</property>
-- <property name="right_padding">0</property>
--
-- <child>
-- <widget class="GtkHBox" id="hbox8">
-- <property name="visible">True</property>
-- <property name="homogeneous">False</property>
-- <property name="spacing">2</property>
--
-- <child>
-- <widget class="GtkImage" id="image5">
-- <property name="visible">True</property>
-- <property name="stock">gtk-properties</property>
-- <property name="icon_size">4</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label35">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">Time _Settings</property>
-- <property name="use_underline">True</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0.5</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
-- </child>
-- </widget>
-- </child>
-- </widget>
-- </child>
- </widget>
- </child>
-
-@@ -910,13 +462,13 @@
-
- <child>
- <widget class="GtkVBox" id="vbox14">
-+ <property name="border_width">12</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
-- <property name="spacing">0</property>
-+ <property name="spacing">24</property>
-
- <child>
- <widget class="GtkTable" id="table23">
-- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="n_rows">1</property>
- <property name="n_columns">3</property>
-@@ -926,7 +478,6 @@
-
- <child>
- <widget class="GtkVBox" id="vbox15">
-- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-@@ -974,62 +525,6 @@
- <property name="column_spacing">6</property>
-
- <child>
-- <widget class="GtkLabel" id="label174">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">Timezone:</property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkLabel" id="label175">
-- <property name="visible">True</property>
-- <property name="label" translatable="yes">Location Name:</property>
-- <property name="use_underline">False</property>
-- <property name="use_markup">False</property>
-- <property name="justify">GTK_JUSTIFY_LEFT</property>
-- <property name="wrap">False</property>
-- <property name="selectable">False</property>
-- <property name="xalign">0</property>
-- <property name="yalign">0.5</property>
-- <property name="xpad">0</property>
-- <property name="ypad">0</property>
-- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-- <property name="width_chars">-1</property>
-- <property name="single_line_mode">False</property>
-- <property name="angle">0</property>
-- </widget>
-- <packing>
-- <property name="left_attach">0</property>
-- <property name="right_attach">1</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="x_options">fill</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
- <widget class="GtkVBox" id="vbox16">
- <property name="visible">True</property>
- <property name="homogeneous">True</property>
-@@ -1070,45 +565,6 @@
- </child>
-
- <child>
-- <widget class="GtkComboBoxEntry" id="edit-location-timezone-combo">
-- <property name="visible">True</property>
-- <property name="items">Dummy Item</property>
-- <property name="add_tearoffs">False</property>
-- <property name="has_frame">True</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">0</property>
-- <property name="bottom_attach">1</property>
-- <property name="x_options">fill</property>
-- <property name="y_options">fill</property>
-- </packing>
-- </child>
--
-- <child>
-- <widget class="GtkEntry" id="edit-location-name-entry">
-- <property name="visible">True</property>
-- <property name="can_focus">True</property>
-- <property name="editable">True</property>
-- <property name="visibility">True</property>
-- <property name="max_length">0</property>
-- <property name="text" translatable="yes"></property>
-- <property name="has_frame">True</property>
-- <property name="invisible_char">●</property>
-- <property name="activates_default">False</property>
-- </widget>
-- <packing>
-- <property name="left_attach">1</property>
-- <property name="right_attach">4</property>
-- <property name="top_attach">1</property>
-- <property name="bottom_attach">2</property>
-- <property name="y_options"></property>
-- </packing>
-- </child>
--
-- <child>
- <widget class="GtkLabel" id="label208">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Longitude:</property>
-@@ -1145,7 +601,7 @@
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
-- <property name="invisible_char">●</property>
-+ <property name="invisible_char">•</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
-@@ -1258,7 +714,7 @@ South</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
-- <property name="invisible_char">●</property>
-+ <property name="invisible_char">•</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
-@@ -1269,6 +725,131 @@ South</property>
- <property name="y_options"></property>
- </packing>
- </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label175">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Location Name:</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="left_attach">0</property>
-+ <property name="right_attach">1</property>
-+ <property name="top_attach">0</property>
-+ <property name="bottom_attach">1</property>
-+ <property name="x_options">fill</property>
-+ <property name="y_options"></property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label174">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Timezone:</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="left_attach">0</property>
-+ <property name="right_attach">1</property>
-+ <property name="top_attach">1</property>
-+ <property name="bottom_attach">2</property>
-+ <property name="x_options">fill</property>
-+ <property name="y_options"></property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox55">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkEntry" id="edit-location-name-entry">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="editable">True</property>
-+ <property name="visibility">True</property>
-+ <property name="max_length">0</property>
-+ <property name="text" translatable="yes"></property>
-+ <property name="has_frame">True</property>
-+ <property name="invisible_char">•</property>
-+ <property name="activates_default">False</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="find-location-button">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Find...</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="left_attach">1</property>
-+ <property name="right_attach">4</property>
-+ <property name="top_attach">0</property>
-+ <property name="bottom_attach">1</property>
-+ <property name="x_options">fill</property>
-+ <property name="y_options">fill</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkComboBoxEntry" id="edit-location-timezone-combo">
-+ <property name="visible">True</property>
-+ <property name="items">Dummy Item</property>
-+ <property name="add_tearoffs">False</property>
-+ <property name="has_frame">True</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ <packing>
-+ <property name="left_attach">1</property>
-+ <property name="right_attach">4</property>
-+ <property name="top_attach">1</property>
-+ <property name="bottom_attach">2</property>
-+ <property name="x_options">fill</property>
-+ <property name="y_options">fill</property>
-+ </packing>
-+ </child>
- </widget>
- <packing>
- <property name="padding">0</property>
-@@ -1294,60 +875,33 @@ South</property>
- </child>
-
- <child>
-- <widget class="GtkHBox" id="hbox40">
-- <property name="border_width">6</property>
-+ <widget class="GtkHButtonBox" id="hbuttonbox20">
- <property name="visible">True</property>
-- <property name="homogeneous">False</property>
-- <property name="spacing">0</property>
-+ <property name="layout_style">GTK_BUTTONBOX_END</property>
-+ <property name="spacing">6</property>
-
- <child>
-- <widget class="GtkHButtonBox" id="hbuttonbox12">
-+ <widget class="GtkButton" id="edit-location-cancel-button">
- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
-- <property name="spacing">0</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-cancel</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">False</property>
-- <property name="fill">False</property>
-- </packing>
- </child>
-
- <child>
-- <widget class="GtkHButtonBox" id="hbuttonbox18">
-+ <widget class="GtkButton" id="edit-location-ok-button">
- <property name="visible">True</property>
-- <property name="layout_style">GTK_BUTTONBOX_END</property>
-- <property name="spacing">6</property>
--
-- <child>
-- <widget class="GtkButton" id="edit-location-cancel-button">
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-cancel</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
--
-- <child>
-- <widget class="GtkButton" id="edit-location-ok-button">
-- <property name="visible">True</property>
-- <property name="can_default">True</property>
-- <property name="can_focus">True</property>
-- <property name="label">gtk-ok</property>
-- <property name="use_stock">True</property>
-- <property name="relief">GTK_RELIEF_NORMAL</property>
-- <property name="focus_on_click">True</property>
-- </widget>
-- </child>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-ok</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
- </widget>
-- <packing>
-- <property name="padding">0</property>
-- <property name="expand">True</property>
-- <property name="fill">True</property>
-- </packing>
- </child>
- </widget>
- <packing>
-@@ -1723,4 +1277,580 @@ South</property>
- </child>
- </widget>
-
-+<widget class="GtkWindow" id="find-location-window">
-+ <property name="title" translatable="yes"></property>
-+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
-+ <property name="window_position">GTK_WIN_POS_NONE</property>
-+ <property name="modal">False</property>
-+ <property name="resizable">True</property>
-+ <property name="destroy_with_parent">False</property>
-+ <property name="decorated">True</property>
-+ <property name="skip_taskbar_hint">False</property>
-+ <property name="skip_pager_hint">False</property>
-+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-+ <property name="focus_on_map">True</property>
-+ <property name="urgency_hint">False</property>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox25">
-+ <property name="border_width">12</property>
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">24</property>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox26">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkScrolledWindow" id="scrolledwindow11">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-+ <property name="shadow_type">GTK_SHADOW_IN</property>
-+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-+
-+ <child>
-+ <widget class="GtkTreeView" id="find-location-tree">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="headers_visible">False</property>
-+ <property name="rules_hint">False</property>
-+ <property name="reorderable">False</property>
-+ <property name="enable_search">False</property>
-+ <property name="fixed_height_mode">False</property>
-+ <property name="hover_selection">False</property>
-+ <property name="hover_expand">False</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox56">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label221">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">_Find:</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="mnemonic_widget">find-location-entry</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkEntry" id="find-location-entry">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="editable">True</property>
-+ <property name="visibility">True</property>
-+ <property name="max_length">0</property>
-+ <property name="text" translatable="yes"></property>
-+ <property name="has_frame">True</property>
-+ <property name="invisible_char">•</property>
-+ <property name="activates_default">False</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="find-next-location-button">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+
-+ <child>
-+ <widget class="GtkAlignment" id="alignment31">
-+ <property name="visible">True</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xscale">0</property>
-+ <property name="yscale">0</property>
-+ <property name="top_padding">0</property>
-+ <property name="bottom_padding">0</property>
-+ <property name="left_padding">0</property>
-+ <property name="right_padding">0</property>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox57">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">2</property>
-+
-+ <child>
-+ <widget class="GtkImage" id="image29">
-+ <property name="visible">True</property>
-+ <property name="stock">gtk-find</property>
-+ <property name="icon_size">4</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label222">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Find _Next</property>
-+ <property name="use_underline">True</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHButtonBox" id="hbuttonbox19">
-+ <property name="visible">True</property>
-+ <property name="layout_style">GTK_BUTTONBOX_END</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkButton" id="find-location-cancel-button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-cancel</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="find-location-ok-button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-ok</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+</widget>
-+
-+<widget class="GtkWindow" id="set-time-window">
-+ <property name="border_width">12</property>
-+ <property name="title" translatable="yes">Time Settings</property>
-+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
-+ <property name="window_position">GTK_WIN_POS_NONE</property>
-+ <property name="modal">False</property>
-+ <property name="resizable">True</property>
-+ <property name="destroy_with_parent">False</property>
-+ <property name="decorated">True</property>
-+ <property name="skip_taskbar_hint">False</property>
-+ <property name="skip_pager_hint">False</property>
-+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-+ <property name="focus_on_map">True</property>
-+ <property name="urgency_hint">False</property>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox20">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label212">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">&lt;b&gt;Time Settings&lt;/b&gt;</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">True</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="time_settings_box">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label217">
-+ <property name="visible">True</property>
-+ <property name="label"> </property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0.5</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox52">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">12</property>
-+
-+ <child>
-+ <widget class="GtkCalendar" id="calendar">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="display_options">GTK_CALENDAR_SHOW_HEADING</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox22">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label218">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Current Time:</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkLabel" id="label219">
-+ <property name="visible">True</property>
-+ <property name="label" translatable="yes">Time:</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkVBox" id="vbox23">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkLabel" id="current_time_label">
-+ <property name="visible">True</property>
-+ <property name="label">23:59:59</property>
-+ <property name="use_underline">False</property>
-+ <property name="use_markup">False</property>
-+ <property name="justify">GTK_JUSTIFY_LEFT</property>
-+ <property name="wrap">False</property>
-+ <property name="selectable">False</property>
-+ <property name="xalign">0</property>
-+ <property name="yalign">0.5</property>
-+ <property name="xpad">0</property>
-+ <property name="ypad">0</property>
-+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-+ <property name="width_chars">-1</property>
-+ <property name="single_line_mode">False</property>
-+ <property name="angle">0</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox53">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkSpinButton" id="hours_spin">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="climb_rate">1</property>
-+ <property name="digits">0</property>
-+ <property name="numeric">True</property>
-+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-+ <property name="snap_to_ticks">False</property>
-+ <property name="wrap">True</property>
-+ <property name="adjustment">23 0 23 1 12 12</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkSpinButton" id="minutes_spin">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="climb_rate">1</property>
-+ <property name="digits">0</property>
-+ <property name="numeric">True</property>
-+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-+ <property name="snap_to_ticks">False</property>
-+ <property name="wrap">True</property>
-+ <property name="adjustment">59 0 59 1 30 30</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkSpinButton" id="seconds_spin">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="climb_rate">1</property>
-+ <property name="digits">0</property>
-+ <property name="numeric">True</property>
-+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-+ <property name="snap_to_ticks">False</property>
-+ <property name="wrap">True</property>
-+ <property name="adjustment">59 0 59 1 30 30</property>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ </packing>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkHBox" id="hbox58">
-+ <property name="visible">True</property>
-+ <property name="homogeneous">False</property>
-+ <property name="spacing">0</property>
-+
-+ <child>
-+ <widget class="GtkHButtonBox" id="hbuttonbox21">
-+ <property name="visible">True</property>
-+ <property name="layout_style">GTK_BUTTONBOX_END</property>
-+ <property name="spacing">6</property>
-+
-+ <child>
-+ <widget class="GtkButton" id="cancel-set-time-button">
-+ <property name="visible">True</property>
-+ <property name="can_default">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label">gtk-cancel</property>
-+ <property name="use_stock">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+
-+ <child>
-+ <widget class="GtkButton" id="set-time-button">
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="label" translatable="yes">Set System Time</property>
-+ <property name="use_underline">True</property>
-+ <property name="relief">GTK_RELIEF_NORMAL</property>
-+ <property name="focus_on_click">True</property>
-+ </widget>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">True</property>
-+ <property name="fill">True</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ <packing>
-+ <property name="padding">0</property>
-+ <property name="expand">False</property>
-+ <property name="fill">False</property>
-+ <property name="pack_type">GTK_PACK_END</property>
-+ </packing>
-+ </child>
-+ </widget>
-+ </child>
-+</widget>
-+
- </glade-interface>
-diff --git a/data/intlclock.schemas.in b/data/intlclock.schemas.in
-index 2ab6772..00fee4f 100644
---- a/data/intlclock.schemas.in
-+++ b/data/intlclock.schemas.in
-@@ -89,41 +89,54 @@
- </schema>
-
- <schema>
-- <key>/schemas/apps/intlclock_applet/prefs/show_locations</key>
-+ <key>/schemas/apps/intlclock_applet/prefs/cities</key>
-+ <owner>clock-applet</owner>
-+ <type>list</type>
-+ <list_type>string</list_type>
-+ <default>[]</default>
-+ <locale name="C">
-+ <short>List of cities for the clock.</short>
-+ <long>
-+ List of cities to display in the international clock.
-+ </long>
-+ </locale>
-+ </schema>
-+
-+ <schema>
-+ <key>/schemas/apps/intlclock_applet/prefs/expand_locations</key>
- <owner>clock-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
-- <short>Show other locations in clock</short>
-+ <short>Expand the location section in clock</short>
- <long>
-- If true, show a list of locations in the international clock.
-+ If true, expand the list of locations in the international clock.
- </long>
- </locale>
- </schema>
-
- <schema>
-- <key>/schemas/apps/intlclock_applet/prefs/show_map</key>
-+ <key>/schemas/apps/intlclock_applet/prefs/expand_tasks</key>
- <owner>clock-applet</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
-- <short>Show world map in clock</short>
-+ <short>Expand the tasks section in clock</short>
- <long>
-- If true, show the world map in the international clock.
-+ If true, expand the list of tasks in the international clock.
- </long>
- </locale>
- </schema>
-
- <schema>
-- <key>/schemas/apps/intlclock_applet/prefs/cities</key>
-+ <key>/schemas/apps/intlclock_applet/prefs/expand_appointments</key>
- <owner>clock-applet</owner>
-- <type>list</type>
-- <list_type>string</list_type>
-- <default>[]</default>
-+ <type>bool</type>
-+ <default>true</default>
- <locale name="C">
-- <short>List of cities for the clock.</short>
-+ <short>Expand the appointments section in clock</short>
- <long>
-- List of cities to display in the international clock.
-+ If true, expand the list of appointments in the international clock.
- </long>
- </locale>
- </schema>
-diff --git a/intltool-extract.in b/intltool-extract.in
-deleted file mode 100755
-index bb6c368..340fc8d
---- a/intltool-extract.in
-+++ /dev/null
-@@ -1,841 +0,0 @@
--#!@INTLTOOL_PERL@ -w
--# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
--
--#
--# The Intltool Message Extractor
--#
--# Copyright (C) 2000-2001, 2003 Free Software Foundation.
--#
--# Intltool 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.
--#
--# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA.
--#
--# As a special exception to the GNU General Public License, if you
--# distribute this file as part of a program that contains a
--# configuration script generated by Autoconf, you may include it under
--# the same distribution terms that you use for the rest of that program.
--#
--# Authors: Kenneth Christiansen <kenneth@gnu.org>
--# Darin Adler <darin@bentspoon.com>
--#
--
--## Release information
--my $PROGRAM = "intltool-extract";
--my $PACKAGE = "intltool";
--my $VERSION = "0.35.0";
--
--## Loaded modules
--use strict;
--use File::Basename;
--use Getopt::Long;
--
--## Scalars used by the option stuff
--my $TYPE_ARG = "0";
--my $LOCAL_ARG = "0";
--my $HELP_ARG = "0";
--my $VERSION_ARG = "0";
--my $UPDATE_ARG = "0";
--my $QUIET_ARG = "0";
--my $SRCDIR_ARG = ".";
--
--my $FILE;
--my $OUTFILE;
--
--my $gettext_type = "";
--my $input;
--my %messages = ();
--my %loc = ();
--my %count = ();
--my %comments = ();
--my $strcount = 0;
--
--my $XMLCOMMENT = "";
--
--## Use this instead of \w for XML files to handle more possible characters.
--my $w = "[-A-Za-z0-9._:]";
--
--## Always print first
--$| = 1;
--
--## Handle options
--GetOptions (
-- "type=s" => \$TYPE_ARG,
-- "local|l" => \$LOCAL_ARG,
-- "help|h" => \$HELP_ARG,
-- "version|v" => \$VERSION_ARG,
-- "update" => \$UPDATE_ARG,
-- "quiet|q" => \$QUIET_ARG,
-- "srcdir=s" => \$SRCDIR_ARG,
-- ) or &error;
--
--&split_on_argument;
--
--
--## Check for options.
--## This section will check for the different options.
--
--sub split_on_argument {
--
-- if ($VERSION_ARG) {
-- &version;
--
-- } elsif ($HELP_ARG) {
-- &help;
--
-- } elsif ($LOCAL_ARG) {
-- &place_local;
-- &extract;
--
-- } elsif ($UPDATE_ARG) {
-- &place_normal;
-- &extract;
--
-- } elsif (@ARGV > 0) {
-- &place_normal;
-- &message;
-- &extract;
--
-- } else {
-- &help;
--
-- }
--}
--
--sub place_normal {
-- $FILE = $ARGV[0];
-- $OUTFILE = "$FILE.h";
--}
--
--sub place_local {
-- $FILE = $ARGV[0];
-- $OUTFILE = fileparse($FILE, ());
-- if (!-e "tmp/") {
-- system("mkdir tmp/");
-- }
-- $OUTFILE = "./tmp/$OUTFILE.h"
--}
--
--sub determine_type {
-- if ($TYPE_ARG =~ /^gettext\/(.*)/) {
-- $gettext_type=$1
-- }
--}
--
--## Sub for printing release information
--sub version{
-- print <<_EOF_;
--${PROGRAM} (${PACKAGE}) $VERSION
--Copyright (C) 2000, 2003 Free Software Foundation, Inc.
--Written by Kenneth Christiansen, 2000.
--
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--_EOF_
-- exit;
--}
--
--## Sub for printing usage information
--sub help {
-- print <<_EOF_;
--Usage: ${PROGRAM} [OPTION]... [FILENAME]
--Generates a header file from an XML source file.
--
--It grabs all strings between <_translatable_node> and its end tag in
--XML files. Read manpage (man ${PROGRAM}) for more info.
--
-- --type=TYPE Specify the file type of FILENAME. Currently supports:
-- "gettext/glade", "gettext/ini", "gettext/keys"
-- "gettext/rfc822deb", "gettext/schemas",
-- "gettext/scheme", "gettext/xml"
-- -l, --local Writes output into current working directory
-- (conflicts with --update)
-- --update Writes output into the same directory the source file
-- reside (conflicts with --local)
-- --srcdir Root of the source tree
-- -v, --version Output version information and exit
-- -h, --help Display this help and exit
-- -q, --quiet Quiet mode
--
--Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
--or send email to <xml-i18n-tools\@gnome.org>.
--_EOF_
-- exit;
--}
--
--## Sub for printing error messages
--sub error{
-- print STDERR "Try `${PROGRAM} --help' for more information.\n";
-- exit;
--}
--
--sub message {
-- print "Generating C format header file for translation.\n" unless $QUIET_ARG;
--}
--
--sub extract {
-- &determine_type;
--
-- &convert;
--
-- open OUT, ">$OUTFILE";
-- binmode (OUT) if $^O eq 'MSWin32';
-- &msg_write;
-- close OUT;
--
-- print "Wrote $OUTFILE\n" unless $QUIET_ARG;
--}
--
--sub convert {
--
-- ## Reading the file
-- {
-- local (*IN);
-- local $/; #slurp mode
-- open (IN, "<$SRCDIR_ARG/$FILE") || die "can't open $SRCDIR_ARG/$FILE: $!";
-- $input = <IN>;
-- }
--
-- &type_ini if $gettext_type eq "ini";
-- &type_keys if $gettext_type eq "keys";
-- &type_xml if $gettext_type eq "xml";
-- &type_glade if $gettext_type eq "glade";
-- &type_scheme if $gettext_type eq "scheme";
-- &type_schemas if $gettext_type eq "schemas";
-- &type_rfc822deb if $gettext_type eq "rfc822deb";
--}
--
--sub entity_decode_minimal
--{
-- local ($_) = @_;
--
-- s/&apos;/'/g; # '
-- s/&quot;/"/g; # "
-- s/&amp;/&/g;
--
-- return $_;
--}
--
--sub entity_decode
--{
-- local ($_) = @_;
--
-- s/&apos;/'/g; # '
-- s/&quot;/"/g; # "
-- s/&amp;/&/g;
-- s/&lt;/</g;
-- s/&gt;/>/g;
--
-- return $_;
--}
--
--sub escape_char
--{
-- return '\"' if $_ eq '"';
-- return '\n' if $_ eq "\n";
-- return '\\' if $_ eq '\\';
--
-- return $_;
--}
--
--sub escape
--{
-- my ($string) = @_;
-- return join "", map &escape_char, split //, $string;
--}
--
--sub type_ini {
-- ### For generic translatable desktop files ###
-- while ($input =~ /^_.*=(.*)$/mg) {
-- $messages{$1} = [];
-- }
--}
--
--sub type_keys {
-- ### For generic translatable mime/keys files ###
-- while ($input =~ /^\s*_\w+=(.*)$/mg) {
-- $messages{$1} = [];
-- }
--}
--
--sub type_xml {
-- ### For generic translatable XML files ###
-- my $tree = readXml($input);
-- parseTree(0, $tree);
--}
--
--sub print_var {
-- my $var = shift;
-- my $vartype = ref $var;
--
-- if ($vartype =~ /ARRAY/) {
-- my @arr = @{$var};
-- print "[ ";
-- foreach my $el (@arr) {
-- print_var($el);
-- print ", ";
-- }
-- print "] ";
-- } elsif ($vartype =~ /HASH/) {
-- my %hash = %{$var};
-- print "{ ";
-- foreach my $key (keys %hash) {
-- print "$key => ";
-- print_var($hash{$key});
-- print ", ";
-- }
-- print "} ";
-- } else {
-- print $var;
-- }
--}
--
--# Same syntax as getAttributeString in intltool-merge.in.in, similar logic (look for ## differences comment)
--sub getAttributeString
--{
-- my $sub = shift;
-- my $do_translate = shift || 1;
-- my $language = shift || "";
-- my $translate = shift;
-- my $result = "";
-- foreach my $e (reverse(sort(keys %{ $sub }))) {
-- my $key = $e;
-- my $string = $sub->{$e};
-- my $quote = '"';
--
-- $string =~ s/^[\s]+//;
-- $string =~ s/[\s]+$//;
--
-- if ($string =~ /^'.*'$/)
-- {
-- $quote = "'";
-- }
-- $string =~ s/^['"]//g;
-- $string =~ s/['"]$//g;
--
-- ## differences from intltool-merge.in.in
-- if ($key =~ /^_/) {
-- $comments{entity_decode($string)} = $XMLCOMMENT if $XMLCOMMENT;
-- $messages{entity_decode($string)} = [];
-- $$translate = 2;
-- }
-- ## differences end here from intltool-merge.in.in
-- $result .= " $key=$quote$string$quote";
-- }
-- return $result;
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub getXMLstring
--{
-- my $ref = shift;
-- my $spacepreserve = shift || 0;
-- my @list = @{ $ref };
-- my $result = "";
--
-- my $count = scalar(@list);
-- my $attrs = $list[0];
-- my $index = 1;
--
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
--
-- while ($index < $count) {
-- my $type = $list[$index];
-- my $content = $list[$index+1];
-- if (! $type ) {
-- # We've got CDATA
-- if ($content) {
-- # lets strip the whitespace here, and *ONLY* here
-- $content =~ s/\s+/ /gs if (!$spacepreserve);
-- $result .= $content;
-- }
-- } elsif ( "$type" ne "1" ) {
-- # We've got another element
-- $result .= "<$type";
-- $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
-- if ($content) {
-- my $subresult = getXMLstring($content, $spacepreserve);
-- if ($subresult) {
-- $result .= ">".$subresult . "</$type>";
-- } else {
-- $result .= "/>";
-- }
-- } else {
-- $result .= "/>";
-- }
-- }
-- $index += 2;
-- }
-- return $result;
--}
--
--# Verbatim copy from intltool-merge.in.in, except for MULTIPLE_OUTPUT handling removed
--# Translate list of nodes if necessary
--sub translate_subnodes
--{
-- my $fh = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $singlelang = shift || 0;
-- my $spacepreserve = shift || 0;
--
-- my @nodes = @{ $content };
--
-- my $count = scalar(@nodes);
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $nodes[$index];
-- my $rest = $nodes[$index+1];
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $index += 2;
-- }
--}
--
--# Based on traverse() in intltool-merge.in.in
--sub traverse
--{
-- my $fh = shift; # unused, to allow us to sync code between -merge and -extract
-- my $nodename = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $spacepreserve = shift || 0;
--
-- if ($nodename && "$nodename" eq "1") {
-- $XMLCOMMENT = $content;
-- } elsif ($nodename) {
-- # element
-- my @all = @{ $content };
-- my $attrs = shift @all;
-- my $translate = 0;
-- my $outattr = getAttributeString($attrs, 1, $language, \$translate);
--
-- if ($nodename =~ /^_/) {
-- $translate = 1;
-- $nodename =~ s/^_//;
-- }
-- my $lookup = '';
--
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- if ($translate) {
-- $lookup = getXMLstring($content, $spacepreserve);
-- if (!$spacepreserve) {
-- $lookup =~ s/^\s+//s;
-- $lookup =~ s/\s+$//s;
-- }
--
-- if ($lookup && $translate != 2) {
-- $comments{$lookup} = $XMLCOMMENT if $XMLCOMMENT;
-- $messages{$lookup} = [];
-- } elsif ($translate == 2) {
-- translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
-- }
-- } else {
-- $XMLCOMMENT = "";
-- my $count = scalar(@all);
-- if ($count > 0) {
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $all[$index];
-- my $rest = $all[$index+1];
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $index += 2;
-- }
-- }
-- }
-- $XMLCOMMENT = "";
-- }
--}
--
--
--# Verbatim copy from intltool-merge.in.in, $fh for compatibility
--sub parseTree
--{
-- my $fh = shift;
-- my $ref = shift;
-- my $language = shift || "";
--
-- my $name = shift @{ $ref };
-- my $cont = shift @{ $ref };
--
-- while (!$name || "$name" eq "1") {
-- $name = shift @{ $ref };
-- $cont = shift @{ $ref };
-- }
--
-- my $spacepreserve = 0;
-- my $attrs = @{$cont}[0];
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- traverse($fh, $name, $cont, $language, $spacepreserve);
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_comment
--{
-- my $expat = shift;
-- my $data = $expat->original_string();
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- $data =~ s/^<!--//s;
-- $data =~ s/-->$//s;
-- push @$clist, 1 => $data;
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_cdatastart
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- push @$clist, 0 => $expat->original_string();
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_cdataend
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- $clist->[$pos] .= $expat->original_string();
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_char
--{
-- my $expat = shift;
-- my $text = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- # Use original_string so that we retain escaped entities
-- # in CDATA sections.
-- #
-- if ($pos > 0 and $clist->[$pos - 1] eq '0') {
-- $clist->[$pos] .= $expat->original_string();
-- } else {
-- push @$clist, 0 => $expat->original_string();
-- }
--}
--
--# Verbatim copy from intltool-merge.in.in
--sub intltool_tree_start
--{
-- my $expat = shift;
-- my $tag = shift;
-- my @origlist = ();
--
-- # Use original_string so that we retain escaped entities
-- # in attribute values. We must convert the string to an
-- # @origlist array to conform to the structure of the Tree
-- # Style.
-- #
-- my @original_array = split /\x/, $expat->original_string();
-- my $source = $expat->original_string();
--
-- # Remove leading tag.
-- #
-- $source =~ s|^\s*<\s*(\S+)||s;
--
-- # Grab attribute key/value pairs and push onto @origlist array.
-- #
-- while ($source)
-- {
-- if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
-- push @origlist, $1;
-- push @origlist, '"' . $2 . '"';
-- }
-- elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
-- push @origlist, $1;
-- push @origlist, "'" . $2 . "'";
-- }
-- else
-- {
-- last;
-- }
-- }
--
-- my $ol = [ { @origlist } ];
--
-- push @{ $expat->{Lists} }, $expat->{Curlist};
-- push @{ $expat->{Curlist} }, $tag => $ol;
-- $expat->{Curlist} = $ol;
--}
--
--# Copied from intltool-merge.in.in and added comment handler.
--sub readXml
--{
-- my $xmldoc = shift || return;
-- my $ret = eval 'require XML::Parser';
-- if(!$ret) {
-- die "You must have XML::Parser installed to run $0\n\n";
-- }
-- my $xp = new XML::Parser(Style => 'Tree');
-- $xp->setHandlers(Char => \&intltool_tree_char);
-- $xp->setHandlers(Start => \&intltool_tree_start);
-- $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
-- $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
--
-- ## differences from intltool-merge.in.in
-- $xp->setHandlers(Comment => \&intltool_tree_comment);
-- ## differences end here from intltool-merge.in.in
--
-- my $tree = $xp->parse($xmldoc);
-- #print_var($tree);
--
--# <foo><!-- comment --><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
--# would be:
--# [foo, [{}, 1, "comment", head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar,
--# [{}, 0, "Howdy", ref, [{}]], 0, "do" ] ]
--
-- return $tree;
--}
--
--sub type_schemas {
-- ### For schemas XML files ###
--
-- # FIXME: We should handle escaped < (less than)
-- while ($input =~ /
-- <locale\ name="C">\s*
-- (<default>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/default>\s*)?
-- (<short>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/short>\s*)?
-- (<long>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/long>\s*)?
-- <\/locale>
-- /sgx) {
-- my @totranslate = ($3,$6,$9);
-- my @eachcomment = ($2,$5,$8);
-- foreach (@totranslate) {
-- my $currentcomment = shift @eachcomment;
-- next if !$_;
-- s/\s+/ /g;
-- $messages{entity_decode_minimal($_)} = [];
-- $comments{entity_decode_minimal($_)} = $currentcomment if (defined($currentcomment));
-- }
-- }
--}
--
--sub type_rfc822deb {
-- ### For rfc822-style Debian configuration files ###
--
-- my $lineno = 1;
-- my $type = '';
-- while ($input =~ /\G(.*?)(^|\n)(_+)([^:]+):[ \t]*(.*?)(?=\n\S|$)/sg)
-- {
-- my ($pre, $newline, $underscore, $tag, $text) = ($1, $2, $3, $4, $5);
-- while ($pre =~ m/\n/g)
-- {
-- $lineno ++;
-- }
-- $lineno += length($newline);
-- my @str_list = rfc822deb_split(length($underscore), $text);
-- for my $str (@str_list)
-- {
-- $strcount++;
-- $messages{$str} = [];
-- $loc{$str} = $lineno;
-- $count{$str} = $strcount;
-- my $usercomment = '';
-- while($pre =~ s/(^|\n)#([^\n]*)$//s)
-- {
-- $usercomment = "\n" . $2 . $usercomment;
-- }
-- $comments{$str} = $tag . $usercomment;
-- }
-- $lineno += ($text =~ s/\n//g);
-- }
--}
--
--sub rfc822deb_split {
-- # Debian defines a special way to deal with rfc822-style files:
-- # when a value contain newlines, it consists of
-- # 1. a short form (first line)
-- # 2. a long description, all lines begin with a space,
-- # and paragraphs are separated by a single dot on a line
-- # This routine returns an array of all paragraphs, and reformat
-- # them.
-- # When first argument is 2, the string is a comma separated list of
-- # values.
-- my $type = shift;
-- my $text = shift;
-- $text =~ s/^[ \t]//mg;
-- return (split(/, */, $text, 0)) if $type ne 1;
-- return ($text) if $text !~ /\n/;
--
-- $text =~ s/([^\n]*)\n//;
-- my @list = ($1);
-- my $str = '';
-- for my $line (split (/\n/, $text))
-- {
-- chomp $line;
-- if ($line =~ /^\.\s*$/)
-- {
-- # New paragraph
-- $str =~ s/\s*$//;
-- push(@list, $str);
-- $str = '';
-- }
-- elsif ($line =~ /^\s/)
-- {
-- # Line which must not be reformatted
-- $str .= "\n" if length ($str) && $str !~ /\n$/;
-- $line =~ s/\s+$//;
-- $str .= $line."\n";
-- }
-- else
-- {
-- # Continuation line, remove newline
-- $str .= " " if length ($str) && $str !~ /\n$/;
-- $str .= $line;
-- }
-- }
-- $str =~ s/\s*$//;
-- push(@list, $str) if length ($str);
-- return @list;
--}
--
--sub type_glade {
-- ### For translatable Glade XML files ###
--
-- my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message";
--
-- while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) {
-- # Glade sometimes uses tags that normally mark translatable things for
-- # little bits of non-translatable content. We work around this by not
-- # translating strings that only includes something like label4 or window1.
-- $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label|dialog)[0-9]+$/;
-- }
--
-- while ($input =~ /<items>(..[^<]*)<\/items>/sg) {
-- for my $item (split (/\n/, $1)) {
-- $messages{entity_decode($item)} = [];
-- }
-- }
--
-- ## handle new glade files
-- while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?:\s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) {
-- $messages{entity_decode($3)} = [] unless $3 =~ /^(window|label)[0-9]+$/;
-- if (defined($2) and !($3 =~ /^(window|label)[0-9]+$/)) {
-- $comments{entity_decode($3)} = entity_decode($2) ;
-- }
-- }
-- while ($input =~ /<atkaction\s+action_name="([^>]*)"\s+description="([^>]+)"\/>/sg) {
-- $messages{entity_decode_minimal($2)} = [];
-- }
--}
--
--sub type_scheme {
-- my ($line, $i, $state, $str, $trcomment, $char);
-- for $line (split(/\n/, $input)) {
-- $i = 0;
-- $state = 0; # 0 - nothing, 1 - string, 2 - translatable string
-- while ($i < length($line)) {
-- if (substr($line,$i,1) eq "\"") {
-- if ($state == 2) {
-- $comments{$str} = $trcomment if ($trcomment);
-- $messages{$str} = [];
-- $str = '';
-- $state = 0; $trcomment = "";
-- } elsif ($state == 1) {
-- $str = '';
-- $state = 0; $trcomment = "";
-- } else {
-- $state = 1;
-- $str = '';
-- if ($i>0 && substr($line,$i-1,1) eq '_') {
-- $state = 2;
-- }
-- }
-- } elsif (!$state) {
-- if (substr($line,$i,1) eq ";") {
-- $trcomment = substr($line,$i+1);
-- $trcomment =~ s/^;*\s*//;
-- $i = length($line);
-- } elsif ($trcomment && substr($line,$i,1) !~ /\s|\(|\)|_/) {
-- $trcomment = "";
-- }
-- } else {
-- if (substr($line,$i,1) eq "\\") {
-- $char = substr($line,$i+1,1);
-- if ($char ne "\"" && $char ne "\\") {
-- $str = $str . "\\";
-- }
-- $i++;
-- }
-- $str = $str . substr($line,$i,1);
-- }
-- $i++;
-- }
-- }
--}
--
--sub msg_write {
-- my @msgids;
-- if (%count)
-- {
-- @msgids = sort { $count{$a} <=> $count{$b} } keys %count;
-- }
-- else
-- {
-- @msgids = sort keys %messages;
-- }
-- for my $message (@msgids)
-- {
-- my $offsetlines = 1;
-- $offsetlines++ if $message =~ /%/;
-- if (defined ($comments{$message}))
-- {
-- while ($comments{$message} =~ m/\n/g)
-- {
-- $offsetlines++;
-- }
-- }
-- print OUT "# ".($loc{$message} - $offsetlines). " \"$FILE\"\n"
-- if defined $loc{$message};
-- print OUT "/* ".$comments{$message}." */\n"
-- if defined $comments{$message};
-- print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/;
--
-- my @lines = split (/\n/, $message, -1);
-- for (my $n = 0; $n < @lines; $n++)
-- {
-- if ($n == 0)
-- {
-- print OUT "char *s = N_(\"";
-- }
-- else
-- {
-- print OUT " \"";
-- }
--
-- print OUT escape($lines[$n]);
--
-- if ($n < @lines - 1)
-- {
-- print OUT "\\n\"\n";
-- }
-- else
-- {
-- print OUT "\");\n";
-- }
-- }
-- }
--}
--
-diff --git a/intltool-extract.in b/intltool-extract.in
-new file mode 120000
-index bb6c368..340fc8d
---- /dev/null
-+++ b/intltool-extract.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/intltool-extract.in
-\ No newline at end of file
-diff --git a/intltool-merge.in b/intltool-merge.in
-deleted file mode 100755
-index d0535ab..2238bbd
---- a/intltool-merge.in
-+++ /dev/null
-@@ -1,1356 +0,0 @@
--#!@INTLTOOL_PERL@ -w
--# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
--
--#
--# The Intltool Message Merger
--#
--# Copyright (C) 2000, 2003 Free Software Foundation.
--# Copyright (C) 2000, 2001 Eazel, Inc
--#
--# Intltool is free software; you can redistribute it and/or
--# modify it under the terms of the GNU General Public License
--# version 2 published by the Free Software Foundation.
--#
--# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA.
--#
--# As a special exception to the GNU General Public License, if you
--# distribute this file as part of a program that contains a
--# configuration script generated by Autoconf, you may include it under
--# the same distribution terms that you use for the rest of that program.
--#
--# Authors: Maciej Stachowiak <mjs@noisehavoc.org>
--# Kenneth Christiansen <kenneth@gnu.org>
--# Darin Adler <darin@bentspoon.com>
--#
--# Proper XML UTF-8'ification written by Cyrille Chepelov <chepelov@calixo.net>
--#
--
--## Release information
--my $PROGRAM = "intltool-merge";
--my $PACKAGE = "intltool";
--my $VERSION = "0.35.0";
--
--## Loaded modules
--use strict;
--use Getopt::Long;
--use Text::Wrap;
--use File::Basename;
--
--my $must_end_tag = -1;
--my $last_depth = -1;
--my $translation_depth = -1;
--my @tag_stack = ();
--my @entered_tag = ();
--my @translation_strings = ();
--my $leading_space = "";
--
--## Scalars used by the option stuff
--my $HELP_ARG = 0;
--my $VERSION_ARG = 0;
--my $BA_STYLE_ARG = 0;
--my $XML_STYLE_ARG = 0;
--my $KEYS_STYLE_ARG = 0;
--my $DESKTOP_STYLE_ARG = 0;
--my $SCHEMAS_STYLE_ARG = 0;
--my $RFC822DEB_STYLE_ARG = 0;
--my $QUIET_ARG = 0;
--my $PASS_THROUGH_ARG = 0;
--my $UTF8_ARG = 0;
--my $MULTIPLE_OUTPUT = 0;
--my $cache_file;
--
--## Handle options
--GetOptions
--(
-- "help" => \$HELP_ARG,
-- "version" => \$VERSION_ARG,
-- "quiet|q" => \$QUIET_ARG,
-- "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility
-- "ba-style|b" => \$BA_STYLE_ARG,
-- "xml-style|x" => \$XML_STYLE_ARG,
-- "keys-style|k" => \$KEYS_STYLE_ARG,
-- "desktop-style|d" => \$DESKTOP_STYLE_ARG,
-- "schemas-style|s" => \$SCHEMAS_STYLE_ARG,
-- "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG,
-- "pass-through|p" => \$PASS_THROUGH_ARG,
-- "utf8|u" => \$UTF8_ARG,
-- "multiple-output|m" => \$MULTIPLE_OUTPUT,
-- "cache|c=s" => \$cache_file
-- ) or &error;
--
--my $PO_DIR;
--my $FILE;
--my $OUTFILE;
--
--my %po_files_by_lang = ();
--my %translations = ();
--my $iconv = $ENV{"ICONV"} || $ENV{"INTLTOOL_ICONV"} || "@INTLTOOL_ICONV@";
--my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null');
--
--# Use this instead of \w for XML files to handle more possible characters.
--my $w = "[-A-Za-z0-9._:]";
--
--# XML quoted string contents
--my $q = "[^\\\"]*";
--
--## Check for options.
--
--if ($VERSION_ARG)
--{
-- &print_version;
--}
--elsif ($HELP_ARG)
--{
-- &print_help;
--}
--elsif ($BA_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &ba_merge_translations;
-- &finalize;
--}
--elsif ($XML_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &xml_merge_output;
-- &finalize;
--}
--elsif ($KEYS_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &keys_merge_translations;
-- &finalize;
--}
--elsif ($DESKTOP_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &desktop_merge_translations;
-- &finalize;
--}
--elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2)
--{
-- &utf8_sanity_check;
-- &preparation;
-- &print_message;
-- &schemas_merge_translations;
-- &finalize;
--}
--elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2)
--{
-- &preparation;
-- &print_message;
-- &rfc822deb_merge_translations;
-- &finalize;
--}
--else
--{
-- &print_help;
--}
--
--exit;
--
--## Sub for printing release information
--sub print_version
--{
-- print <<_EOF_;
--${PROGRAM} (${PACKAGE}) ${VERSION}
--Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen.
--
--Copyright (C) 2000-2003 Free Software Foundation, Inc.
--Copyright (C) 2000-2001 Eazel, Inc.
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--_EOF_
-- exit;
--}
--
--## Sub for printing usage information
--sub print_help
--{
-- print <<_EOF_;
--Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE
--Generates an output file that includes some localized attributes from an
--untranslated source file.
--
--Mandatory options: (exactly one must be specified)
-- -b, --ba-style includes translations in the bonobo-activation style
-- -d, --desktop-style includes translations in the desktop style
-- -k, --keys-style includes translations in the keys style
-- -s, --schemas-style includes translations in the schemas style
-- -r, --rfc822deb-style includes translations in the RFC822 style
-- -x, --xml-style includes translations in the standard xml style
--
--Other options:
-- -u, --utf8 convert all strings to UTF-8 before merging
-- (default for everything except RFC822 style)
-- -p, --pass-through deprecated, does nothing and issues a warning
-- -m, --multiple-output output one localized file per locale, instead of
-- a single file containing all localized elements
-- -c, --cache=FILE specify cache file name
-- (usually \$top_builddir/po/.intltool-merge-cache)
-- -q, --quiet suppress most messages
-- --help display this help and exit
-- --version output version information and exit
--
--Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
--or send email to <xml-i18n-tools\@gnome.org>.
--_EOF_
-- exit;
--}
--
--
--## Sub for printing error messages
--sub print_error
--{
-- print STDERR "Try `${PROGRAM} --help' for more information.\n";
-- exit;
--}
--
--
--sub print_message
--{
-- print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG;
--}
--
--
--sub preparation
--{
-- $PO_DIR = $ARGV[0];
-- $FILE = $ARGV[1];
-- $OUTFILE = $ARGV[2];
--
-- &gather_po_files;
-- &get_translation_database;
--}
--
--# General-purpose code for looking up translations in .po files
--
--sub po_file2lang
--{
-- my ($tmp) = @_;
-- $tmp =~ s/^.*\/(.*)\.po$/$1/;
-- return $tmp;
--}
--
--sub gather_po_files
--{
-- for my $po_file (glob "$PO_DIR/*.po") {
-- $po_files_by_lang{po_file2lang($po_file)} = $po_file;
-- }
--}
--
--sub get_local_charset
--{
-- my ($encoding) = @_;
-- my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "@INTLTOOL_LIBDIR@/charset.alias";
--
-- # seek character encoding aliases in charset.alias (glib)
--
-- if (open CHARSET_ALIAS, $alias_file)
-- {
-- while (<CHARSET_ALIAS>)
-- {
-- next if /^\#/;
-- return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i)
-- }
--
-- close CHARSET_ALIAS;
-- }
--
-- # if not found, return input string
--
-- return $encoding;
--}
--
--sub get_po_encoding
--{
-- my ($in_po_file) = @_;
-- my $encoding = "";
--
-- open IN_PO_FILE, $in_po_file or die;
-- while (<IN_PO_FILE>)
-- {
-- ## example: "Content-Type: text/plain; charset=ISO-8859-1\n"
-- if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/)
-- {
-- $encoding = $1;
-- last;
-- }
-- }
-- close IN_PO_FILE;
--
-- if (!$encoding)
-- {
-- print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG;
-- $encoding = "ISO-8859-1";
-- }
--
-- system ("$iconv -f $encoding -t UTF-8 <$devnull 2>$devnull");
-- if ($?) {
-- $encoding = get_local_charset($encoding);
-- }
--
-- return $encoding
--}
--
--sub utf8_sanity_check
--{
-- print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG;
-- $UTF8_ARG = 1;
--}
--
--sub get_translation_database
--{
-- if ($cache_file) {
-- &get_cached_translation_database;
-- } else {
-- &create_translation_database;
-- }
--}
--
--sub get_newest_po_age
--{
-- my $newest_age;
--
-- foreach my $file (values %po_files_by_lang)
-- {
-- my $file_age = -M $file;
-- $newest_age = $file_age if !$newest_age || $file_age < $newest_age;
-- }
--
-- $newest_age = 0 if !$newest_age;
--
-- return $newest_age;
--}
--
--sub create_cache
--{
-- print "Generating and caching the translation database\n" unless $QUIET_ARG;
--
-- &create_translation_database;
--
-- open CACHE, ">$cache_file" || die;
-- print CACHE join "\x01", %translations;
-- close CACHE;
--}
--
--sub load_cache
--{
-- print "Found cached translation database\n" unless $QUIET_ARG;
--
-- my $contents;
-- open CACHE, "<$cache_file" || die;
-- {
-- local $/;
-- $contents = <CACHE>;
-- }
-- close CACHE;
-- %translations = split "\x01", $contents;
--}
--
--sub get_cached_translation_database
--{
-- my $cache_file_age = -M $cache_file;
-- if (defined $cache_file_age)
-- {
-- if ($cache_file_age <= &get_newest_po_age)
-- {
-- &load_cache;
-- return;
-- }
-- print "Found too-old cached translation database\n" unless $QUIET_ARG;
-- }
--
-- &create_cache;
--}
--
--sub create_translation_database
--{
-- for my $lang (keys %po_files_by_lang)
-- {
-- my $po_file = $po_files_by_lang{$lang};
--
-- if ($UTF8_ARG)
-- {
-- my $encoding = get_po_encoding ($po_file);
--
-- if (lc $encoding eq "utf-8")
-- {
-- open PO_FILE, "<$po_file";
-- }
-- else
-- {
-- print "NOTICE: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;;
--
-- open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|";
-- }
-- }
-- else
-- {
-- open PO_FILE, "<$po_file";
-- }
--
-- my $nextfuzzy = 0;
-- my $inmsgid = 0;
-- my $inmsgstr = 0;
-- my $msgid = "";
-- my $msgstr = "";
--
-- while (<PO_FILE>)
-- {
-- $nextfuzzy = 1 if /^#, fuzzy/;
--
-- if (/^msgid "((\\.|[^\\])*)"/ )
-- {
-- $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
-- $msgid = "";
-- $msgstr = "";
--
-- if ($nextfuzzy) {
-- $inmsgid = 0;
-- } else {
-- $msgid = unescape_po_string($1);
-- $inmsgid = 1;
-- }
-- $inmsgstr = 0;
-- $nextfuzzy = 0;
-- }
--
-- if (/^msgstr "((\\.|[^\\])*)"/)
-- {
-- $msgstr = unescape_po_string($1);
-- $inmsgstr = 1;
-- $inmsgid = 0;
-- }
--
-- if (/^"((\\.|[^\\])*)"/)
-- {
-- $msgid .= unescape_po_string($1) if $inmsgid;
-- $msgstr .= unescape_po_string($1) if $inmsgstr;
-- }
-- }
-- $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
-- }
--}
--
--sub finalize
--{
--}
--
--sub unescape_one_sequence
--{
-- my ($sequence) = @_;
--
-- return "\\" if $sequence eq "\\\\";
-- return "\"" if $sequence eq "\\\"";
-- return "\n" if $sequence eq "\\n";
-- return "\r" if $sequence eq "\\r";
-- return "\t" if $sequence eq "\\t";
-- return "\b" if $sequence eq "\\b";
-- return "\f" if $sequence eq "\\f";
-- return "\a" if $sequence eq "\\a";
-- return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7)
--
-- return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/);
-- return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/);
--
-- # FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489
--
-- return $sequence;
--}
--
--sub unescape_po_string
--{
-- my ($string) = @_;
--
-- $string =~ s/(\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\.)/unescape_one_sequence($1)/eg;
--
-- return $string;
--}
--
--## NOTE: deal with < - &lt; but not > - &gt; because it seems its ok to have
--## > in the entity. For further info please look at #84738.
--sub entity_decode
--{
-- local ($_) = @_;
--
-- s/&apos;/'/g; # '
-- s/&quot;/"/g; # "
-- s/&amp;/&/g;
-- s/&lt;/</g;
--
-- return $_;
--}
--
--# entity_encode: (string)
--#
--# Encode the given string to XML format (encode '<' etc).
--
--sub entity_encode
--{
-- my ($pre_encoded) = @_;
--
-- my @list_of_chars = unpack ('C*', $pre_encoded);
--
-- # with UTF-8 we only encode minimalistic
-- return join ('', map (&entity_encode_int_minimalist, @list_of_chars));
--}
--
--sub entity_encode_int_minimalist
--{
-- return "&quot;" if $_ == 34;
-- return "&amp;" if $_ == 38;
-- return "&apos;" if $_ == 39;
-- return "&lt;" if $_ == 60;
-- return chr $_;
--}
--
--sub entity_encoded_translation
--{
-- my ($lang, $string) = @_;
--
-- my $translation = $translations{$lang, $string};
-- return $string if !$translation;
-- return entity_encode ($translation);
--}
--
--## XML (bonobo-activation specific) merge code
--
--sub ba_merge_translations
--{
-- my $source;
--
-- {
-- local $/; # slurp mode
-- open INPUT, "<$FILE" or die "can't open $FILE: $!";
-- $source = <INPUT>;
-- close INPUT;
-- }
--
-- open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!";
-- # Binmode so that selftest works ok if using a native Win32 Perl...
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s)
-- {
-- print OUTPUT $1;
--
-- my $node = $2 . "\n";
--
-- my @strings = ();
-- $_ = $node;
-- while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) {
-- push @strings, entity_decode($3);
-- }
-- print OUTPUT;
--
-- my %langs;
-- for my $string (@strings)
-- {
-- for my $lang (keys %po_files_by_lang)
-- {
-- $langs{$lang} = 1 if $translations{$lang, $string};
-- }
-- }
--
-- for my $lang (sort keys %langs)
-- {
-- $_ = $node;
-- s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s;
-- s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg;
-- print OUTPUT;
-- }
-- }
--
-- print OUTPUT $source;
--
-- close OUTPUT;
--}
--
--
--## XML (non-bonobo-activation) merge code
--
--
--# Process tag attributes
--# Only parameter is a HASH containing attributes -> values mapping
--sub getAttributeString
--{
-- my $sub = shift;
-- my $do_translate = shift || 0;
-- my $language = shift || "";
-- my $result = "";
-- my $translate = shift;
-- foreach my $e (reverse(sort(keys %{ $sub }))) {
-- my $key = $e;
-- my $string = $sub->{$e};
-- my $quote = '"';
--
-- $string =~ s/^[\s]+//;
-- $string =~ s/[\s]+$//;
--
-- if ($string =~ /^'.*'$/)
-- {
-- $quote = "'";
-- }
-- $string =~ s/^['"]//g;
-- $string =~ s/['"]$//g;
--
-- if ($do_translate && $key =~ /^_/) {
-- $key =~ s|^_||g;
-- if ($language) {
-- # Handle translation
-- my $decode_string = entity_decode($string);
-- my $translation = $translations{$language, $decode_string};
-- if ($translation) {
-- $translation = entity_encode($translation);
-- $string = $translation;
-- }
-- $$translate = 2;
-- } else {
-- $$translate = 2 if ($translate && (!$$translate)); # watch not to "overwrite" $translate
-- }
-- }
--
-- $result .= " $key=$quote$string$quote";
-- }
-- return $result;
--}
--
--# Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree
--sub getXMLstring
--{
-- my $ref = shift;
-- my $spacepreserve = shift || 0;
-- my @list = @{ $ref };
-- my $result = "";
--
-- my $count = scalar(@list);
-- my $attrs = $list[0];
-- my $index = 1;
--
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
--
-- while ($index < $count) {
-- my $type = $list[$index];
-- my $content = $list[$index+1];
-- if (! $type ) {
-- # We've got CDATA
-- if ($content) {
-- # lets strip the whitespace here, and *ONLY* here
-- $content =~ s/\s+/ /gs if (!$spacepreserve);
-- $result .= $content;
-- }
-- } elsif ( "$type" ne "1" ) {
-- # We've got another element
-- $result .= "<$type";
-- $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
-- if ($content) {
-- my $subresult = getXMLstring($content, $spacepreserve);
-- if ($subresult) {
-- $result .= ">".$subresult . "</$type>";
-- } else {
-- $result .= "/>";
-- }
-- } else {
-- $result .= "/>";
-- }
-- }
-- $index += 2;
-- }
-- return $result;
--}
--
--# Translate list of nodes if necessary
--sub translate_subnodes
--{
-- my $fh = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $singlelang = shift || 0;
-- my $spacepreserve = shift || 0;
--
-- my @nodes = @{ $content };
--
-- my $count = scalar(@nodes);
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $nodes[$index];
-- my $rest = $nodes[$index+1];
-- if ($singlelang) {
-- my $oldMO = $MULTIPLE_OUTPUT;
-- $MULTIPLE_OUTPUT = 1;
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $MULTIPLE_OUTPUT = $oldMO;
-- } else {
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- }
-- $index += 2;
-- }
--}
--
--sub isWellFormedXmlFragment
--{
-- my $ret = eval 'require XML::Parser';
-- if(!$ret) {
-- die "You must have XML::Parser installed to run $0\n\n";
-- }
--
-- my $fragment = shift;
-- return 0 if (!$fragment);
--
-- $fragment = "<root>$fragment</root>";
-- my $xp = new XML::Parser(Style => 'Tree');
-- my $tree = 0;
-- eval { $tree = $xp->parse($fragment); };
-- return $tree;
--}
--
--sub traverse
--{
-- my $fh = shift;
-- my $nodename = shift;
-- my $content = shift;
-- my $language = shift || "";
-- my $spacepreserve = shift || 0;
--
-- if (!$nodename) {
-- if ($content =~ /^[\s]*$/) {
-- $leading_space .= $content;
-- }
-- print $fh $content;
-- } else {
-- # element
-- my @all = @{ $content };
-- my $attrs = shift @all;
-- my $translate = 0;
-- my $outattr = getAttributeString($attrs, 1, $language, \$translate);
--
-- if ($nodename =~ /^_/) {
-- $translate = 1;
-- $nodename =~ s/^_//;
-- }
-- my $lookup = '';
--
-- $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- print $fh "<$nodename", $outattr;
-- if ($translate) {
-- $lookup = getXMLstring($content, $spacepreserve);
-- if (!$spacepreserve) {
-- $lookup =~ s/^\s+//s;
-- $lookup =~ s/\s+$//s;
-- }
--
-- if ($lookup || $translate == 2) {
-- my $translation = $translations{$language, $lookup} if isWellFormedXmlFragment($translations{$language, $lookup});
-- if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) {
-- $translation = $lookup if (!$translation);
-- print $fh " xml:lang=\"", $language, "\"" if $language;
-- print $fh ">";
-- if ($translate == 2) {
-- translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
-- } else {
-- print $fh $translation;
-- }
-- print $fh "</$nodename>";
--
-- return; # this means there will be no same translation with xml:lang="$language"...
-- # if we want them both, just remove this "return"
-- } else {
-- print $fh ">";
-- if ($translate == 2) {
-- translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
-- } else {
-- print $fh $lookup;
-- }
-- print $fh "</$nodename>";
-- }
-- } else {
-- print $fh "/>";
-- }
--
-- for my $lang (sort keys %po_files_by_lang) {
-- if ($MULTIPLE_OUTPUT && $lang ne "$language") {
-- next;
-- }
-- if ($lang) {
-- # Handle translation
-- #
-- my $translate = 0;
-- my $localattrs = getAttributeString($attrs, 1, $lang, \$translate);
-- my $translation = $translations{$lang, $lookup} if isWellFormedXmlFragment($translations{$lang, $lookup});
-- if ($translate && !$translation) {
-- $translation = $lookup;
-- }
--
-- if ($translation || $translate) {
-- print $fh "\n";
-- $leading_space =~ s/.*\n//g;
-- print $fh $leading_space;
-- print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">";
-- if ($translate == 2) {
-- translate_subnodes($fh, \@all, $lang, 1, $spacepreserve);
-- } else {
-- print $fh $translation;
-- }
-- print $fh "</$nodename>";
-- }
-- }
-- }
--
-- } else {
-- my $count = scalar(@all);
-- if ($count > 0) {
-- print $fh ">";
-- my $index = 0;
-- while ($index < $count) {
-- my $type = $all[$index];
-- my $rest = $all[$index+1];
-- traverse($fh, $type, $rest, $language, $spacepreserve);
-- $index += 2;
-- }
-- print $fh "</$nodename>";
-- } else {
-- print $fh "/>";
-- }
-- }
-- }
--}
--
--sub intltool_tree_comment
--{
-- my $expat = shift;
-- my $data = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- push @$clist, 1 => $data;
--}
--
--sub intltool_tree_cdatastart
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- push @$clist, 0 => $expat->original_string();
--}
--
--sub intltool_tree_cdataend
--{
-- my $expat = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- $clist->[$pos] .= $expat->original_string();
--}
--
--sub intltool_tree_char
--{
-- my $expat = shift;
-- my $text = shift;
-- my $clist = $expat->{Curlist};
-- my $pos = $#$clist;
--
-- # Use original_string so that we retain escaped entities
-- # in CDATA sections.
-- #
-- if ($pos > 0 and $clist->[$pos - 1] eq '0') {
-- $clist->[$pos] .= $expat->original_string();
-- } else {
-- push @$clist, 0 => $expat->original_string();
-- }
--}
--
--sub intltool_tree_start
--{
-- my $expat = shift;
-- my $tag = shift;
-- my @origlist = ();
--
-- # Use original_string so that we retain escaped entities
-- # in attribute values. We must convert the string to an
-- # @origlist array to conform to the structure of the Tree
-- # Style.
-- #
-- my @original_array = split /\x/, $expat->original_string();
-- my $source = $expat->original_string();
--
-- # Remove leading tag.
-- #
-- $source =~ s|^\s*<\s*(\S+)||s;
--
-- # Grab attribute key/value pairs and push onto @origlist array.
-- #
-- while ($source)
-- {
-- if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
-- push @origlist, $1;
-- push @origlist, '"' . $2 . '"';
-- }
-- elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
-- {
-- $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
-- push @origlist, $1;
-- push @origlist, "'" . $2 . "'";
-- }
-- else
-- {
-- last;
-- }
-- }
--
-- my $ol = [ { @origlist } ];
--
-- push @{ $expat->{Lists} }, $expat->{Curlist};
-- push @{ $expat->{Curlist} }, $tag => $ol;
-- $expat->{Curlist} = $ol;
--}
--
--sub readXml
--{
-- my $filename = shift || return;
-- if(!-f $filename) {
-- die "ERROR Cannot find filename: $filename\n";
-- }
--
-- my $ret = eval 'require XML::Parser';
-- if(!$ret) {
-- die "You must have XML::Parser installed to run $0\n\n";
-- }
-- my $xp = new XML::Parser(Style => 'Tree');
-- $xp->setHandlers(Char => \&intltool_tree_char);
-- $xp->setHandlers(Start => \&intltool_tree_start);
-- $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
-- $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
-- my $tree = $xp->parsefile($filename);
--
--# <foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
--# would be:
--# [foo, [{}, head, [{id => "a"}, 0, "Hello ", em, [{}, 0, "there"]], bar, [{},
--# 0, "Howdy", ref, [{}]], 0, "do" ] ]
--
-- return $tree;
--}
--
--sub print_header
--{
-- my $infile = shift;
-- my $fh = shift;
-- my $source;
--
-- if(!-f $infile) {
-- die "ERROR Cannot find filename: $infile\n";
-- }
--
-- print $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
-- {
-- local $/;
-- open DOCINPUT, "<${FILE}" or die;
-- $source = <DOCINPUT>;
-- close DOCINPUT;
-- }
-- if ($source =~ /(<!DOCTYPE.*\[.*\]\s*>)/s)
-- {
-- print $fh "$1\n";
-- }
-- elsif ($source =~ /(<!DOCTYPE[^>]*>)/s)
-- {
-- print $fh "$1\n";
-- }
--}
--
--sub parseTree
--{
-- my $fh = shift;
-- my $ref = shift;
-- my $language = shift || "";
--
-- my $name = shift @{ $ref };
-- my $cont = shift @{ $ref };
--
-- while (!$name || "$name" eq "1") {
-- $name = shift @{ $ref };
-- $cont = shift @{ $ref };
-- }
--
-- my $spacepreserve = 0;
-- my $attrs = @{$cont}[0];
-- $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
--
-- traverse($fh, $name, $cont, $language, $spacepreserve);
--}
--
--sub xml_merge_output
--{
-- my $source;
--
-- if ($MULTIPLE_OUTPUT) {
-- for my $lang (sort keys %po_files_by_lang) {
-- if ( ! -e $lang ) {
-- mkdir $lang or die "Cannot create subdirectory $lang: $!\n";
-- }
-- open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n";
-- binmode (OUTPUT) if $^O eq 'MSWin32';
-- my $tree = readXml($FILE);
-- print_header($FILE, \*OUTPUT);
-- parseTree(\*OUTPUT, $tree, $lang);
-- close OUTPUT;
-- print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG;
-- }
-- }
-- open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n";
-- binmode (OUTPUT) if $^O eq 'MSWin32';
-- my $tree = readXml($FILE);
-- print_header($FILE, \*OUTPUT);
-- parseTree(\*OUTPUT, $tree);
-- close OUTPUT;
-- print "CREATED $OUTFILE\n" unless $QUIET_ARG;
--}
--
--sub keys_merge_translations
--{
-- open INPUT, "<${FILE}" or die;
-- open OUTPUT, ">${OUTFILE}" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while (<INPUT>)
-- {
-- if (s/^(\s*)_(\w+=(.*))/$1$2/)
-- {
-- my $string = $3;
--
-- print OUTPUT;
--
-- my $non_translated_line = $_;
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $translation = $translations{$lang, $string};
-- next if !$translation;
--
-- $_ = $non_translated_line;
-- s/(\w+)=.*/[$lang]$1=$translation/;
-- print OUTPUT;
-- }
-- }
-- else
-- {
-- print OUTPUT;
-- }
-- }
--
-- close OUTPUT;
-- close INPUT;
--}
--
--sub desktop_merge_translations
--{
-- open INPUT, "<${FILE}" or die;
-- open OUTPUT, ">${OUTFILE}" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while (<INPUT>)
-- {
-- if (s/^(\s*)_(\w+=(.*))/$1$2/)
-- {
-- my $string = $3;
--
-- print OUTPUT;
--
-- my $non_translated_line = $_;
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $translation = $translations{$lang, $string};
-- next if !$translation;
--
-- $_ = $non_translated_line;
-- s/(\w+)=.*/${1}[$lang]=$translation/;
-- print OUTPUT;
-- }
-- }
-- else
-- {
-- print OUTPUT;
-- }
-- }
--
-- close OUTPUT;
-- close INPUT;
--}
--
--sub schemas_merge_translations
--{
-- my $source;
--
-- {
-- local $/; # slurp mode
-- open INPUT, "<$FILE" or die "can't open $FILE: $!";
-- $source = <INPUT>;
-- close INPUT;
-- }
--
-- open OUTPUT, ">$OUTFILE" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- # FIXME: support attribute translations
--
-- # Empty nodes never need translation, so unmark all of them.
-- # For example, <_foo/> is just replaced by <foo/>.
-- $source =~ s|<\s*_($w+)\s*/>|<$1/>|g;
--
-- while ($source =~ s/
-- (.*?)
-- (\s+)(<locale\ name="C">(\s*)
-- (<default>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/default>)?(\s*)
-- (<short>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/short>)?(\s*)
-- (<long>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/long>)?(\s*)
-- <\/locale>)
-- //sx)
-- {
-- print OUTPUT $1;
--
-- my $locale_start_spaces = $2 ? $2 : '';
-- my $default_spaces = $4 ? $4 : '';
-- my $short_spaces = $7 ? $7 : '';
-- my $long_spaces = $10 ? $10 : '';
-- my $locale_end_spaces = $13 ? $13 : '';
-- my $c_default_block = $3 ? $3 : '';
-- my $default_string = $6 ? $6 : '';
-- my $short_string = $9 ? $9 : '';
-- my $long_string = $12 ? $12 : '';
--
-- print OUTPUT "$locale_start_spaces$c_default_block";
--
-- $default_string =~ s/\s+/ /g;
-- $default_string = entity_decode($default_string);
-- $short_string =~ s/\s+/ /g;
-- $short_string = entity_decode($short_string);
-- $long_string =~ s/\s+/ /g;
-- $long_string = entity_decode($long_string);
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $default_translation = $translations{$lang, $default_string};
-- my $short_translation = $translations{$lang, $short_string};
-- my $long_translation = $translations{$lang, $long_string};
--
-- next if (!$default_translation && !$short_translation &&
-- !$long_translation);
--
-- print OUTPUT "\n$locale_start_spaces<locale name=\"$lang\">";
--
-- print OUTPUT "$default_spaces";
--
-- if ($default_translation)
-- {
-- $default_translation = entity_encode($default_translation);
-- print OUTPUT "<default>$default_translation</default>";
-- }
--
-- print OUTPUT "$short_spaces";
--
-- if ($short_translation)
-- {
-- $short_translation = entity_encode($short_translation);
-- print OUTPUT "<short>$short_translation</short>";
-- }
--
-- print OUTPUT "$long_spaces";
--
-- if ($long_translation)
-- {
-- $long_translation = entity_encode($long_translation);
-- print OUTPUT "<long>$long_translation</long>";
-- }
--
-- print OUTPUT "$locale_end_spaces</locale>";
-- }
-- }
--
-- print OUTPUT $source;
--
-- close OUTPUT;
--}
--
--sub rfc822deb_merge_translations
--{
-- my %encodings = ();
-- for my $lang (keys %po_files_by_lang) {
-- $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang}));
-- }
--
-- my $source;
--
-- $Text::Wrap::huge = 'overflow';
-- $Text::Wrap::break = qr/\n|\s(?=\S)/;
--
-- {
-- local $/; # slurp mode
-- open INPUT, "<$FILE" or die "can't open $FILE: $!";
-- $source = <INPUT>;
-- close INPUT;
-- }
--
-- open OUTPUT, ">${OUTFILE}" or die;
-- binmode (OUTPUT) if $^O eq 'MSWin32';
--
-- while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg)
-- {
-- my $sep = $1;
-- my $non_translated_line = $3.$4;
-- my $string = $5;
-- my $underscore = length($2);
-- next if $underscore eq 0 && $non_translated_line =~ /^#/;
-- # Remove [] dummy strings
-- my $stripped = $string;
-- $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2;
-- $stripped =~ s/\[\s[^\[\]]*\]$//;
-- $non_translated_line .= $stripped;
--
-- print OUTPUT $sep.$non_translated_line;
--
-- if ($underscore)
-- {
-- my @str_list = rfc822deb_split($underscore, $string);
--
-- for my $lang (sort keys %po_files_by_lang)
-- {
-- my $is_translated = 1;
-- my $str_translated = '';
-- my $first = 1;
--
-- for my $str (@str_list)
-- {
-- my $translation = $translations{$lang, $str};
--
-- if (!$translation)
-- {
-- $is_translated = 0;
-- last;
-- }
--
-- # $translation may also contain [] dummy
-- # strings, mostly to indicate an empty string
-- $translation =~ s/\[\s[^\[\]]*\]$//;
--
-- if ($first)
-- {
-- if ($underscore eq 2)
-- {
-- $str_translated .= $translation;
-- }
-- else
-- {
-- $str_translated .=
-- Text::Tabs::expand($translation) .
-- "\n";
-- }
-- }
-- else
-- {
-- if ($underscore eq 2)
-- {
-- $str_translated .= ', ' . $translation;
-- }
-- else
-- {
-- $str_translated .= Text::Tabs::expand(
-- Text::Wrap::wrap(' ', ' ', $translation)) .
-- "\n .\n";
-- }
-- }
-- $first = 0;
--
-- # To fix some problems with Text::Wrap::wrap
-- $str_translated =~ s/(\n )+\n/\n .\n/g;
-- }
-- next unless $is_translated;
--
-- $str_translated =~ s/\n \.\n$//;
-- $str_translated =~ s/\s+$//;
--
-- $_ = $non_translated_line;
-- s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s;
-- print OUTPUT;
-- }
-- }
-- }
-- print OUTPUT "\n";
--
-- close OUTPUT;
-- close INPUT;
--}
--
--sub rfc822deb_split
--{
-- # Debian defines a special way to deal with rfc822-style files:
-- # when a value contain newlines, it consists of
-- # 1. a short form (first line)
-- # 2. a long description, all lines begin with a space,
-- # and paragraphs are separated by a single dot on a line
-- # This routine returns an array of all paragraphs, and reformat
-- # them.
-- # When first argument is 2, the string is a comma separated list of
-- # values.
-- my $type = shift;
-- my $text = shift;
-- $text =~ s/^[ \t]//mg;
-- return (split(/, */, $text, 0)) if $type ne 1;
-- return ($text) if $text !~ /\n/;
--
-- $text =~ s/([^\n]*)\n//;
-- my @list = ($1);
-- my $str = '';
--
-- for my $line (split (/\n/, $text))
-- {
-- chomp $line;
-- if ($line =~ /^\.\s*$/)
-- {
-- # New paragraph
-- $str =~ s/\s*$//;
-- push(@list, $str);
-- $str = '';
-- }
-- elsif ($line =~ /^\s/)
-- {
-- # Line which must not be reformatted
-- $str .= "\n" if length ($str) && $str !~ /\n$/;
-- $line =~ s/\s+$//;
-- $str .= $line."\n";
-- }
-- else
-- {
-- # Continuation line, remove newline
-- $str .= " " if length ($str) && $str !~ /\n$/;
-- $str .= $line;
-- }
-- }
--
-- $str =~ s/\s*$//;
-- push(@list, $str) if length ($str);
--
-- return @list;
--}
--
-diff --git a/intltool-merge.in b/intltool-merge.in
-new file mode 120000
-index d0535ab..2238bbd
---- /dev/null
-+++ b/intltool-merge.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/intltool-merge.in
-\ No newline at end of file
-diff --git a/intltool-update.in b/intltool-update.in
-deleted file mode 100755
-index 661d8fe..0b1800f
---- a/intltool-update.in
-+++ /dev/null
-@@ -1,1089 +0,0 @@
--#!@INTLTOOL_PERL@ -w
--# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4 -*-
--
--#
--# The Intltool Message Updater
--#
--# Copyright (C) 2000-2003 Free Software Foundation.
--#
--# Intltool is free software; you can redistribute it and/or
--# modify it under the terms of the GNU General Public License
--# version 2 published by the Free Software Foundation.
--#
--# Intltool 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., 675 Mass Ave, Cambridge, MA 02139, USA.
--#
--# As a special exception to the GNU General Public License, if you
--# distribute this file as part of a program that contains a
--# configuration script generated by Autoconf, you may include it under
--# the same distribution terms that you use for the rest of that program.
--#
--# Authors: Kenneth Christiansen <kenneth@gnu.org>
--# Maciej Stachowiak
--# Darin Adler <darin@bentspoon.com>
--
--## Release information
--my $PROGRAM = "intltool-update";
--my $VERSION = "0.35.0";
--my $PACKAGE = "intltool";
--
--## Loaded modules
--use strict;
--use Getopt::Long;
--use Cwd;
--use File::Copy;
--use File::Find;
--
--## Scalars used by the option stuff
--my $HELP_ARG = 0;
--my $VERSION_ARG = 0;
--my $DIST_ARG = 0;
--my $POT_ARG = 0;
--my $HEADERS_ARG = 0;
--my $MAINTAIN_ARG = 0;
--my $REPORT_ARG = 0;
--my $VERBOSE = 0;
--my $GETTEXT_PACKAGE = "";
--my $OUTPUT_FILE = "";
--
--my @languages;
--my %varhash = ();
--my %po_files_by_lang = ();
--
--# Regular expressions to categorize file types.
--# FIXME: Please check if the following is correct
--
--my $xml_support =
--"xml(?:\\.in)*|". # http://www.w3.org/XML/ (Note: .in is not required)
--"ui|". # Bonobo specific - User Interface desc. files
--"lang|". # ?
--"glade2?(?:\\.in)*|". # Glade specific - User Interface desc. files (Note: .in is not required)
--"scm(?:\\.in)*|". # ? (Note: .in is not required)
--"oaf(?:\\.in)+|". # DEPRECATED: Replaces by Bonobo .server files
--"etspec|". # ?
--"server(?:\\.in)+|". # Bonobo specific
--"sheet(?:\\.in)+|". # ?
--"schemas(?:\\.in)+|". # GConf specific
--"pong(?:\\.in)+|". # DEPRECATED: PONG is not used [by GNOME] any longer.
--"kbd(?:\\.in)+"; # GOK specific.
--
--my $ini_support =
--"icon(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec
--"desktop(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec
--"caves(?:\\.in)+|". # GNOME Games specific
--"directory(?:\\.in)+|". # http://www.freedesktop.org/Standards/menu-spec
--"soundlist(?:\\.in)+|". # GNOME specific
--"keys(?:\\.in)+|". # GNOME Mime database specific
--"theme(?:\\.in)+|". # http://www.freedesktop.org/Standards/icon-theme-spec
--"service(?:\\.in)+"; # DBus specific
--
--my $buildin_gettext_support =
--"c|y|cs|cc|cpp|c\\+\\+|h|hh|gob|py";
--
--## Always flush buffer when printing
--$| = 1;
--
--## Sometimes the source tree will be rooted somewhere else.
--my $SRCDIR = ".";
--my $POTFILES_in;
--
--$SRCDIR = $ENV{"srcdir"} if $ENV{"srcdir"};
--$POTFILES_in = "<$SRCDIR/POTFILES.in";
--
--my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null');
--
--## Handle options
--GetOptions
--(
-- "help" => \$HELP_ARG,
-- "version" => \$VERSION_ARG,
-- "dist|d" => \$DIST_ARG,
-- "pot|p" => \$POT_ARG,
-- "headers|s" => \$HEADERS_ARG,
-- "maintain|m" => \$MAINTAIN_ARG,
-- "report|r" => \$REPORT_ARG,
-- "verbose|x" => \$VERBOSE,
-- "gettext-package|g=s" => \$GETTEXT_PACKAGE,
-- "output-file|o=s" => \$OUTPUT_FILE,
-- ) or &Console_WriteError_InvalidOption;
--
--&Console_Write_IntltoolHelp if $HELP_ARG;
--&Console_Write_IntltoolVersion if $VERSION_ARG;
--
--my $arg_count = ($DIST_ARG > 0)
-- + ($POT_ARG > 0)
-- + ($HEADERS_ARG > 0)
-- + ($MAINTAIN_ARG > 0)
-- + ($REPORT_ARG > 0);
--
--&Console_Write_IntltoolHelp if $arg_count > 1;
--
--# --version and --help don't require a module name
--my $MODULE = $GETTEXT_PACKAGE || &FindPackageName || "unknown";
--
--if ($POT_ARG)
--{
-- &GenerateHeaders;
-- &GeneratePOTemplate;
--}
--elsif ($HEADERS_ARG)
--{
-- &GenerateHeaders;
--}
--elsif ($MAINTAIN_ARG)
--{
-- &FindLeftoutFiles;
--}
--elsif ($REPORT_ARG)
--{
-- &GenerateHeaders;
-- &GeneratePOTemplate;
-- &Console_Write_CoverageReport;
--}
--elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/)
--{
-- my $lang = $ARGV[0];
--
-- ## Report error if the language file supplied
-- ## to the command line is non-existent
-- &Console_WriteError_NotExisting("$SRCDIR/$lang.po")
-- if ! -s "$SRCDIR/$lang.po";
--
-- if (!$DIST_ARG)
-- {
-- print "Working, please wait..." if $VERBOSE;
-- &GenerateHeaders;
-- &GeneratePOTemplate;
-- }
-- &POFile_Update ($lang, $OUTPUT_FILE);
-- &Console_Write_TranslationStatus ($lang, $OUTPUT_FILE);
--}
--else
--{
-- &Console_Write_IntltoolHelp;
--}
--
--exit;
--
--#########
--
--sub Console_Write_IntltoolVersion
--{
-- print <<_EOF_;
--${PROGRAM} (${PACKAGE}) $VERSION
--Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.
--
--Copyright (C) 2000-2003 Free Software Foundation, Inc.
--This is free software; see the source for copying conditions. There is NO
--warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--_EOF_
-- exit;
--}
--
--sub Console_Write_IntltoolHelp
--{
-- print <<_EOF_;
--Usage: ${PROGRAM} [OPTION]... LANGCODE
--Updates PO template files and merge them with the translations.
--
--Mode of operation (only one is allowed):
-- -p, --pot generate the PO template only
-- -s, --headers generate the header files in POTFILES.in
-- -m, --maintain search for left out files from POTFILES.in
-- -r, --report display a status report for the module
-- -d, --dist merge LANGCODE.po with existing PO template
--
--Extra options:
-- -g, --gettext-package=NAME override PO template name, useful with --pot
-- -o, --output-file=FILE write merged translation to FILE
-- -x, --verbose display lots of feedback
-- --help display this help and exit
-- --version output version information and exit
--
--Examples of use:
--${PROGRAM} --pot just create a new PO template
--${PROGRAM} xy create new PO template and merge xy.po with it
--
--Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
--or send email to <xml-i18n-tools\@gnome.org>.
--_EOF_
-- exit;
--}
--
--sub echo_n
--{
-- my $str = shift;
-- my $ret = `echo "$str"`;
--
-- $ret =~ s/\n$//; # do we need the "s" flag?
--
-- return $ret;
--}
--
--sub POFile_DetermineType ($)
--{
-- my $type = $_;
-- my $gettext_type;
--
-- my $xml_regex = "(?:" . $xml_support . ")";
-- my $ini_regex = "(?:" . $ini_support . ")";
-- my $buildin_regex = "(?:" . $buildin_gettext_support . ")";
--
-- if ($type =~ /\[type: gettext\/([^\]].*)]/)
-- {
-- $gettext_type=$1;
-- }
-- elsif ($type =~ /schemas(\.in)+$/)
-- {
-- $gettext_type="schemas";
-- }
-- elsif ($type =~ /glade2?(\.in)*$/)
-- {
-- $gettext_type="glade";
-- }
-- elsif ($type =~ /scm(\.in)*$/)
-- {
-- $gettext_type="scheme";
-- }
-- elsif ($type =~ /keys(\.in)+$/)
-- {
-- $gettext_type="keys";
-- }
--
-- # bucket types
--
-- elsif ($type =~ /$xml_regex$/)
-- {
-- $gettext_type="xml";
-- }
-- elsif ($type =~ /$ini_regex$/)
-- {
-- $gettext_type="ini";
-- }
-- elsif ($type =~ /$buildin_regex$/)
-- {
-- $gettext_type="buildin";
-- }
-- else
-- {
-- $gettext_type="unknown";
-- }
--
-- return "gettext\/$gettext_type";
--}
--
--sub TextFile_DetermineEncoding ($)
--{
-- my $gettext_code="ASCII"; # All files are ASCII by default
-- my $filetype=`file $_ | cut -d ' ' -f 2`;
--
-- if ($? eq "0")
-- {
-- if ($filetype =~ /^(ISO|UTF)/)
-- {
-- chomp ($gettext_code = $filetype);
-- }
-- elsif ($filetype =~ /^XML/)
-- {
-- $gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8
-- }
-- }
--
-- return $gettext_code;
--}
--
--sub isNotValidMissing
--{
-- my ($file) = @_;
--
-- return if $file =~ /^\{arch\}\/.*$/;
-- return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/;
--}
--
--sub FindLeftoutFiles
--{
-- my (@buf_i18n_plain,
-- @buf_i18n_xml,
-- @buf_i18n_xml_unmarked,
-- @buf_i18n_ini,
-- @buf_potfiles,
-- @buf_potfiles_ignore,
-- @buf_allfiles,
-- @buf_allfiles_sorted,
-- @buf_potfiles_sorted
-- );
--
-- ## Search and find all translatable files
-- find sub {
-- push @buf_i18n_plain, "$File::Find::name" if /\.($buildin_gettext_support)$/;
-- push @buf_i18n_xml, "$File::Find::name" if /\.($xml_support)$/;
-- push @buf_i18n_ini, "$File::Find::name" if /\.($ini_support)$/;
-- push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/;
-- }, "..";
--
--
-- open POTFILES, $POTFILES_in or die "$PROGRAM: there's no POTFILES.in!\n";
-- @buf_potfiles = grep !/^(#|\s*$)/, <POTFILES>;
-- close POTFILES;
--
-- foreach (@buf_potfiles) {
-- s/^\[.*]\s*//;
-- }
--
-- print "Searching for missing translatable files...\n" if $VERBOSE;
--
-- ## Check if we should ignore some found files, when
-- ## comparing with POTFILES.in
-- foreach my $ignore ("POTFILES.skip", "POTFILES.ignore")
-- {
-- (-s $ignore) or next;
--
-- if ("$ignore" eq "POTFILES.ignore")
-- {
-- print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n".
-- "content of this file to POTFILES.skip.\n";
-- }
--
-- print "Found $ignore: Ignoring files...\n" if $VERBOSE;
-- open FILE, "<$ignore" or die "ERROR: Failed to open $ignore!\n";
--
-- while (<FILE>)
-- {
-- push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/;
-- }
-- close FILE;
--
-- @buf_potfiles = (@buf_potfiles_ignore, @buf_potfiles);
-- }
--
-- foreach my $file (@buf_i18n_plain)
-- {
-- my $in_comment = 0;
-- my $in_macro = 0;
--
-- open FILE, "<$file";
-- while (<FILE>)
-- {
-- # Handle continued multi-line comment.
-- if ($in_comment)
-- {
-- next unless s-.*\*/--;
-- $in_comment = 0;
-- }
--
-- # Handle continued macro.
-- if ($in_macro)
-- {
-- $in_macro = 0 unless /\\$/;
-- next;
-- }
--
-- # Handle start of macro (or any preprocessor directive).
-- if (/^\s*\#/)
-- {
-- $in_macro = 1 if /^([^\\]|\\.)*\\$/;
-- next;
-- }
--
-- # Handle comments and quoted text.
-- while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy
-- {
-- my $match = $1;
-- if ($match eq "/*")
-- {
-- if (!s-/\*.*?\*/--)
-- {
-- s-/\*.*--;
-- $in_comment = 1;
-- }
-- }
-- elsif ($match eq "//")
-- {
-- s-//.*--;
-- }
-- else # ' or "
-- {
-- if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-)
-- {
-- warn "mismatched quotes at line $. in $file\n";
-- s-$match.*--;
-- }
-- }
-- }
--
-- if (/\.GetString ?\(QUOTEDTEXT/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- ## Remove the first 3 chars and add newline
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
--
-- if (/_\(QUOTEDTEXT/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- ## Remove the first 3 chars and add newline
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
-- }
-- close FILE;
-- }
--
-- foreach my $file (@buf_i18n_xml)
-- {
-- open FILE, "<$file";
--
-- while (<FILE>)
-- {
-- # FIXME: share the pattern matching code with intltool-extract
-- if (/\s_[-A-Za-z0-9._:]+\s*=\s*\"([^"]+)\"/ || /<_[^>]+>/ || /translatable=\"yes\"/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
-- }
-- close FILE;
-- }
--
-- foreach my $file (@buf_i18n_ini)
-- {
-- open FILE, "<$file";
-- while (<FILE>)
-- {
-- if (/_(.*)=/)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- last;
-- }
-- }
-- close FILE;
-- }
--
-- foreach my $file (@buf_i18n_xml_unmarked)
-- {
-- if (defined isNotValidMissing (unpack("x3 A*", $file))) {
-- push @buf_allfiles, unpack("x3 A*", $file) . "\n";
-- }
-- }
--
--
-- @buf_allfiles_sorted = sort (@buf_allfiles);
-- @buf_potfiles_sorted = sort (@buf_potfiles);
--
-- my %in2;
-- foreach (@buf_potfiles_sorted)
-- {
-- $in2{$_} = 1;
-- }
--
-- my @result;
--
-- foreach (@buf_allfiles_sorted)
-- {
-- if (!exists($in2{$_}))
-- {
-- push @result, $_
-- }
-- }
--
-- my @buf_potfiles_notexist;
--
-- foreach (@buf_potfiles_sorted)
-- {
-- chomp (my $dummy = $_);
-- if ("$dummy" ne "" and ! -f "../$dummy")
-- {
-- push @buf_potfiles_notexist, $_;
-- }
-- }
--
-- ## Save file with information about the files missing
-- ## if any, and give information about this procedure.
-- if (@result + @buf_potfiles_notexist > 0)
-- {
-- if (@result)
-- {
-- print "\n" if $VERBOSE;
-- unlink "missing";
-- open OUT, ">missing";
-- print OUT @result;
-- close OUT;
-- warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n".
-- "\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n";
-- print STDERR @result, "\n";
-- warn "If some of these files are left out on purpose then please add them to\n".
-- "POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n".
-- "of left out files has been written in the current directory.\n";
-- }
-- if (@buf_potfiles_notexist)
-- {
-- unlink "notexist";
-- open OUT, ">notexist";
-- print OUT @buf_potfiles_notexist;
-- close OUT;
-- warn "\n" if ($VERBOSE or @result);
-- warn "\e[1mThe following files do not exist anymore:\e[0m\n\n";
-- warn @buf_potfiles_notexist, "\n";
-- warn "Please remove them from POTFILES.in or POTFILES.skip. A file \e[1m'notexist'\e[0m\n".
-- "containing this list of absent files has been written in the current directory.\n";
-- }
-- }
--
-- ## If there is nothing to complain about, notify the user
-- else {
-- print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE;
-- }
--}
--
--sub Console_WriteError_InvalidOption
--{
-- ## Handle invalid arguments
-- print STDERR "Try `${PROGRAM} --help' for more information.\n";
-- exit 1;
--}
--
--sub GenerateHeaders
--{
-- my $EXTRACT = "@INTLTOOL_EXTRACT@";
-- chomp $EXTRACT;
--
-- $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} if $ENV{"INTLTOOL_EXTRACT"};
--
-- ## Generate the .h header files, so we can allow glade and
-- ## xml translation support
-- if (! -x "$EXTRACT")
-- {
-- print STDERR "\n *** The intltool-extract script wasn't found!"
-- ."\n *** Without it, intltool-update can not generate files.\n";
-- exit;
-- }
-- else
-- {
-- open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n";
--
-- while (<FILE>)
-- {
-- chomp;
-- next if /^\[\s*encoding/;
--
-- ## Find xml files in POTFILES.in and generate the
-- ## files with help from the extract script
--
-- my $gettext_type= &POFile_DetermineType ($1);
--
-- if (/\.($xml_support|$ini_support)$/ || /^\[/)
-- {
-- s/^\[[^\[].*]\s*//;
--
-- my $filename = "../$_";
--
-- if ($VERBOSE)
-- {
-- system ($EXTRACT, "--update", "--srcdir=$SRCDIR",
-- "--type=$gettext_type", $filename);
-- }
-- else
-- {
-- system ($EXTRACT, "--update", "--type=$gettext_type",
-- "--srcdir=$SRCDIR", "--quiet", $filename);
-- }
-- }
-- }
-- close FILE;
-- }
--}
--
--#
--# Generate .pot file from POTFILES.in
--#
--sub GeneratePOTemplate
--{
-- my $XGETTEXT = $ENV{"XGETTEXT"} || "@INTLTOOL_XGETTEXT@";
-- my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || '';
-- chomp $XGETTEXT;
--
-- if (! -x $XGETTEXT)
-- {
-- print STDERR " *** xgettext is not found on this system!\n".
-- " *** Without it, intltool-update can not extract strings.\n";
-- exit;
-- }
--
-- print "Building $MODULE.pot...\n" if $VERBOSE;
--
-- open INFILE, $POTFILES_in;
-- unlink "POTFILES.in.temp";
-- open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing");
--
-- my $gettext_support_nonascii = 0;
--
-- # checks for GNU gettext >= 0.12
-- my $dummy = `$XGETTEXT --version --from-code=UTF-8 >$devnull 2>$devnull`;
-- if ($? == 0)
-- {
-- $gettext_support_nonascii = 1;
-- }
-- else
-- {
-- # urge everybody to upgrade gettext
-- print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n".
-- " strings. That means you should install a version of gettext\n".
-- " that supports non-ASCII strings (such as GNU gettext >= 0.12),\n".
-- " or have to let non-ASCII strings untranslated. (If there is any)\n";
-- }
--
-- my $encoding = "ASCII";
-- my $forced_gettext_code;
-- my @temp_headers;
-- my $encoding_problem_is_reported = 0;
--
-- while (<INFILE>)
-- {
-- next if (/^#/ or /^\s*$/);
--
-- chomp;
--
-- my $gettext_code;
--
-- if (/^\[\s*encoding:\s*(.*)\s*\]/)
-- {
-- $forced_gettext_code=$1;
-- }
-- elsif (/\.($xml_support|$ini_support)$/ || /^\[/)
-- {
-- s/^\[.*]\s*//;
-- print OUTFILE "../$_.h\n";
-- push @temp_headers, "../$_.h";
-- $gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code);
-- }
-- else
-- {
-- if ($SRCDIR eq ".") {
-- print OUTFILE "../$_\n";
-- } else {
-- print OUTFILE "$SRCDIR/../$_\n";
-- }
-- $gettext_code = &TextFile_DetermineEncoding ("../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code);
-- }
--
-- next if (! $gettext_support_nonascii);
--
-- if (defined $forced_gettext_code)
-- {
-- $encoding=$forced_gettext_code;
-- }
-- elsif (defined $gettext_code and "$encoding" ne "$gettext_code")
-- {
-- if ($encoding eq "ASCII")
-- {
-- $encoding=$gettext_code;
-- }
-- elsif ($gettext_code ne "ASCII")
-- {
-- # Only report once because the message is quite long
-- if (! $encoding_problem_is_reported)
-- {
-- print STDERR "WARNING: You should use the same file encoding for all your project files,\n".
-- " but $PROGRAM thinks that most of the source files are in\n".
-- " $encoding encoding, while \"$_\" is (likely) in\n".
-- " $gettext_code encoding. If you are sure that all translatable strings\n".
-- " are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n".
-- " line to POTFILES.in:\n\n".
-- " [encoding: UTF-8]\n\n".
-- " and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n".
-- "(such warning message will only be reported once.)\n";
-- $encoding_problem_is_reported = 1;
-- }
-- }
-- }
-- }
--
-- close OUTFILE;
-- close INFILE;
--
-- unlink "$MODULE.pot";
-- my @xgettext_argument=("$XGETTEXT",
-- "--add-comments",
-- "--directory\=\.",
-- "--output\=$MODULE\.pot",
-- "--files-from\=\.\/POTFILES\.in\.temp");
-- my $XGETTEXT_KEYWORDS = &FindPOTKeywords;
-- push @xgettext_argument, $XGETTEXT_KEYWORDS;
-- my $MSGID_BUGS_ADDRESS = &FindMakevarsBugAddress;
-- push @xgettext_argument, "--msgid-bugs-address\=$MSGID_BUGS_ADDRESS" if $MSGID_BUGS_ADDRESS;
-- push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii);
-- push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS;
-- my $xgettext_command = join ' ', @xgettext_argument;
--
-- # intercept xgettext error message
-- print "Running $xgettext_command\n" if $VERBOSE;
-- my $xgettext_error_msg = `$xgettext_command 2>\&1`;
-- my $command_failed = $?;
--
-- unlink "POTFILES.in.temp";
--
-- print "Removing generated header (.h) files..." if $VERBOSE;
-- unlink foreach (@temp_headers);
-- print "done.\n" if $VERBOSE;
--
-- if (! $command_failed)
-- {
-- if (! -e "$MODULE.pot")
-- {
-- print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE;
-- }
-- else
-- {
-- print "Wrote $MODULE.pot\n" if $VERBOSE;
-- }
-- }
-- else
-- {
-- if ($xgettext_error_msg =~ /--from-code/)
-- {
-- # replace non-ASCII error message with a more useful one.
-- print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n".
-- " string marked for translation. Please make sure that all strings marked\n".
-- " for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n".
-- " following line to POTFILES.in and rerun $PROGRAM:\n\n".
-- " [encoding: UTF-8]\n\n";
-- }
-- else
-- {
-- print STDERR "$xgettext_error_msg";
-- if (-e "$MODULE.pot")
-- {
-- # is this possible?
-- print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n".
-- " Please consult error message above if there is any.\n";
-- }
-- else
-- {
-- print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n".
-- " error message above if there is any.\n";
-- }
-- }
-- exit (1);
-- }
--}
--
--sub POFile_Update
--{
-- -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n";
--
-- my $MSGMERGE = $ENV{"MSGMERGE"} || "@INTLTOOL_MSGMERGE@";
-- my ($lang, $outfile) = @_;
--
-- print "Merging $SRCDIR/$lang.po with $MODULE.pot..." if $VERBOSE;
--
-- my $infile = "$SRCDIR/$lang.po";
-- $outfile = "$SRCDIR/$lang.po" if ($outfile eq "");
--
-- # I think msgmerge won't overwrite old file if merge is not successful
-- system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot");
--}
--
--sub Console_WriteError_NotExisting
--{
-- my ($file) = @_;
--
-- ## Report error if supplied language file is non-existing
-- print STDERR "$PROGRAM: $file does not exist!\n";
-- print STDERR "Try '$PROGRAM --help' for more information.\n";
-- exit;
--}
--
--sub GatherPOFiles
--{
-- my @po_files = glob ("./*.po");
--
-- @languages = map (&POFile_GetLanguage, @po_files);
--
-- foreach my $lang (@languages)
-- {
-- $po_files_by_lang{$lang} = shift (@po_files);
-- }
--}
--
--sub POFile_GetLanguage ($)
--{
-- s/^(.*\/)?(.+)\.po$/$2/;
-- return $_;
--}
--
--sub Console_Write_TranslationStatus
--{
-- my ($lang, $output_file) = @_;
-- my $MSGFMT = $ENV{"MSGFMT"} || "@INTLTOOL_MSGFMT@";
--
-- $output_file = "$SRCDIR/$lang.po" if ($output_file eq "");
--
-- system ("$MSGFMT", "-o", "$devnull", "--verbose", $output_file);
--}
--
--sub Console_Write_CoverageReport
--{
-- my $MSGFMT = $ENV{"MSGFMT"} || "@INTLTOOL_MSGFMT@";
--
-- &GatherPOFiles;
--
-- foreach my $lang (@languages)
-- {
-- print "$lang: ";
-- &POFile_Update ($lang, "");
-- }
--
-- print "\n\n * Current translation support in $MODULE \n\n";
--
-- foreach my $lang (@languages)
-- {
-- print "$lang: ";
-- system ("$MSGFMT", "-o", "$devnull", "--verbose", "$SRCDIR/$lang.po");
-- }
--}
--
--sub SubstituteVariable
--{
-- my ($str) = @_;
--
-- # always need to rewind file whenever it has been accessed
-- seek (CONF, 0, 0);
--
-- # cache each variable. varhash is global to we can add
-- # variables elsewhere.
-- while (<CONF>)
-- {
-- if (/^(\w+)=(.*)$/)
-- {
-- ($varhash{$1} = $2) =~ s/^["'](.*)["']$/$1/;
-- }
-- }
--
-- if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/)
-- {
-- my $rest = $3;
-- my $untouched = $1;
-- my $sub = "";
-- # Ignore recursive definitions of variables
-- $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\${?$2}?/;
--
-- return SubstituteVariable ("$untouched$sub$rest");
-- }
--
-- # We're using Perl backticks ` and "echo -n" here in order to
-- # expand any shell escapes (such as backticks themselves) in every variable
-- return echo_n ($str);
--}
--
--sub CONF_Handle_Open
--{
-- my $base_dirname = getcwd();
-- $base_dirname =~ s@.*/@@;
--
-- my ($conf_in, $src_dir);
--
-- if ($base_dirname =~ /^po(-.+)?$/)
-- {
-- if (-f "Makevars")
-- {
-- my $makefile_source;
--
-- local (*IN);
-- open (IN, "<Makevars") || die "can't open Makevars: $!";
--
-- while (<IN>)
-- {
-- if (/^top_builddir[ \t]*=/)
-- {
-- $src_dir = $_;
-- $src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
--
-- chomp $src_dir;
-- if (-f "$src_dir" . "/configure.ac") {
-- $conf_in = "$src_dir" . "/configure.ac" . "\n";
-- } else {
-- $conf_in = "$src_dir" . "/configure.in" . "\n";
-- }
-- last;
-- }
-- }
-- close IN;
--
-- $conf_in || die "Cannot find top_builddir in Makevars.";
-- }
-- elsif (-f "../configure.ac")
-- {
-- $conf_in = "../configure.ac";
-- }
-- elsif (-f "../configure.in")
-- {
-- $conf_in = "../configure.in";
-- }
-- else
-- {
-- my $makefile_source;
--
-- local (*IN);
-- open (IN, "<Makefile") || return;
--
-- while (<IN>)
-- {
-- if (/^top_srcdir[ \t]*=/)
-- {
-- $src_dir = $_;
-- $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
--
-- chomp $src_dir;
-- $conf_in = "$src_dir" . "/configure.in" . "\n";
--
-- last;
-- }
-- }
-- close IN;
--
-- $conf_in || die "Cannot find top_srcdir in Makefile.";
-- }
--
-- open (CONF, "<$conf_in");
-- }
-- else
-- {
-- print STDERR "$PROGRAM: Unable to proceed.\n" .
-- "Make sure to run this script inside the po directory.\n";
-- exit;
-- }
--}
--
--sub FindPackageName
--{
-- my $version;
-- my $domain = &FindMakevarsDomain;
-- my $name = $domain || "untitled";
--
-- &CONF_Handle_Open;
--
-- my $conf_source; {
-- local (*IN);
-- open (IN, "<&CONF") || return $name;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $conf_source = <IN>;
-- close IN;
-- }
--
-- # priority for getting package name:
-- # 1. GETTEXT_PACKAGE
-- # 2. first argument of AC_INIT (with >= 2 arguments)
-- # 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument)
--
-- # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m
-- # the \s makes this not work, why?
-- if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m)
-- {
-- ($name, $version) = ($1, $2);
-- $name =~ s/[\[\]\s]//g;
-- $version =~ s/[\[\]\s]//g;
-- $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
-- $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
-- $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
-- $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
-- }
--
-- if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m)
-- {
-- ($name, $version) = ($1, $2);
-- $name =~ s/[\[\]\s]//g;
-- $version =~ s/[\[\]\s]//g;
-- $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
-- $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
-- $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
-- $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
-- }
--
-- # \s makes this not work, why?
-- $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m;
--
-- # m4 macros AC_PACKAGE_NAME, AC_PACKAGE_VERSION etc. have same value
-- # as corresponding $PACKAGE_NAME, $PACKAGE_VERSION etc. shell variables.
-- $name =~ s/\bAC_PACKAGE_/\$PACKAGE_/g;
--
-- $name = $domain if $domain;
--
-- $name = SubstituteVariable ($name);
-- $name =~ s/^["'](.*)["']$/$1/;
--
-- return $name if $name;
--}
--
--
--sub FindPOTKeywords
--{
--
-- my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_";
-- my $varname = "XGETTEXT_OPTIONS";
-- my $make_source; {
-- local (*IN);
-- open (IN, "<Makevars") || (open(IN, "<Makefile.in.in") && ($varname = "XGETTEXT_KEYWORDS")) || return $keywords;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $make_source = <IN>;
-- close IN;
-- }
--
-- $keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m;
--
-- return $keywords;
--}
--
--sub FindMakevarsDomain
--{
--
-- my $domain = "";
-- my $makevars_source; {
-- local (*IN);
-- open (IN, "<Makevars") || return $domain;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $makevars_source = <IN>;
-- close IN;
-- }
--
-- $domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m;
-- $domain =~ s/^\s+//;
-- $domain =~ s/\s+$//;
--
-- return $domain;
--}
--
--sub FindMakevarsBugAddress
--{
--
-- my $address = "";
-- my $makevars_source; {
-- local (*IN);
-- open (IN, "<Makevars") || return undef;
-- seek (IN, 0, 0);
-- local $/; # slurp mode
-- $makevars_source = <IN>;
-- close IN;
-- }
--
-- $address = $1 if $makevars_source =~ /^MSGID_BUGS_ADDRESS[ ]*=\[?([^\n\]\$]+)/m;
-- $address =~ s/^\s+//;
-- $address =~ s/\s+$//;
--
-- return $address;
--}
-diff --git a/intltool-update.in b/intltool-update.in
-new file mode 120000
-index 661d8fe..0b1800f
---- /dev/null
-+++ b/intltool-update.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/intltool-update.in
-\ No newline at end of file
-diff --git a/pixmaps/intlclock-map-location-current.png b/pixmaps/intlclock-map-location-current.png
-new file mode 100644
-index 0000000..5c505d1
-Binary files /dev/null and b/pixmaps/intlclock-map-location-current.png differ
-diff --git a/pixmaps/intlclock-map-location-current.svg b/pixmaps/intlclock-map-location-current.svg
-new file mode 100644
-index 0000000..93b5188
---- /dev/null
-+++ b/pixmaps/intlclock-map-location-current.svg
-@@ -0,0 +1,76 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<!-- Created with Inkscape (http://www.inkscape.org/) -->
-+<svg
-+ xmlns:dc="http://purl.org/dc/elements/1.1/"
-+ xmlns:cc="http://web.resource.org/cc/"
-+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-+ xmlns:svg="http://www.w3.org/2000/svg"
-+ xmlns="http://www.w3.org/2000/svg"
-+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-+ width="10"
-+ height="10"
-+ id="svg2"
-+ sodipodi:version="0.32"
-+ inkscape:version="0.45.1"
-+ sodipodi:docbase="/home/mclasen/Desktop"
-+ sodipodi:docname="star.svg"
-+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
-+ version="1.0">
-+ <defs
-+ id="defs4" />
-+ <sodipodi:namedview
-+ id="base"
-+ pagecolor="#ffffff"
-+ bordercolor="#666666"
-+ borderopacity="1.0"
-+ gridtolerance="10000"
-+ guidetolerance="10"
-+ objecttolerance="10"
-+ inkscape:pageopacity="0.0"
-+ inkscape:pageshadow="2"
-+ inkscape:zoom="1"
-+ inkscape:cx="88.125"
-+ inkscape:cy="-22.797357"
-+ inkscape:document-units="px"
-+ inkscape:current-layer="layer1"
-+ inkscape:window-width="1003"
-+ inkscape:window-height="824"
-+ inkscape:window-x="93"
-+ inkscape:window-y="30"
-+ width="10px"
-+ height="10px" />
-+ <metadata
-+ id="metadata7">
-+ <rdf:RDF>
-+ <cc:Work
-+ rdf:about="">
-+ <dc:format>image/svg+xml</dc:format>
-+ <dc:type
-+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-+ </cc:Work>
-+ </rdf:RDF>
-+ </metadata>
-+ <g
-+ inkscape:label="Layer 1"
-+ inkscape:groupmode="layer"
-+ id="layer1"
-+ transform="translate(-164.31866,-172.88433)">
-+ <path
-+ sodipodi:type="star"
-+ style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:10.30000114;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
-+ id="path2160"
-+ sodipodi:sides="5"
-+ sodipodi:cx="311.42856"
-+ sodipodi:cy="320.93362"
-+ sodipodi:r1="121.8637"
-+ sodipodi:r2="42.747437"
-+ sodipodi:arg1="1.0073988"
-+ sodipodi:arg2="1.6371268"
-+ inkscape:flatsided="false"
-+ inkscape:rounded="0"
-+ inkscape:randomized="0"
-+ d="M 376.51129,423.96274 L 308.59518,363.58706 L 233.55372,414.66873 L 269.98717,331.41956 L 198.21652,275.83599 L 288.64975,284.76085 L 319.33452,199.32664 L 338.79187,288.09169 L 429.52674,290.87401 L 351.11882,336.80896 L 376.51129,423.96274 z "
-+ transform="matrix(3.8213745e-2,-2.1588882e-2,2.2396111e-2,3.6200569e-2,150.72076,172.68179)" />
-+ </g>
-+</svg>
-diff --git a/pixmaps/intlclock-map-location-hilight.png b/pixmaps/intlclock-map-location-hilight.png
-new file mode 100644
-index 0000000..d7de5b7
-Binary files /dev/null and b/pixmaps/intlclock-map-location-hilight.png differ
-diff --git a/pixmaps/intlclock-map-location-hilight.svg b/pixmaps/intlclock-map-location-hilight.svg
-new file mode 100644
-index 0000000..4a245e0
---- /dev/null
-+++ b/pixmaps/intlclock-map-location-hilight.svg
-@@ -0,0 +1,90 @@
-+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-+<!-- Created with Inkscape (http://www.inkscape.org/) -->
-+<svg
-+ xmlns:dc="http://purl.org/dc/elements/1.1/"
-+ xmlns:cc="http://web.resource.org/cc/"
-+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-+ xmlns:svg="http://www.w3.org/2000/svg"
-+ xmlns="http://www.w3.org/2000/svg"
-+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-+ width="7"
-+ height="7"
-+ id="svg6063"
-+ sodipodi:version="0.32"
-+ inkscape:version="0.45.1"
-+ version="1.0"
-+ sodipodi:docbase="/home/mclasen/Desktop/intlclock/pixmaps"
-+ sodipodi:docname="intlclock-map-location-hilight.svg"
-+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
-+ inkscape:export-filename="/home/garrett/Desktop/dot.png"
-+ inkscape:export-xdpi="90"
-+ inkscape:export-ydpi="90">
-+ <defs
-+ id="defs6065">
-+ <linearGradient
-+ id="linearGradient7251">
-+ <stop
-+ style="stop-color:#e1d9dc;stop-opacity:1;"
-+ offset="0"
-+ id="stop7253" />
-+ <stop
-+ id="stop3143"
-+ offset="0.5"
-+ style="stop-color:#e3bfca;stop-opacity:1;" />
-+ <stop
-+ style="stop-color:#3d0e1a;stop-opacity:1;"
-+ offset="1"
-+ id="stop7255" />
-+ </linearGradient>
-+ </defs>
-+ <sodipodi:namedview
-+ id="base"
-+ pagecolor="#ffffff"
-+ bordercolor="#666666"
-+ borderopacity="1.0"
-+ gridtolerance="10000"
-+ guidetolerance="10"
-+ objecttolerance="10"
-+ inkscape:pageopacity="0.0"
-+ inkscape:pageshadow="2"
-+ inkscape:zoom="22.627417"
-+ inkscape:cx="2.5000319"
-+ inkscape:cy="2.5000319"
-+ inkscape:document-units="px"
-+ inkscape:current-layer="layer1"
-+ inkscape:window-width="872"
-+ inkscape:window-height="750"
-+ inkscape:window-x="0"
-+ inkscape:window-y="30" />
-+ <metadata
-+ id="metadata6068">
-+ <rdf:RDF>
-+ <cc:Work
-+ rdf:about="">
-+ <dc:format>image/svg+xml</dc:format>
-+ <dc:type
-+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-+ </cc:Work>
-+ </rdf:RDF>
-+ </metadata>
-+ <g
-+ inkscape:label="Layer 1"
-+ inkscape:groupmode="layer"
-+ id="layer1"
-+ transform="translate(-474.64282,-409.86216)">
-+ <path
-+ sodipodi:type="arc"
-+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:13.16123206;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-+ id="path7259"
-+ sodipodi:cx="-418.5"
-+ sodipodi:cy="-489.5"
-+ sodipodi:rx="39.5"
-+ sodipodi:ry="39.5"
-+ d="M -379 -489.5 A 39.5 39.5 0 1 1 -458,-489.5 A 39.5 39.5 0 1 1 -379 -489.5 z"
-+ transform="matrix(5.4243529e-2,8.5329805e-4,-8.5329805e-4,5.4243529e-2,499.42608,439.2715)"
-+ inkscape:export-filename="/home/garrett/Desktop/map-new.png"
-+ inkscape:export-xdpi="90"
-+ inkscape:export-ydpi="90" />
-+ </g>
-+</svg>
-diff --git a/pixmaps/intlclock-map-location-marker.png b/pixmaps/intlclock-map-location-marker.png
-new file mode 100644
-index 0000000..48d2184
-Binary files /dev/null and b/pixmaps/intlclock-map-location-marker.png differ
-diff --git a/po/Makefile.in.in b/po/Makefile.in.in
-deleted file mode 100755
-index d2d4e4c..e4713cf
---- a/po/Makefile.in.in
-+++ /dev/null
-@@ -1,221 +0,0 @@
--# Makefile for program source directory in GNU NLS utilities package.
--# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
--#
--# This file file be copied and used freely without restrictions. It can
--# be used in projects which are not available under the GNU Public License
--# but which still want to provide support for the GNU gettext functionality.
--# Please note that the actual code is *not* freely available.
--#
--# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE
--# instead of PACKAGE and to look for po2tbl in ./ not in intl/
--#
--# - Modified by jacob berkman <jacob@ximian.com> to install
--# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
--#
--# - Modified by Rodney Dawes <dobey@novell.com> for use with intltool
--#
--# We have the following line for use by intltoolize:
--# INTLTOOL_MAKEFILE
--
--GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
--PACKAGE = @PACKAGE@
--VERSION = @VERSION@
--
--SHELL = /bin/sh
--
--srcdir = @srcdir@
--top_srcdir = @top_srcdir@
--top_builddir = ..
--VPATH = @srcdir@
--
--prefix = @prefix@
--exec_prefix = @exec_prefix@
--datadir = @datadir@
--datarootdir = @datarootdir@
--libdir = @libdir@
--DATADIRNAME = @DATADIRNAME@
--itlocaledir = $(prefix)/$(DATADIRNAME)/locale
--subdir = po
--install_sh = @install_sh@
--# Automake >= 1.8 provides @mkdir_p@.
--# Until it can be supposed, use the safe fallback:
--mkdir_p = $(install_sh) -d
--
--INSTALL = @INSTALL@
--INSTALL_DATA = @INSTALL_DATA@
--
--GMSGFMT = @GMSGFMT@
--MSGFMT = @MSGFMT@
--XGETTEXT = @XGETTEXT@
--INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
--INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
--MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
--GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
--
--ALL_LINGUAS = @ALL_LINGUAS@
--
--PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi)
--
--POFILES=$(shell if test -n "$(PO_LINGUAS)"; then LINGUAS="$(PO_LINGUAS)"; else LINGUAS="$(ALL_LINGUAS)"; fi; for lang in $$LINGUAS; do printf "$$lang.po "; done)
--
--DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES)
--EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS
--
--POTFILES = \
--#This Gets Replace for some reason
--
--CATALOGS=$(shell if test -n "$(PO_LINGUAS)"; then LINGUAS="$(PO_LINGUAS)"; else LINGUAS="$(ALL_LINGUAS)"; fi; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
--
--.SUFFIXES:
--.SUFFIXES: .po .pox .gmo .mo .msg .cat
--
--.po.pox:
-- $(MAKE) $(GETTEXT_PACKAGE).pot
-- $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
--
--.po.mo:
-- $(MSGFMT) -o $@ $<
--
--.po.gmo:
-- file=`echo $* | sed 's,.*/,,'`.gmo \
-- && rm -f $$file && $(GMSGFMT) -o $$file $<
--
--.po.cat:
-- sed -f ../intl/po2msg.sed < $< > $*.msg \
-- && rm -f $@ && gencat $@ $*.msg
--
--
--all: all-@USE_NLS@
--
--all-yes: $(CATALOGS)
--all-no:
--
--$(GETTEXT_PACKAGE).pot: $(POTFILES)
-- $(GENPOT)
--
--install: install-data
--install-data: install-data-@USE_NLS@
--install-data-no: all
--install-data-yes: all
-- $(mkdir_p) $(DESTDIR)$(itlocaledir)
-- if test -n "$(PO_LINGUAS)"; then \
-- linguas="$(PO_LINGUAS)"; \
-- else \
-- linguas="$(ALL_LINGUAS)"; \
-- fi; \
-- for lang in $$linguas; do \
-- dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \
-- $(mkdir_p) $$dir; \
-- if test -r $$lang.gmo; then \
-- $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
-- echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
-- else \
-- $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
-- echo "installing $(srcdir)/$$lang.gmo as" \
-- "$$dir/$(GETTEXT_PACKAGE).mo"; \
-- fi; \
-- if test -r $$lang.gmo.m; then \
-- $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
-- echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
-- else \
-- if test -r $(srcdir)/$$lang.gmo.m ; then \
-- $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
-- $$dir/$(GETTEXT_PACKAGE).mo.m; \
-- echo "installing $(srcdir)/$$lang.gmo.m as" \
-- "$$dir/$(GETTEXT_PACKAGE).mo.m"; \
-- else \
-- true; \
-- fi; \
-- fi; \
-- done
--
--# Empty stubs to satisfy archaic automake needs
--dvi info tags TAGS ID:
--
--# Define this as empty until I found a useful application.
--installcheck:
--
--uninstall:
-- if test -n "$(PO_LINGUAS)"; then \
-- linguas="$(PO_LINGUAS)"; \
-- else \
-- linguas="$(ALL_LINGUAS)"; \
-- fi; \
-- for lang in $$linguas; do \
-- rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
-- rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
-- done
--
--check: all $(GETTEXT_PACKAGE).pot
--
--mostlyclean:
-- rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
-- rm -f .intltool-merge-cache
--
--clean: mostlyclean
--
--distclean: clean
-- rm -f Makefile Makefile.in POTFILES stamp-it
-- rm -f *.mo *.msg *.cat *.cat.m *.gmo
--
--maintainer-clean: distclean
-- @echo "This command is intended for maintainers to use;"
-- @echo "it deletes files that may require special tools to rebuild."
-- rm -f Makefile.in.in
--
--distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
--dist distdir: $(DISTFILES)
-- dists="$(DISTFILES)"; \
-- extra_dists="$(EXTRA_DISTFILES)"; \
-- for file in $$extra_dists; do \
-- test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
-- done; \
-- for file in $$dists; do \
-- test -f $$file || file="$(srcdir)/$$file"; \
-- ln $$file $(distdir) 2> /dev/null \
-- || cp -p $$file $(distdir); \
-- done
--
--update-po: Makefile
-- $(MAKE) $(GETTEXT_PACKAGE).pot
-- tmpdir=`pwd`; \
-- if test -n "$(PO_LINGUAS)"; then \
-- linguas="$(PO_LINGUAS)"; \
-- else \
-- linguas="$(ALL_LINGUAS)"; \
-- fi; \
-- for lang in $$linguas; do \
-- echo "$$lang:"; \
-- result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
-- if $$result; then \
-- if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
-- rm -f $$tmpdir/$$lang.new.po; \
-- else \
-- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
-- :; \
-- else \
-- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
-- rm -f $$tmpdir/$$lang.new.po; \
-- exit 1; \
-- fi; \
-- fi; \
-- else \
-- echo "msgmerge for $$lang.gmo failed!"; \
-- rm -f $$tmpdir/$$lang.new.po; \
-- fi; \
-- done
--
--Makefile POTFILES: stamp-it
-- @if test ! -f $@; then \
-- rm -f stamp-it; \
-- $(MAKE) stamp-it; \
-- fi
--
--stamp-it: Makefile.in.in ../config.status POTFILES.in
-- cd .. \
-- && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
-- $(SHELL) ./config.status
--
--# Tell versions [3.59,3.63) of GNU make not to export all variables.
--# Otherwise a system limit (for SysV at least) may be exceeded.
--.NOEXPORT:
-diff --git a/po/Makefile.in.in b/po/Makefile.in.in
-new file mode 120000
-index d2d4e4c..e4713cf
---- /dev/null
-+++ b/po/Makefile.in.in
-@@ -0,0 +1 @@
-+/usr/share/intltool/Makefile.in.in
-\ No newline at end of file
-diff --git a/src/Makefile.am b/src/Makefile.am
-index 80d1419..d681d39 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -3,7 +3,7 @@
- INCLUDES = \
- $(INTLCLOCK_CFLAGS) \
- -DGNOMELOCALEDIR=\"$(prefix)/$(DATADIRNAME)/locale\" \
-- -DEVOLUTION_TEXTDOMAIN=\"evolution-2.6\" \
-+ -DEVOLUTION_TEXTDOMAIN=\"evolution-2.12\" \
- -DINTLCLOCK_TEXTDOMAIN=\"gnome-panel-2.0\" \
- -DINTLCLOCK_ICONDIR=\"$(pkgdatadir)\" \
- -DINTLCLOCK_DATADIR=\"$(pkgdatadir)\" \
-@@ -60,7 +60,11 @@ COMMON_SOURCES = \
- intlclock-zoneinfo.c \
- intlclock-zoneinfo.h \
- intlclock-zonetable.c \
-- intlclock-zonetable.h
-+ intlclock-zonetable.h \
-+ set-timezone.c \
-+ set-timezone.h \
-+ gweather-xml.c \
-+ gweather-xml.h
-
-
- intlclock_applet_SOURCES = \
-diff --git a/src/gweather-xml.c b/src/gweather-xml.c
-new file mode 100644
-index 0000000..94b275d
---- /dev/null
-+++ b/src/gweather-xml.c
-@@ -0,0 +1,490 @@
-+/* gweather-xml.c - Locations.xml parsing code
-+ *
-+ * Copyright (C) 2005 Ryan Lortie, 2004 Gareth Owen
-+ *
-+ * 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
-+ */
-+
-+
-+/* There is very little error checking in the parsing code below, it relies
-+ * heavily on the locations file being in the correct format. If you have
-+ * <name> elements within a parent element, they must come first and be
-+ * grouped together.
-+ * The format is as follows:
-+ *
-+ * <gweather format="1.0">
-+ * <region>
-+ * <name>Name of the region</name>
-+ * <name xml:lang="xx">Translated Name</name>
-+ * <name xml:lang="zz">Another Translated Name</name>
-+ * <country>
-+ * <name>Name of the country</name>
-+ * <location>
-+ * <name>Name of the location</name>
-+ * <code>IWIN code</code>
-+ * <zone>Forecast code (North America, Australia, UK only)</zone>
-+ * <radar>Weather.com radar map code (North America only)</radar>
-+ * <coordinates>Latitude and longitude as DD-MM[-SS][H] pair</coordinates>
-+ * </location>
-+ * <state>
-+ * <location>
-+ * ....
-+ * </location>
-+ * <city>
-+ * <name>Name of city with multiple locations</city>
-+ * <zone>Forecast code</zone>
-+ * <radar>Radar Map code</radar>
-+ * <location>
-+ * ...
-+ * </location>
-+ * </city>
-+ * </state>
-+ * </country>
-+ * </region>
-+ * <gweather>
-+ *
-+ * The thing to note is that each country can either contain different locations
-+ * or be split into "states" which in turn contain a list of locations.
-+ *
-+ */
-+
-+#include <string.h>
-+#include <math.h>
-+#include <locale.h>
-+#include <gtk/gtk.h>
-+#include <libxml/xmlreader.h>
-+
-+#include "gweather-xml.h"
-+
-+static gint
-+gweather_xml_location_sort_func( GtkTreeModel *model, GtkTreeIter *a,
-+ GtkTreeIter *b, gpointer user_data )
-+{
-+ gint res;
-+ gchar *name_a, *name_b;
-+ gchar *fold_a, *fold_b;
-+
-+ gtk_tree_model_get (model, a, GWEATHER_XML_COL_LOC, &name_a, -1);
-+ gtk_tree_model_get (model, b, GWEATHER_XML_COL_LOC, &name_b, -1);
-+
-+ fold_a = g_utf8_casefold(name_a, -1);
-+ fold_b = g_utf8_casefold(name_b, -1);
-+
-+ res = g_utf8_collate(fold_a, fold_b);
-+
-+ g_free(name_a);
-+ g_free(name_b);
-+ g_free(fold_a);
-+ g_free(fold_b);
-+
-+ return res;
-+}
-+
-+static char*
-+gweather_xml_get_value( xmlTextReaderPtr xml )
-+{
-+ char* value;
-+
-+ /* check for null node */
-+ if ( xmlTextReaderIsEmptyElement( xml ) )
-+ return NULL;
-+
-+ /* the next "node" is the text node containing the value we want to get */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ return NULL;
-+
-+ value = (char *) xmlTextReaderValue( xml );
-+
-+ /* move on to the end of this node */
-+ while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_END_ELEMENT )
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( value );
-+ return NULL;
-+ }
-+
-+ /* consume the end element too */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( value );
-+ return NULL;
-+ }
-+
-+ return value;
-+}
-+
-+static char *
-+gweather_xml_parse_name( xmlTextReaderPtr xml )
-+{
-+ const char * const *locales;
-+ const char *this_language;
-+ int best_match = INT_MAX;
-+ char *lang, *tagname;
-+ gboolean keep_going;
-+ char *name = NULL;
-+ int i;
-+
-+ locales = g_get_language_names();
-+
-+ do
-+ {
-+ /* First let's get the language */
-+ lang = (char *) xmlTextReaderXmlLang( xml );
-+
-+ if( lang == NULL )
-+ this_language = "C";
-+ else
-+ this_language = lang;
-+
-+ /* the next "node" is text node containing the actual name */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( lang );
-+ return NULL;
-+ }
-+
-+ for( i = 0; locales[i] && i < best_match; i++ )
-+ if( !strcmp( locales[i], this_language ) )
-+ {
-+ /* if we've already encounted a less accurate
-+ translation, then free it */
-+ xmlFree( name );
-+
-+ name = (char *) xmlTextReaderValue( xml );
-+ best_match = i;
-+
-+ break;
-+ }
-+
-+ xmlFree( lang );
-+
-+ while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_ELEMENT )
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ {
-+ xmlFree( name );
-+ return NULL;
-+ }
-+
-+ /* if the next tag is another <name> then keep going */
-+ tagname = (char *) xmlTextReaderName( xml );
-+ keep_going = !strcmp( tagname, "name" );
-+ xmlFree( tagname );
-+
-+ } while( keep_going );
-+
-+ return name;
-+}
-+
-+static int
-+gweather_xml_parse_node (GtkTreeView *view, GtkTreeIter *parent,
-+ xmlTextReaderPtr xml, WeatherLocation *current,
-+ const char *dflt_radar, const char *dflt_zone,
-+ const char *cityname)
-+{
-+ GtkTreeStore *store = GTK_TREE_STORE( gtk_tree_view_get_model( view ) );
-+ char *name, *code, *zone, *radar, *coordinates;
-+ char **city, *nocity = NULL;
-+ GtkTreeIter iter, *self;
-+ gboolean is_location;
-+ char *tagname;
-+ int ret = -1;
-+ int tagtype;
-+
-+ if( (tagname = (char *) xmlTextReaderName( xml )) == NULL )
-+ return -1;
-+
-+ if( !strcmp( tagname, "city" ) )
-+ city = &name;
-+ else
-+ city = &nocity;
-+
-+ is_location = !strcmp( tagname, "location" );
-+
-+ /* if we're processing the top-level, then don't create a new iter */
-+ if( !strcmp( tagname, "gweather" ) )
-+ self = NULL;
-+ else
-+ {
-+ self = &iter;
-+ /* insert this node into the tree */
-+ gtk_tree_store_append( store, self, parent );
-+ }
-+
-+ xmlFree( tagname );
-+
-+ coordinates = NULL;
-+ radar = NULL;
-+ zone = NULL;
-+ code = NULL;
-+ name = NULL;
-+
-+ /* absorb the start tag */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+
-+ /* start parsing the actual contents of the node */
-+ while( (tagtype = xmlTextReaderNodeType( xml )) !=
-+ XML_READER_TYPE_END_ELEMENT )
-+ {
-+
-+ /* skip non-element types */
-+ if( tagtype != XML_READER_TYPE_ELEMENT )
-+ {
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+
-+ continue;
-+ }
-+
-+ tagname = (char *) xmlTextReaderName( xml );
-+
-+ if( !strcmp( tagname, "region" ) || !strcmp( tagname, "country" ) ||
-+ !strcmp( tagname, "state" ) || !strcmp( tagname, "city" ) ||
-+ !strcmp( tagname, "location" ) )
-+ {
-+ /* recursively handle sub-sections */
-+ if( gweather_xml_parse_node( view, self, xml, current,
-+ radar, zone, *city ) )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "name" ) )
-+ {
-+ xmlFree( name );
-+ if( (name = gweather_xml_parse_name( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "code" ) )
-+ {
-+ xmlFree( code );
-+ if( (code = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "zone" ) )
-+ {
-+ xmlFree( zone );
-+ if( (zone = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "radar" ) )
-+ {
-+ xmlFree( radar );
-+ if( (radar = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else if ( !strcmp( tagname, "coordinates" ) )
-+ {
-+ xmlFree( coordinates );
-+ if( (coordinates = gweather_xml_get_value( xml )) == NULL )
-+ goto error_out;
-+ }
-+ else /* some strange tag */
-+ {
-+ /* skip past it */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+ }
-+
-+ xmlFree( tagname );
-+ }
-+
-+ if( self )
-+ gtk_tree_store_set( store, self, GWEATHER_XML_COL_LOC, name, -1 );
-+
-+ /* absorb the end tag. in the case of processing a <gweather> then 'self'
-+ is NULL. In this case, we let this fail since we might be at EOF */
-+ if( xmlTextReaderRead( xml ) != 1 && self )
-+ goto error_out;
-+
-+ /* if this is an actual location, setup the WeatherLocation for it */
-+ if( is_location )
-+ {
-+ WeatherLocation *new_loc;
-+
-+ if( cityname == NULL )
-+ cityname = name;
-+
-+ if( radar != NULL )
-+ dflt_radar = radar;
-+
-+ if( zone != NULL )
-+ dflt_zone = zone;
-+
-+ new_loc = weather_location_new( cityname, code, dflt_zone,
-+ dflt_radar, coordinates );
-+
-+ gtk_tree_store_set( store, &iter, GWEATHER_XML_COL_POINTER, new_loc, -1 );
-+
-+ /* If this location is actually the currently selected one, select it */
-+ if( current && weather_location_equal( new_loc, current ) )
-+ {
-+ GtkTreePath *path;
-+
-+ path = gtk_tree_model_get_path( GTK_TREE_MODEL (store), &iter );
-+ gtk_tree_view_expand_to_path( view, path );
-+ gtk_tree_view_set_cursor( view, path, NULL, FALSE );
-+ gtk_tree_view_scroll_to_cell( view, path, NULL, TRUE, 0.5, 0.5 );
-+ gtk_tree_path_free( path );
-+ }
-+ }
-+
-+ ret = 0;
-+
-+error_out:
-+ xmlFree( name );
-+ xmlFree( code );
-+ xmlFree( zone );
-+ xmlFree( radar );
-+ xmlFree( coordinates );
-+
-+ return ret;
-+}
-+
-+/*****************************************************************************
-+ * Func: gweather_xml_load_locations()
-+ * Desc: Main entry point for loading the locations from the XML file
-+ * Parm:
-+ * *tree: tree to view locations
-+ * *current: currently selected location
-+ */
-+int
-+gweather_xml_load_locations( GtkTreeView *tree, WeatherLocation *current )
-+{
-+ char *tagname, *format;
-+ GtkTreeSortable *sortable;
-+ xmlTextReaderPtr xml;
-+ int keep_going;
-+ int ret = -1;
-+
-+ /* Open the xml file containing the different locations */
-+#ifdef GWEATHER_XML_LOCATION
-+ xml = xmlNewTextReaderFilename (GWEATHER_XML_LOCATION "Locations.xml");
-+#else
-+ xml = xmlNewTextReaderFilename ("/usr/share/gnome-applets/gweather/Locations.xml");
-+#endif
-+ if( xml == NULL )
-+ goto error_out;
-+
-+ /* fast forward to the first element */
-+ do
-+ {
-+ /* if we encounter a problem here, exit right away */
-+ if( xmlTextReaderRead( xml ) != 1 )
-+ goto error_out;
-+ } while( xmlTextReaderNodeType( xml ) != XML_READER_TYPE_ELEMENT );
-+
-+ /* check the name and format */
-+ tagname = (char *) xmlTextReaderName( xml );
-+ keep_going = tagname && !strcmp( tagname, "gweather" );
-+ xmlFree( tagname );
-+
-+ if( !keep_going )
-+ goto error_out;
-+
-+ format = (char *) xmlTextReaderGetAttribute( xml, (xmlChar *) "format" );
-+ keep_going = format && !strcmp( format, "1.0" );
-+ xmlFree( format );
-+
-+ if( !keep_going )
-+ goto error_out;
-+
-+ ret = gweather_xml_parse_node( tree, NULL, xml, current, NULL, NULL, NULL );
-+
-+ if( ret )
-+ goto error_out;
-+
-+ /* Sort the tree */
-+ sortable = GTK_TREE_SORTABLE (gtk_tree_view_get_model( tree ));
-+ gtk_tree_sortable_set_default_sort_func( sortable,
-+ &gweather_xml_location_sort_func,
-+ NULL, NULL);
-+ gtk_tree_sortable_set_sort_column_id( sortable,
-+ GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
-+ GTK_SORT_ASCENDING );
-+error_out:
-+ xmlFreeTextReader( xml );
-+
-+ return ret;
-+}
-+
-+typedef struct {
-+ const gchar *name;
-+ gdouble latitude;
-+ gdouble longitude;
-+ gdouble distance;
-+ WeatherLocation *location;
-+} SearchData;
-+
-+
-+static gdouble
-+distance (gdouble lat1, gdouble lon1,
-+ gdouble lat2, gdouble lon2)
-+{
-+ gdouble radius = 6372.795;
-+
-+ return acos (cos (lat1) * cos (lat2) * cos (lon1 - lon2) + sin (lat1) * sin (lat2)) * radius;
-+}
-+
-+gboolean
-+compare_location (GtkTreeModel *model,
-+ GtkTreePath *path,
-+ GtkTreeIter *iter,
-+ gpointer user_data)
-+{
-+ SearchData *data = user_data;
-+ WeatherLocation *loc;
-+ gdouble d;
-+
-+ gtk_tree_model_get (model, iter, GWEATHER_XML_COL_POINTER, &loc, -1);
-+
-+ if (!loc)
-+ return FALSE;
-+
-+ d = distance (data->latitude, data->longitude, loc->latitude, loc->longitude);
-+
-+ if (d < data->distance) {
-+ data->distance = d;
-+ data->location = loc;
-+ }
-+
-+ return FALSE;
-+}
-+
-+gchar *
-+find_weather_code (GtkTreeModel *model,
-+ const gchar *name,
-+ gdouble lat,
-+ gdouble lon)
-+{
-+ SearchData data;
-+ gchar *code;
-+
-+ data.name = name;
-+ data.latitude = lat;
-+ data.longitude = lon;
-+ data.distance = 1e6;
-+ data.location = NULL;
-+
-+ gtk_tree_model_foreach (GTK_TREE_MODEL (model), compare_location, &data);
-+
-+ if (data.distance < 50)
-+ code = g_strdup (data.location->code);
-+ else
-+ code = g_strdup ("-");
-+
-+ g_debug ("distance: %f\nin: %s\nlat, lon: %f, %f\nout: %s\nDMS: %s\ncode: %s\n",
-+ data.distance, name, lat, lon, data.location->name, data.location->coordinates, code);
-+
-+ return code;
-+}
-diff --git a/src/gweather-xml.h b/src/gweather-xml.h
-new file mode 100644
-index 0000000..d65b651
---- /dev/null
-+++ b/src/gweather-xml.h
-@@ -0,0 +1,37 @@
-+/* gweather-xml.h
-+ *
-+ * Copyright (C) 2004 Gareth Owen
-+ *
-+ * 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
-+ */
-+
-+#ifndef __GWEATHER_XML_H__
-+#define __GWEATHER_XML_H__
-+
-+#include <gtk/gtk.h>
-+#include <libgweather/weather.h>
-+
-+enum
-+{
-+ GWEATHER_XML_COL_LOC = 0,
-+ GWEATHER_XML_COL_POINTER,
-+ GWEATHER_XML_NUM_COLUMNS
-+};
-+
-+int gweather_xml_load_locations( GtkTreeView *tree, WeatherLocation *current );
-+gchar *find_weather_code (GtkTreeModel *model, const gchar *name, gdouble lat, gdouble lon);
-+
-+
-+#endif /* __GWEATHER_XML_H__ */
-diff --git a/src/intlclock-events-popup.c b/src/intlclock-events-popup.c
-index 4276f81..a54f6e3 100644
---- a/src/intlclock-events-popup.c
-+++ b/src/intlclock-events-popup.c
-@@ -1,6 +1,8 @@
- #include <gtk/gtk.h>
- #include <string.h>
- #include <time.h>
-+#include <gconf/gconf-client.h>
-+#include <panel-applet-gconf.h>
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
-@@ -11,12 +13,18 @@
- #endif
-
- #include "intlclock-events-popup.h"
-+#include "intlclock-ui.h"
-+
-+#define KEY_EXPAND_LOCATIONS "expand_locations"
-+#define KEY_EXPAND_TASKS "expand_tasks"
-+#define KEY_EXPAND_APPOINTMENTS "expand_appointments"
-
- G_DEFINE_TYPE (IntlClockEventsPopup, intlclock_events_popup, GTK_TYPE_WINDOW)
-
- typedef struct {
- IntlClock *clock;
- PanelApplet *panel_applet;
-+ IntlClockUI *ui;
-
- GtkWidget *calendar;
- GtkWidget *main_section;
-@@ -126,7 +134,7 @@ intlclock_events_popup_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc
- }
-
- IntlClockEventsPopup *
--intlclock_events_popup_new (IntlClock *clock, PanelApplet *panel_applet)
-+intlclock_events_popup_new (IntlClock *clock, PanelApplet *panel_applet, IntlClockUI *ui)
- {
- IntlClockEventsPopup *this;
- IntlClockEventsPopupPrivate *priv;
-@@ -138,6 +146,7 @@ intlclock_events_popup_new (IntlClock *clock, PanelApplet *panel_applet)
-
- priv->clock = g_object_ref (clock);
- priv->panel_applet = panel_applet;
-+ priv->ui = ui;
-
- gtk_widget_set_name (GTK_WIDGET (this), "intlclock-events-window");
- gtk_container_set_border_width (GTK_CONTAINER (this), 0);
-@@ -275,6 +284,21 @@ intlclock_events_popup_tick (IntlClock *clock, IntlClockEventsPopup *this)
- gmtime (&priv->current_time);
- }
-
-+static GtkWidget * create_hig_frame (IntlClockEventsPopup *this,
-+ const char *title,
-+ const char *button_label,
-+ const char *key,
-+ GCallback callback);
-+
-+
-+static void
-+edit_locations (IntlClockEventsPopup *this)
-+{
-+ IntlClockEventsPopupPrivate *priv = PRIVATE (this);
-+
-+ intlclock_ui_edit_locations (priv->ui);
-+}
-+
- static void
- intlclock_events_popup_fill (IntlClockEventsPopup *this)
- {
-@@ -296,7 +320,10 @@ intlclock_events_popup_fill (IntlClockEventsPopup *this)
-
- orient = panel_applet_get_orient (priv->panel_applet);
-
-- priv->clock_container = gtk_vbox_new (FALSE, 0);
-+ priv->clock_container = create_hig_frame (this,
-+ _("Locations"), _("Edit"),
-+ KEY_EXPAND_LOCATIONS,
-+ G_CALLBACK (edit_locations));
-
- switch (orient) {
- case PANEL_APPLET_ORIENT_UP:
-@@ -642,28 +669,167 @@ modify_task_text_attributes (GtkTreeModel *model,
- g_value_take_boxed (value, attr_list);
- }
-
-+static void
-+expand_collapse_child (GtkWidget *child,
-+ gpointer data)
-+{
-+ gboolean expanded;
-+
-+ if (data == child || gtk_widget_is_ancestor (data, child))
-+ return;
-+
-+ expanded = gtk_expander_get_expanded (GTK_EXPANDER (data));
-+ g_object_set (child, "visible", expanded, NULL);
-+}
-+
-+static void
-+expand_collapse (GtkWidget *expander,
-+ GParamSpec *pspec,
-+ gpointer data)
-+{
-+ GtkWidget *box = data;
-+
-+ gtk_container_foreach (GTK_CONTAINER (box),
-+ (GtkCallback)expand_collapse_child,
-+ expander);
-+}
-+
-+static void
-+expander_activated (GtkExpander *expander,
-+ gpointer data)
-+{
-+ IntlClockEventsPopup *this = data;
-+ IntlClockEventsPopupPrivate *priv = PRIVATE (this);
-+ const gchar *key;
-+ gboolean expanded;
-+
-+ key = (const gchar*)g_object_get_data (G_OBJECT (expander), "gconf-key");
-+ expanded = gtk_expander_get_expanded (expander);
-+
-+ panel_applet_gconf_set_bool (priv->panel_applet, key, expanded, NULL);
-+}
-+
-+static void
-+expanded_changed (GConfClient *client,
-+ guint cnxn_id,
-+ GConfEntry *entry,
-+ GtkExpander *expander)
-+{
-+ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-+ return;
-+
-+ gtk_expander_set_expanded (expander,
-+ gconf_value_get_bool (entry->value));
-+}
-+
-+static void
-+remove_listener (gpointer data)
-+{
-+ GConfClient *client;
-+
-+ client = gconf_client_get_default ();
-+ gconf_client_notify_remove (client, GPOINTER_TO_UINT (data));
-+ g_object_unref (client);
-+}
-+
-+static void
-+connect_expander_with_gconf (IntlClockEventsPopup *this,
-+ GtkWidget *expander,
-+ const gchar *key)
-+{
-+ IntlClockEventsPopupPrivate *priv = PRIVATE (this);
-+ GConfClient *client;
-+ gboolean expanded;
-+ guint listener;
-+ gchar *full_key;
-+
-+ g_object_set_data (G_OBJECT (expander), "gconf-key", (gpointer)key);
-+
-+ expanded = panel_applet_gconf_get_bool (priv->panel_applet, key, NULL);
-+ gtk_expander_set_expanded (GTK_EXPANDER (expander), expanded);
-+
-+ g_signal_connect_after (expander, "activate",
-+ G_CALLBACK (expander_activated),
-+ this);
-+
-+ client = gconf_client_get_default ();
-+ full_key = panel_applet_gconf_get_full_key (priv->panel_applet, key);
-+ listener = gconf_client_notify_add (client, full_key,
-+ (GConfClientNotifyFunc)expanded_changed,
-+ expander, NULL, NULL);
-+ g_object_set_data_full (G_OBJECT (expander), "listener-id",
-+ GUINT_TO_POINTER (listener), remove_listener);
-+ g_object_unref (client);
-+}
-+
-+static void add_child (GtkContainer *container,
-+ GtkWidget *child,
-+ GtkExpander *expander)
-+{
-+ gboolean expanded;
-+
-+ expanded = gtk_expander_get_expanded (expander);
-+ g_object_set (child, "visible", expanded, NULL);
-+}
-+
- static GtkWidget *
--create_hig_frame (const char *title)
-+create_hig_frame (IntlClockEventsPopup *this,
-+ const char *title,
-+ const char *button_label,
-+ const char *key,
-+ GCallback callback)
- {
- GtkWidget *vbox;
- GtkWidget *alignment;
- GtkWidget *label;
-+ GtkWidget *hbox;
-+ GtkWidget *button;
- char *bold_title;
-+ char *text;
-+ GtkWidget *expander;
-
- vbox = gtk_vbox_new (FALSE, 6);
-
- bold_title = g_strdup_printf ("<b>%s</b>", title);
--
-- alignment = gtk_alignment_new (0, 0.5, 0, 0);
-- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
-- gtk_widget_show (alignment);
--
-- label = gtk_label_new (bold_title);
-- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-- gtk_container_add (GTK_CONTAINER (alignment), label);
-- gtk_widget_show (label);
--
-+ expander = gtk_expander_new ("");
-+ gtk_expander_set_label (GTK_EXPANDER (expander), bold_title);
- g_free (bold_title);
-+ gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
-+
-+ hbox = gtk_hbox_new (FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (hbox), expander, FALSE, FALSE, 0);
-+ gtk_widget_show_all (vbox);
-+
-+ g_signal_connect (expander, "notify::expanded",
-+ G_CALLBACK (expand_collapse), hbox);
-+ g_signal_connect (expander, "notify::expanded",
-+ G_CALLBACK (expand_collapse), vbox);
-+
-+ /* FIXME: this doesn't really work, since "add" does not
-+ * get emitted for e.g. gtk_box_pack_start
-+ */
-+ g_signal_connect (vbox, "add", G_CALLBACK (add_child), expander);
-+ g_signal_connect (hbox, "add", G_CALLBACK (add_child), expander);
-+
-+ if (button_label) {
-+ button = gtk_button_new ();
-+ text = g_markup_printf_escaped ("<small>%s</small>", button_label);
-+ label = gtk_label_new (text);
-+ g_free (text);
-+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-+ gtk_container_add (GTK_CONTAINER (button), label);
-+
-+ alignment = gtk_alignment_new (1, 0, 0, 0);
-+ gtk_container_add (GTK_CONTAINER (alignment), button);
-+ gtk_widget_show_all (alignment);
-+
-+ gtk_container_add (GTK_CONTAINER (hbox), alignment);
-+
-+ g_signal_connect_swapped (button, "clicked", callback, this);
-+ }
-+
-+ connect_expander_with_gconf (this, expander, key);
-
- return vbox;
- }
-@@ -791,6 +957,12 @@ compare_tasks (GtkTreeModel *model,
- }
- }
-
-+static void
-+edit_tasks (IntlClockEventsPopup *this)
-+{
-+ clock_launch_evolution (this, "--component=tasks");
-+}
-+
- static GtkWidget *
- create_task_list (IntlClockEventsPopup *this,
- GtkWidget **tree_view,
-@@ -804,7 +976,9 @@ create_task_list (IntlClockEventsPopup *this,
- GtkCellRenderer *cell;
- GtkTreeViewColumn *column;
-
-- vbox = create_hig_frame (_("Tasks"));
-+ vbox = create_hig_frame (this, _("Tasks"), _("Edit"),
-+ KEY_EXPAND_TASKS,
-+ G_CALLBACK (edit_tasks));
-
- *scrolled_window = scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
-@@ -812,8 +986,8 @@ create_task_list (IntlClockEventsPopup *this,
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
-- gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
- gtk_widget_show (scrolled);
-+ gtk_container_add (GTK_CONTAINER (vbox), scrolled);
-
- if (!priv->tasks_model) {
- GType column_types [N_TASK_COLUMNS] = {
-@@ -984,6 +1158,12 @@ handle_appointments_changed (IntlClockEventsPopup *this)
- update_frame_visibility (priv->appointment_list, GTK_TREE_MODEL (priv->appointments_model));
- }
-
-+static void
-+edit_appointments (IntlClockEventsPopup *this)
-+{
-+ clock_launch_evolution (this, "--component=calendar");
-+}
-+
- static GtkWidget *
- create_appointment_list (IntlClockEventsPopup *this,
- GtkWidget **tree_view,
-@@ -997,7 +1177,9 @@ create_appointment_list (IntlClockEventsPopup *this,
- GtkCellRenderer *cell;
- GtkTreeViewColumn *column;
-
-- vbox = create_hig_frame ( _("Appointments"));
-+ vbox = create_hig_frame (this, _("Appointments"), _("Edit"),
-+ KEY_EXPAND_APPOINTMENTS,
-+ G_CALLBACK (edit_appointments));
-
- *scrolled_window = scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
-@@ -1005,8 +1187,8 @@ create_appointment_list (IntlClockEventsPopup *this,
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
-- gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
- gtk_widget_show (scrolled);
-+ gtk_container_add (GTK_CONTAINER (vbox), scrolled);
-
- if (!priv->appointments_model) {
- priv->appointments_model =
-diff --git a/src/intlclock-events-popup.h b/src/intlclock-events-popup.h
-index 84a5183..b88e4c7 100644
---- a/src/intlclock-events-popup.h
-+++ b/src/intlclock-events-popup.h
-@@ -2,6 +2,7 @@
- #define __INTLCLOCK_EVENTS_POPUP_H__
-
- #include "intlclock.h"
-+#include "intlclock-ui.h"
-
- #include <glib.h>
- #include <gtk/gtk.h>
-@@ -29,7 +30,8 @@ typedef struct
- GType intlclock_events_popup_get_type (void);
-
- IntlClockEventsPopup *intlclock_events_popup_new (IntlClock *clock,
-- PanelApplet *panel_applet);
-+ PanelApplet *panel_applet,
-+ IntlClockUI *ui);
- void intlclock_events_popup_set_date (IntlClockEventsPopup *this,
- guint year, guint month, guint mday);
- GtkWidget *intlclock_events_popup_get_clock_container (IntlClockEventsPopup *this);
-diff --git a/src/intlclock-location-tile.c b/src/intlclock-location-tile.c
-index 40d96e3..7f64fee 100644
---- a/src/intlclock-location-tile.c
-+++ b/src/intlclock-location-tile.c
-@@ -23,9 +23,18 @@ typedef struct {
-
- IntlClockFaceSize size;
-
-+ GtkWidget *box;
- GtkWidget *clock_face;
- GtkWidget *city_label;
- GtkWidget *time_label;
-+
-+ GtkWidget *current_button;
-+ GtkWidget *current_label;
-+ GtkWidget *current_marker;
-+ GtkSizeGroup *button_group;
-+
-+ GtkWidget *weather_icon;
-+
- } IntlClockLocationTilePrivate;
-
- static void intlclock_location_tile_finalize (GObject *);
-@@ -36,6 +45,12 @@ static void intlclock_location_tile_refresh (IntlClockLocationTile *this);
- #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_LOCATION_TILE_TYPE, IntlClockLocationTilePrivate))
-
- static void intlclock_location_tile_fill (IntlClockLocationTile *this);
-+static void update_weather_icon (IntlClockLocation *loc, WeatherInfo *info, gpointer data);
-+static gboolean weather_tooltip (GtkWidget *widget,
-+ gint x, gint y,
-+ gboolean keyboard_mode,
-+ GtkTooltip *tooltip,
-+ gpointer data);
-
- IntlClockLocationTile *
- intlclock_location_tile_new (IntlClock *clock, IntlClockUI *ui,
-@@ -56,13 +71,17 @@ intlclock_location_tile_new (IntlClock *clock, IntlClockUI *ui,
- priv->location = g_object_ref (loc);
- priv->size = size;
-
-- gtk_alignment_set (GTK_ALIGNMENT (this), 0.0, 0.0, 0.0, 0.0);
-- gtk_alignment_set_padding (GTK_ALIGNMENT (this), 3, 3, 3, 3);
--
- intlclock_location_tile_fill (this);
-
-- g_signal_connect (G_OBJECT (priv->clock), "tick",
-- G_CALLBACK (intlclock_location_tile_tick), this);
-+ update_weather_icon (loc, intlclock_location_get_weather_info (loc), this);
-+ gtk_widget_set_has_tooltip (priv->weather_icon, TRUE);
-+
-+ g_signal_connect (priv->weather_icon, "query-tooltip",
-+ G_CALLBACK (weather_tooltip), this);
-+ g_signal_connect (G_OBJECT (loc), "weather-updated",
-+ G_CALLBACK (update_weather_icon), this);
-+ g_signal_connect (G_OBJECT (priv->clock), "tick",
-+ G_CALLBACK (intlclock_location_tile_tick), this);
-
- return this;
- }
-@@ -133,13 +152,99 @@ intlclock_location_tile_finalize (GObject *g_obj)
- priv->location = NULL;
- }
-
-+ if (priv->button_group) {
-+ g_object_unref (priv->button_group);
-+ priv->button_group = NULL;
-+ }
-+
- G_OBJECT_CLASS (intlclock_location_tile_parent_class)->finalize (g_obj);
- }
-
-+static gboolean
-+press_on_tile (GtkWidget *widget,
-+ GdkEventButton *event,
-+ IntlClockLocationTile *tile)
-+{
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+
-+ intlclock_blink_location (priv->clock, priv->location);
-+
-+ return TRUE;
-+}
-+
-+static void
-+make_current (GtkWidget *widget, IntlClockLocationTile *tile)
-+{
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+ GError *error = NULL;
-+ GtkWidget *dialog;
-+
-+ if (intlclock_location_make_current (priv->location, &error)) {
-+ g_signal_emit_by_name (priv->clock, "current-timezone-changed", 0);
-+ }
-+ else if (error) {
-+ dialog = gtk_message_dialog_new (NULL,
-+ 0,
-+ GTK_MESSAGE_ERROR,
-+ GTK_BUTTONS_OK,
-+ _("Failed to set the system timezone"));
-+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), error->message);
-+ g_signal_connect (dialog, "response",
-+ G_CALLBACK (gtk_widget_destroy), NULL);
-+ gtk_window_present (GTK_WINDOW (dialog));
-+
-+ g_error_free (error);
-+ }
-+}
-+
-+static gboolean
-+enter_or_leave_tile (GtkWidget *widget,
-+ GdkEventCrossing *event,
-+ IntlClockLocationTile *tile)
-+{
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+
-+ if (event->type == GDK_ENTER_NOTIFY) {
-+ gint can_set;
-+
-+ can_set = can_set_system_timezone ();
-+ if (!intlclock_location_is_current (priv->location) &&
-+ can_set != 0) {
-+ gtk_label_set_markup (GTK_LABEL (priv->current_label),
-+ can_set == 1 ?
-+ _("<small>Set...</small>") :
-+ _("<small>Set</small>"));
-+ gtk_widget_show (priv->current_button);
-+ }
-+ }
-+ else {
-+ if (event->detail != GDK_NOTIFY_INFERIOR)
-+ gtk_widget_hide (priv->current_button);
-+ }
-+
-+ return TRUE;
-+}
-+
- static void
- intlclock_location_tile_fill (IntlClockLocationTile *this)
- {
- IntlClockLocationTilePrivate *priv = PRIVATE (this);
-+ GtkWidget *align;
-+ GtkWidget *strut;
-+ GtkWidget *box;
-+
-+ priv->box = gtk_event_box_new ();
-+
-+ gtk_widget_add_events (priv->box, GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-+ g_signal_connect (priv->box, "button-press-event",
-+ G_CALLBACK (press_on_tile), this);
-+ g_signal_connect (priv->box, "enter-notify-event",
-+ G_CALLBACK (enter_or_leave_tile), this);
-+ g_signal_connect (priv->box, "leave-notify-event",
-+ G_CALLBACK (enter_or_leave_tile), this);
-+
-+ GtkWidget *alignment = gtk_alignment_new (0, 0, 1, 0);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 3, 0);
-
- GtkWidget *tile = gtk_hbox_new (FALSE, 6);
- GtkWidget *head_section = gtk_vbox_new (FALSE, 0);
-@@ -147,21 +252,55 @@ intlclock_location_tile_fill (IntlClockLocationTile *this)
- priv->city_label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (priv->city_label), 0, 0);
-
-+ align = gtk_alignment_new (0, 0, 0, 0);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 0, 3);
-+ gtk_container_add (GTK_CONTAINER (align), priv->city_label);
-+ gtk_box_pack_start (GTK_BOX (head_section), align, FALSE, FALSE, 0);
-+
- priv->time_label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (priv->time_label), 0, 0);
-
-- gtk_box_pack_start (GTK_BOX (head_section), priv->city_label,
-- FALSE, FALSE, 0);
-- gtk_box_pack_start (GTK_BOX (head_section), priv->time_label,
-- FALSE, FALSE, 0);
-+ priv->weather_icon = gtk_image_new ();
-+ align = gtk_alignment_new (0, 0, 0, 0);
-+ gtk_container_add (GTK_CONTAINER (align), priv->weather_icon);
-+
-+ box = gtk_hbox_new (FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (head_section), box, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), align, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), priv->time_label, FALSE, FALSE, 0);
-+
-+ priv->current_button = gtk_button_new ();
-+ priv->current_label = gtk_label_new ("");
-+ gtk_widget_show (priv->current_label);
-+ gtk_widget_set_no_show_all (priv->current_button, TRUE);
-+ gtk_container_add (GTK_CONTAINER (priv->current_button), priv->current_label);
-+ gtk_widget_set_tooltip_text (priv->current_button, _("Set as current timezone for this computer"));
-+
-+ priv->current_marker = gtk_image_new_from_icon_name ("go-home", GTK_ICON_SIZE_BUTTON);
-+ gtk_widget_set_no_show_all (priv->current_marker, TRUE);
-+
-+ align = gtk_alignment_new (1, 1, 0, 0);
-+ strut = gtk_event_box_new ();
-+ gtk_box_pack_start (GTK_BOX (box), strut, TRUE, TRUE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), priv->current_button, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (box), priv->current_marker, FALSE, FALSE, 0);
-+ priv->button_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
-+ gtk_size_group_set_ignore_hidden (priv->button_group, FALSE);
-+ gtk_size_group_add_widget (priv->button_group, strut);
-+ gtk_size_group_add_widget (priv->button_group, priv->current_button);
-+
-+ g_signal_connect (priv->current_button, "clicked",
-+ G_CALLBACK (make_current), this);
-
- priv->clock_face = intlclock_face_new_with_location (
- priv->size, priv->location, head_section);
-
- gtk_box_pack_start (GTK_BOX (tile), priv->clock_face, FALSE, FALSE, 0);
-- gtk_box_pack_start (GTK_BOX (tile), head_section, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (tile), head_section, TRUE, TRUE, 0);
-
-- gtk_container_add (GTK_CONTAINER (this), tile);
-+ gtk_container_add (GTK_CONTAINER (alignment), tile);
-+ gtk_container_add (GTK_CONTAINER (priv->box), alignment);
-+ gtk_container_add (GTK_CONTAINER (this), priv->box);
-
- intlclock_location_tile_refresh (this);
- }
-@@ -231,6 +370,21 @@ intlclock_location_tile_refresh (IntlClockLocationTile *this)
- char buf[256];
- struct tm now;
-
-+ if (intlclock_location_is_current (priv->location)) {
-+ if (!GTK_WIDGET_VISIBLE (priv->current_marker)) {
-+ GdkPixbuf *pixbuf;
-+
-+ pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (priv->weather_icon));
-+ intlclock_ui_update_weather_icon (priv->ui, pixbuf);
-+ }
-+
-+ gtk_widget_hide (priv->current_button);
-+ gtk_widget_show (priv->current_marker);
-+ }
-+ else {
-+ gtk_widget_hide (priv->current_marker);
-+ }
-+
- if (intlclock_needs_face_refresh (this)) {
- intlclock_face_refresh (INTLCLOCK_FACE (priv->clock_face));
- }
-@@ -271,3 +425,87 @@ intlclock_location_tile_tick (IntlClock *clock,
-
- intlclock_location_tile_refresh (this);
- }
-+
-+static gboolean
-+weather_tooltip (GtkWidget *widget,
-+ gint x,
-+ gint y,
-+ gboolean keyboard_mode,
-+ GtkTooltip *tooltip,
-+ gpointer data)
-+{
-+ IntlClockLocationTile *tile = data;
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+ WeatherInfo *info;
-+ GdkPixbuf *pixbuf = NULL;
-+ gchar *conditions, *temp, *apparent, *wind;
-+ gchar *line1, *line2, *line3, *line4, *tip;
-+
-+ info = intlclock_location_get_weather_info (priv->location);
-+
-+ if (!info || !weather_info_is_valid (info))
-+ return FALSE;
-+
-+ weather_info_get_pixbuf (info, &pixbuf);
-+ if (pixbuf)
-+ gtk_tooltip_set_icon (tooltip, pixbuf);
-+
-+ conditions = weather_info_get_conditions (info);
-+ if (strcmp (conditions, "-") != 0)
-+ line1 = g_strdup_printf (_("%s, %s"),
-+ conditions,
-+ weather_info_get_sky (info));
-+ else
-+ line1 = g_strdup (weather_info_get_sky (info));
-+
-+ temp = weather_info_get_temp (info);
-+ apparent = weather_info_get_apparent (info);
-+ if (strcmp (apparent, temp) != 0 &&
-+ /* FIXME libgweather needs some real api */
-+ strcmp (apparent, dgettext ("gnome-applets-2.0", "Unknown")) != 0)
-+ line2 = g_strdup_printf (_("%s, feels like %s"), temp, apparent);
-+ else
-+ line2 = g_strdup (temp);
-+
-+ wind = weather_info_get_wind (info);
-+ if (strcmp (apparent, dgettext ("gnome-applets-2.0", "Unknown")) != 0)
-+ line3 = g_strdup_printf ("%s\n", wind);
-+ else
-+ line3 = g_strdup ("");
-+
-+ line4 = g_strdup_printf (_("Sunrise: %s / Sunset: %s"),
-+ weather_info_get_sunrise (info),
-+ weather_info_get_sunset (info));
-+
-+ tip = g_strdup_printf ("<b>%s</b>\n%s\n%s%s", line1, line2, line3, line4);
-+ gtk_tooltip_set_markup (tooltip, tip);
-+ g_free (line1);
-+ g_free (line2);
-+ g_free (line3);
-+ g_free (line4);
-+ g_free (tip);
-+
-+ return TRUE;
-+}
-+
-+
-+static void
-+update_weather_icon (IntlClockLocation *loc, WeatherInfo *info, gpointer data)
-+{
-+ IntlClockLocationTile *tile = data;
-+ IntlClockLocationTilePrivate *priv = PRIVATE (tile);
-+ GdkPixbuf *pixbuf = NULL;
-+
-+ if (!info || !weather_info_is_valid (info))
-+ return;
-+
-+ weather_info_get_pixbuf_mini (info, &pixbuf);
-+
-+ if (pixbuf) {
-+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->weather_icon), pixbuf);
-+ gtk_alignment_set_padding (GTK_ALIGNMENT (gtk_widget_get_parent (priv->weather_icon)), 0, 0, 0, 6);
-+ if (intlclock_location_is_current (loc))
-+ intlclock_ui_update_weather_icon (priv->ui, pixbuf);
-+ }
-+}
-+
-diff --git a/src/intlclock-location.c b/src/intlclock-location.c
-index 384b2aa..0a37b48 100644
---- a/src/intlclock-location.c
-+++ b/src/intlclock-location.c
-@@ -1,4 +1,3 @@
--#include "intlclock-location.h"
-
- #ifdef HAVE_CONFIG_H
- #include <config.h>
-@@ -13,9 +12,16 @@
- #include <sys/stat.h>
- #include <time.h>
- #include <unistd.h>
-+#include <math.h>
-
- #include <glib.h>
- #include <libgnome/gnome-i18n.h>
-+#include <libgnomevfs/gnome-vfs.h>
-+
-+#include "intlclock-location.h"
-+#include "intlclock-marshallers.h"
-+#include "set-timezone.h"
-+#include "gweather-xml.h"
-
- G_DEFINE_TYPE (IntlClockLocation, intlclock_location, G_TYPE_OBJECT)
-
-@@ -29,17 +35,31 @@ typedef struct {
-
- gfloat latitude;
- gfloat longitude;
-+
-+ gchar *weather_code;
-+ WeatherInfo *weather_info;
-+ guint weather_timeout;
-+
- } IntlClockLocationPrivate;
-
-+enum {
-+ WEATHER_UPDATED,
-+ LAST_SIGNAL
-+};
-+
-+static guint location_signals[LAST_SIGNAL] = { 0 };
-+
- static void intlclock_location_finalize (GObject *);
- static void intlclock_location_set_tz (IntlClockLocation *this);
- static void intlclock_location_unset_tz (IntlClockLocation *this);
-+static void setup_weather_updates (IntlClockLocation *loc);
-
- #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_LOCATION_TYPE, IntlClockLocationPrivate))
-
- IntlClockLocation *
- intlclock_location_new (const gchar *name, const gchar *timezone,
-- gfloat latitude, gfloat longitude)
-+ gfloat latitude, gfloat longitude,
-+ const gchar *code)
- {
- IntlClockLocation *this;
- IntlClockLocationPrivate *priv;
-@@ -62,6 +82,9 @@ intlclock_location_new (const gchar *name, const gchar *timezone,
- priv->latitude = latitude;
- priv->longitude = longitude;
-
-+ priv->weather_code = g_strdup (code);
-+ setup_weather_updates (this);
-+
- return this;
- }
-
-@@ -193,6 +216,77 @@ guess_zone_from_tree (const gchar *localtime, IntlClockZoneTable *zones)
- return ret;
- }
-
-+static const gchar *current_zone = NULL;
-+static GnomeVFSMonitorHandle *monitor = NULL;
-+
-+static void
-+parse_etc_sysconfig_clock (void)
-+{
-+ gchar *data;
-+ gsize len;
-+ gchar **lines;
-+ gchar *res;
-+ gint i;
-+ gchar *p, *q;
-+
-+ lines = NULL;
-+ res = NULL;
-+ if (g_file_test ("/etc/sysconfig/clock",
-+ G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-+ if (!g_file_get_contents ("/etc/sysconfig/clock",
-+ &data, &len, NULL))
-+ goto out;
-+
-+ lines = g_strsplit (data, "\n", 0);
-+ g_free (data);
-+
-+ for (i = 0; lines[i] && !res; i++) {
-+ if (g_str_has_prefix (lines[i], "ZONE=")) {
-+ p = lines[i] + strlen ("ZONE=");
-+ if (p[0] != '\"')
-+ goto out;
-+ p++;
-+ q = strchr (p, '\"');
-+ q[0] = '\0';
-+ res = g_strdup (p);
-+ }
-+ }
-+ }
-+
-+out:
-+ if (lines)
-+ g_strfreev (lines);
-+
-+ g_free (current_zone);
-+ current_zone = res;
-+}
-+
-+static void
-+monitor_etc_sysconfig_clock (GnomeVFSMonitorHandle *handle,
-+ const gchar *monitor_uri,
-+ const gchar *info_uri,
-+ GnomeVFSMonitorEventType event_type,
-+ gpointer user_data)
-+{
-+ parse_etc_sysconfig_clock ();
-+}
-+
-+static const gchar *
-+zone_from_etc_sysconfig_clock (void)
-+{
-+ if (monitor == NULL) {
-+ parse_etc_sysconfig_clock ();
-+
-+ gnome_vfs_monitor_add (&monitor,
-+ "/etc/sysconfig/clock",
-+ GNOME_VFS_MONITOR_FILE,
-+ monitor_etc_sysconfig_clock,
-+ NULL);
-+ }
-+
-+ return current_zone;
-+}
-+
- static gchar *
- intlclock_location_guess_zone (IntlClockZoneTable *zones)
- {
-@@ -200,6 +294,12 @@ intlclock_location_guess_zone (IntlClockZoneTable *zones)
- const char *localtime = "/etc/localtime";
- gchar *linkfile = NULL;
- GError *err = NULL;
-+ gchar *zone;
-+
-+ /* look for /etc/sysconfig/clock */
-+ if ((zone = zone_from_etc_sysconfig_clock ())) {
-+ return g_strdup (zone);
-+ }
-
- /* guess the current time zone by readlink() on /etc/localtime */
- linkfile = g_file_read_link (localtime, &err);
-@@ -235,14 +335,14 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
-
- if (zone == NULL) {
- /* make a fake location with a null TZ */
-- return intlclock_location_new (_("Unknown Location"), NULL, 0.0, 0.0);
-+ return intlclock_location_new (_("Unknown Location"), NULL, 0.0, 0.0, NULL);
- }
-
- info = intlclock_zonetable_get_zone (zones, zone);
-
- if (info == NULL) {
- /* make a fake location with the current TZ */
-- return intlclock_location_new (_("Unknown Location"), zone, 0.0, 0.0);
-+ return intlclock_location_new (_("Unknown Location"), zone, 0.0, 0.0, NULL);
- }
-
- g_free (zone);
-@@ -260,7 +360,7 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
- }
-
- ret = intlclock_location_new (name, intlclock_zoneinfo_get_name (info),
-- lat, lon);
-+ lat, lon, NULL);
-
- g_free (name);
-
-@@ -274,6 +374,15 @@ intlclock_location_class_init (IntlClockLocationClass *this_class)
-
- g_obj_class->finalize = intlclock_location_finalize;
-
-+ location_signals[WEATHER_UPDATED] =
-+ g_signal_new ("weather-updated",
-+ G_OBJECT_CLASS_TYPE (g_obj_class),
-+ G_SIGNAL_RUN_FIRST,
-+ G_STRUCT_OFFSET (IntlClockLocationClass, weather_updated),
-+ NULL, NULL,
-+ _intlclock_marshal_VOID__POINTER,
-+ G_TYPE_NONE, 1, G_TYPE_POINTER);
-+
- g_type_class_add_private (this_class, sizeof (IntlClockLocationPrivate));
- }
-
-@@ -318,6 +427,21 @@ intlclock_location_finalize (GObject *g_obj)
- priv->tzname = NULL;
- }
-
-+ if (priv->weather_code) {
-+ g_free (priv->weather_code);
-+ priv->weather_code = NULL;
-+ }
-+
-+ if (priv->weather_info) {
-+ weather_info_free (priv->weather_info);
-+ priv->weather_info = NULL;
-+ }
-+
-+ if (priv->weather_timeout) {
-+ g_source_remove (priv->weather_timeout);
-+ priv->weather_timeout = 0;
-+ }
-+
- G_OBJECT_CLASS (intlclock_location_parent_class)->finalize (g_obj);
- }
-
-@@ -467,3 +591,179 @@ intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm)
-
- intlclock_location_unset_tz (loc);
- }
-+
-+gboolean
-+intlclock_location_is_current (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ gboolean current;
-+ long sys_timezone;
-+ const char *zone;
-+
-+ if ((zone = zone_from_etc_sysconfig_clock ()))
-+ return strcmp (zone, priv->timezone) == 0;
-+
-+ unsetenv ("TZ");
-+ tzset ();
-+ sys_timezone = timezone;
-+
-+ setenv ("TZ", priv->timezone, 1);
-+ tzset();
-+
-+ current = sys_timezone == timezone;
-+
-+ if (priv->sys_timezone) {
-+ setenv ("TZ", priv->sys_timezone, 1);
-+ } else {
-+ unsetenv ("TZ");
-+ }
-+ tzset();
-+
-+ return current;
-+}
-+
-+gboolean
-+intlclock_location_make_current (IntlClockLocation *loc, GError **error)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ gchar *filename;
-+ gboolean ret;
-+
-+ filename = g_build_filename (SYSTEM_ZONEINFODIR, priv->timezone, NULL);
-+ ret = set_system_timezone (filename, error);
-+ g_free (filename);
-+
-+ if (ret) {
-+ /* FIXME this ugly shortcut is necessary until we move the
-+ * current timezone tracking to intlclock.c and emit the
-+ * signal from there
-+ */
-+ g_free (current_zone);
-+ current_zone = g_strdup (priv->timezone);
-+ }
-+
-+ return ret;
-+}
-+
-+const gchar *
-+intlclock_location_get_weather_code (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ return priv->weather_code;
-+}
-+
-+void
-+intlclock_location_set_weather_code (IntlClockLocation *loc, const gchar *code)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ g_free (priv->weather_code);
-+ priv->weather_code = g_strdup (code);
-+
-+ setup_weather_updates (loc);
-+}
-+
-+WeatherInfo *
-+intlclock_location_get_weather_info (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ return priv->weather_info;
-+}
-+
-+static void
-+weather_info_updated (WeatherInfo *info, gpointer data)
-+{
-+ IntlClockLocation *loc = data;
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+
-+ g_signal_emit (loc, location_signals[WEATHER_UPDATED],
-+ 0, priv->weather_info);
-+}
-+
-+static gboolean
-+update_weather_info (gpointer data)
-+{
-+ IntlClockLocation *loc = data;
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ WeatherPrefs prefs = {
-+ FORECAST_STATE,
-+ FALSE,
-+ NULL,
-+ TEMP_UNIT_CENTIGRADE,
-+ SPEED_UNIT_MS,
-+ PRESSURE_UNIT_MB,
-+ DISTANCE_UNIT_KM
-+ };
-+
-+ weather_info_update (priv->weather_info,
-+ &prefs, weather_info_updated, loc);
-+
-+ return TRUE;
-+}
-+
-+static gchar *
-+rad2dms (gfloat lat, gfloat lon)
-+{
-+ gchar h, h2;
-+ gfloat d, deg, min, d2, deg2, min2;
-+
-+ h = lat > 0 ? 'N' : 'S';
-+ d = fabs (lat);
-+ deg = floor (d);
-+ min = floor (60 * (d - deg));
-+ h2 = lon > 0 ? 'E' : 'W';
-+ d2 = fabs (lon);
-+ deg2 = floor (d2);
-+ min2 = floor (60 * (d2 - deg2));
-+ return g_strdup_printf ("%02d-%02d%c %02d-%02d%c",
-+ (int)deg, (int)min, h,
-+ (int)deg2, (int)min2, h2);
-+}
-+
-+static void
-+setup_weather_updates (IntlClockLocation *loc)
-+{
-+ IntlClockLocationPrivate *priv = PRIVATE (loc);
-+ const gchar *code;
-+ WeatherLocation *wl;
-+ WeatherPrefs prefs = {
-+ FORECAST_STATE,
-+ FALSE,
-+ NULL,
-+ TEMP_UNIT_CENTIGRADE,
-+ SPEED_UNIT_MS,
-+ PRESSURE_UNIT_MB,
-+ DISTANCE_UNIT_KM
-+ };
-+ gfloat lat, lon;
-+ gchar *dms;
-+
-+ if (priv->weather_info) {
-+ weather_info_free (priv->weather_info);
-+ priv->weather_info = NULL;
-+ }
-+
-+ if (priv->weather_timeout) {
-+ g_source_remove (priv->weather_timeout);
-+ priv->weather_timeout = 0;
-+ }
-+
-+ if (!priv->weather_code || strcmp (priv->weather_code, "-") == 0)
-+ return;
-+
-+ dms = rad2dms (priv->latitude, priv->longitude);
-+ wl = weather_location_new (priv->name, priv->weather_code,
-+ NULL, NULL, dms);
-+
-+ priv->weather_info =
-+ weather_info_new (wl, &prefs, weather_info_updated, loc);
-+
-+ priv->weather_timeout =
-+ g_timeout_add_seconds (1800, update_weather_info, loc);
-+
-+ weather_location_free (wl);
-+ g_free (dms);
-+}
-+
-diff --git a/src/intlclock-location.h b/src/intlclock-location.h
-index 824ee3c..deb7074 100644
---- a/src/intlclock-location.h
-+++ b/src/intlclock-location.h
-@@ -4,6 +4,7 @@
- #include <time.h>
- #include <glib.h>
- #include <glib-object.h>
-+#include <libgweather/weather.h>
-
- #include "intlclock-zonetable.h"
-
-@@ -24,12 +25,16 @@ typedef struct
- typedef struct
- {
- GObjectClass g_object_class;
-+
-+ void (* weather_updated) (IntlClockLocation *location, WeatherInfo *info);
-+
- } IntlClockLocationClass;
-
- GType intlclock_location_get_type (void);
-
- IntlClockLocation *intlclock_location_new (const gchar *name, const gchar *timezone,
-- gfloat latitude, gfloat longitude);
-+ gfloat latitude, gfloat longitude,
-+ const gchar *code);
-
- IntlClockLocation *intlclock_location_new_from_env (IntlClockZoneTable *zones);
-
-@@ -46,5 +51,12 @@ void intlclock_location_set_coords (IntlClockLocation *loc, gfloat latitude, gfl
-
- void intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm);
-
-+gboolean intlclock_location_is_current (IntlClockLocation *loc);
-+gboolean intlclock_location_make_current (IntlClockLocation *loc, GError **error);
-+
-+const gchar *intlclock_location_get_weather_code (IntlClockLocation *loc);
-+void intlclock_location_set_weather_code (IntlClockLocation *loc, const gchar *code);
-+WeatherInfo *intlclock_location_get_weather_info (IntlClockLocation *loc);
-+
- G_END_DECLS
- #endif /* __INTLCLOCK_LOCATION_H__ */
-diff --git a/src/intlclock-map.c b/src/intlclock-map.c
-index 2d72975..9ded127 100644
---- a/src/intlclock-map.c
-+++ b/src/intlclock-map.c
-@@ -25,7 +25,7 @@ typedef struct {
- gint height;
-
- GdkPixbuf *stock_map_pixbuf;
-- GdkPixbuf *location_marker_pixbuf;
-+ GdkPixbuf *location_marker_pixbuf[3];
-
- GdkPixbuf *location_map_pixbuf;
-
-@@ -54,6 +54,7 @@ static void intlclock_map_display (IntlClockMap *this);
-
-
- static void intlclock_map_locations_changed (IntlClock *clock, IntlClockMap *this);
-+static void intlclock_map_blink_location (IntlClock *clock, IntlClockLocation *loc, IntlClockMap *this);
- static void intlclock_map_tick (IntlClock *clock, IntlClockMap *this);
-
- #define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_MAP_TYPE, IntlClockMapPrivate))
-@@ -69,8 +70,12 @@ intlclock_map_new (IntlClock *clock)
-
- priv->clock = g_object_ref (clock);
-
-- priv->location_marker_pixbuf = rsvg_pixbuf_from_file
-- (INTLCLOCK_ICONDIR "/intlclock-map-location-marker.svg", NULL);
-+ priv->location_marker_pixbuf[0] = gdk_pixbuf_new_from_file
-+ (INTLCLOCK_ICONDIR "/intlclock-map-location-marker.png", NULL);
-+ priv->location_marker_pixbuf[1] = gdk_pixbuf_new_from_file
-+ (INTLCLOCK_ICONDIR "/intlclock-map-location-hilight.png", NULL);
-+ priv->location_marker_pixbuf[2] = gdk_pixbuf_new_from_file
-+ (INTLCLOCK_ICONDIR "/intlclock-map-location-current.png", NULL);
-
- g_signal_connect (G_OBJECT (priv->clock), "tick",
- G_CALLBACK (intlclock_map_tick), this);
-@@ -78,6 +83,12 @@ intlclock_map_new (IntlClock *clock)
- g_signal_connect (G_OBJECT (priv->clock), "locations_changed",
- G_CALLBACK (intlclock_map_locations_changed), this);
-
-+ g_signal_connect (G_OBJECT (priv->clock), "current_timezone_changed",
-+ G_CALLBACK (intlclock_map_locations_changed), this);
-+
-+ g_signal_connect (G_OBJECT (priv->clock), "blink_location",
-+ G_CALLBACK (intlclock_map_blink_location), this);
-+
- intlclock_map_refresh (this);
-
- return this;
-@@ -109,13 +120,16 @@ intlclock_map_init (IntlClockMap *this)
- priv->clock = NULL;
-
- priv->stock_map_pixbuf = NULL;
-- priv->location_marker_pixbuf = NULL;
-+ priv->location_marker_pixbuf[0] = NULL;
-+ priv->location_marker_pixbuf[1] = NULL;
-+ priv->location_marker_pixbuf[2] = NULL;
- }
-
- static void
- intlclock_map_finalize (GObject *g_obj)
- {
- IntlClockMapPrivate *priv = PRIVATE (g_obj);
-+ int i;
-
- g_signal_handlers_disconnect_by_func
- (priv->clock, G_CALLBACK (intlclock_map_tick), g_obj);
-@@ -130,10 +144,12 @@ intlclock_map_finalize (GObject *g_obj)
- priv->stock_map_pixbuf = NULL;
- }
-
-- if (priv->location_marker_pixbuf) {
-- gdk_pixbuf_unref (priv->location_marker_pixbuf);
-- priv->location_marker_pixbuf = NULL;
-- }
-+ for (i = 0; i < 3; i++) {
-+ if (priv->location_marker_pixbuf[i]) {
-+ gdk_pixbuf_unref (priv->location_marker_pixbuf[i]);
-+ priv->location_marker_pixbuf[i] = NULL;
-+ }
-+ }
-
- if (priv->location_map_pixbuf) {
- gdk_pixbuf_unref (priv->location_map_pixbuf);
-@@ -164,12 +180,13 @@ intlclock_map_refresh (IntlClockMap *this)
- IntlClockMapPrivate *priv = PRIVATE (this);
- GtkWidget *widget = GTK_WIDGET (this);
- GtkWidget *parent = gtk_widget_get_parent (widget);
-+ GtkRequisition req;
- gint width;
- gint height;
-
-- gtk_widget_size_request (widget, &(widget->requisition));
-- width = widget->requisition.width;
-- height = widget->requisition.height;
-+ gtk_widget_size_request (widget, &req);
-+ width = req.width;
-+ height = req.height;
-
- if (parent) {
- if (widget->allocation.width != 1) {
-@@ -276,10 +293,10 @@ intlclock_map_size_allocate (GtkWidget *this, GtkAllocation *allocation)
- }
-
- static void
--intlclock_map_mark (IntlClockMap *this, gfloat latitude, gfloat longitude)
-+intlclock_map_mark (IntlClockMap *this, gfloat latitude, gfloat longitude, gint mark)
- {
- IntlClockMapPrivate *priv = PRIVATE (this);
-- GdkPixbuf *marker = priv->location_marker_pixbuf;
-+ GdkPixbuf *marker = priv->location_marker_pixbuf[mark];
- GdkPixbuf *partial = NULL;
-
- int x, y;
-@@ -395,14 +412,22 @@ intlclock_map_mark (IntlClockMap *this, gfloat latitude, gfloat longitude)
- }
-
- static void
--intlclock_map_place_location (IntlClockMap *this, IntlClockLocation *loc)
-+intlclock_map_place_location (IntlClockMap *this, IntlClockLocation *loc, gboolean hilight)
- {
- IntlClockMapPrivate *priv = PRIVATE (this);
- gfloat latitude, longitude;
-+ gint marker;
-
- intlclock_location_get_coords (loc, &latitude, &longitude);
-
-- intlclock_map_mark (this, latitude, longitude);
-+ if (hilight)
-+ marker = 1;
-+ else if (intlclock_location_is_current (loc))
-+ marker = 2;
-+ else
-+ marker = 0;
-+
-+ intlclock_map_mark (this, latitude, longitude, marker);
- }
-
- static void
-@@ -428,7 +453,7 @@ intlclock_map_place_locations (IntlClockMap *this)
- while (locs) {
- loc = INTLCLOCK_LOCATION (locs->data);
-
-- intlclock_map_place_location (this, loc);
-+ intlclock_map_place_location (this, loc, FALSE);
-
- locs = locs->next;
- }
-@@ -633,16 +658,12 @@ intlclock_map_rotate (IntlClockMap *this)
- static void
- intlclock_map_display (IntlClockMap *this)
- {
-- IntlClockMapPrivate *priv = PRIVATE (this);
--
- gtk_widget_queue_draw (GTK_WIDGET (this));
- }
-
- static void
- intlclock_map_locations_changed (IntlClock *clock, IntlClockMap *this)
- {
-- IntlClockMapPrivate *priv = PRIVATE (this);
--
- intlclock_map_place_locations (this);
-
- intlclock_map_render_shadow (this);
-@@ -651,6 +672,49 @@ intlclock_map_locations_changed (IntlClock *clock, IntlClockMap *this)
- intlclock_map_display (this);
- }
-
-+typedef struct {
-+ IntlClockMap *map;
-+ IntlClockLocation *location;
-+ int count;
-+} BlinkData;
-+
-+static gboolean
-+highlight (gpointer user_data)
-+{
-+ BlinkData *data = user_data;
-+
-+ if (data->count == 6) {
-+ g_free (data);
-+ return FALSE;
-+ }
-+
-+ if (data->count % 2 == 0)
-+ intlclock_map_place_location (data->map, data->location, TRUE);
-+ else
-+ intlclock_map_place_locations (data->map);
-+ intlclock_map_render_shadow (data->map);
-+ intlclock_map_rotate (data->map);
-+ intlclock_map_display (data->map);
-+
-+ data->count++;
-+
-+ return TRUE;
-+}
-+
-+static void
-+intlclock_map_blink_location (IntlClock *clock, IntlClockLocation *loc, IntlClockMap *this)
-+{
-+ BlinkData *data;
-+
-+ data = g_new0 (BlinkData, 1);
-+ data->map = this;
-+ data->location = loc;
-+
-+ highlight (data);
-+
-+ g_timeout_add (300, highlight, data);
-+}
-+
- static gboolean
- intlclock_map_needs_refresh (IntlClockMap *this)
- {
-diff --git a/src/intlclock-marshallers.c b/src/intlclock-marshallers.c
-deleted file mode 100644
-index 8f01ab8..0000000
---- a/src/intlclock-marshallers.c
-+++ /dev/null
-@@ -1,51 +0,0 @@
--
--#include <glib-object.h>
--
--
--#ifdef G_ENABLE_DEBUG
--#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
--#define g_marshal_value_peek_char(v) g_value_get_char (v)
--#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
--#define g_marshal_value_peek_int(v) g_value_get_int (v)
--#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
--#define g_marshal_value_peek_long(v) g_value_get_long (v)
--#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
--#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
--#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
--#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
--#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
--#define g_marshal_value_peek_float(v) g_value_get_float (v)
--#define g_marshal_value_peek_double(v) g_value_get_double (v)
--#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
--#define g_marshal_value_peek_param(v) g_value_get_param (v)
--#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
--#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
--#define g_marshal_value_peek_object(v) g_value_get_object (v)
--#else /* !G_ENABLE_DEBUG */
--/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
-- * Do not access GValues directly in your code. Instead, use the
-- * g_value_get_*() functions
-- */
--#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
--#define g_marshal_value_peek_char(v) (v)->data[0].v_int
--#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
--#define g_marshal_value_peek_int(v) (v)->data[0].v_int
--#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
--#define g_marshal_value_peek_long(v) (v)->data[0].v_long
--#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
--#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
--#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
--#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
--#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
--#define g_marshal_value_peek_float(v) (v)->data[0].v_float
--#define g_marshal_value_peek_double(v) (v)->data[0].v_double
--#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
--#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
--#endif /* !G_ENABLE_DEBUG */
--
--
--/* VOID:VOID (intlclock-marshallers.list:1) */
--
-diff --git a/src/intlclock-marshallers.h b/src/intlclock-marshallers.h
-deleted file mode 100644
-index c022a3e..0000000
---- a/src/intlclock-marshallers.h
-+++ /dev/null
-@@ -1,15 +0,0 @@
--
--#ifndef ___intlclock_marshal_MARSHAL_H__
--#define ___intlclock_marshal_MARSHAL_H__
--
--#include <glib-object.h>
--
--G_BEGIN_DECLS
--
--/* VOID:VOID (intlclock-marshallers.list:1) */
--#define _intlclock_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
--
--G_END_DECLS
--
--#endif /* ___intlclock_marshal_MARSHAL_H__ */
--
-diff --git a/src/intlclock-marshallers.list b/src/intlclock-marshallers.list
-index 5b76282..e737cac 100644
---- a/src/intlclock-marshallers.list
-+++ b/src/intlclock-marshallers.list
-@@ -1 +1,3 @@
- VOID:VOID
-+VOID:OBJECT
-+VOID:POINTER
-diff --git a/src/intlclock-sunpos.c b/src/intlclock-sunpos.c
-index 942617b..89d4cc1 100644
---- a/src/intlclock-sunpos.c
-+++ b/src/intlclock-sunpos.c
-@@ -1,348 +1,196 @@
- /*
-- * sunpos.c
-- * kirk johnson
-- * july 1993
-+ * Copyright (C) 2007 Red Hat, Inc.
- *
-- * includes revisions from Frank T. Solensky, february 1999
-+ * 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.
- *
-- * code for calculating the position on the earth's surface for which
-- * the sun is directly overhead (adapted from _practical astronomy
-- * with your calculator, third edition_, peter duffett-smith,
-- * cambridge university press, 1988.)
-+ * 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.
- *
-- * Copyright (C) 1989, 1990, 1993-1995, 1999 Kirk Lauritz Johnson
-+ * 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.
- *
-- * Parts of the source code (as marked) are:
-- * Copyright (C) 1989, 1990, 1991 by Jim Frost
-- * Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
-- *
-- * Permission to use, copy, modify and freely distribute xearth for
-- * non-commercial and not-for-profit purposes is hereby granted
-- * without fee, provided that both the above copyright notice and this
-- * permission notice appear in all copies and in supporting
-- * documentation.
-- *
-- * Unisys Corporation holds worldwide patent rights on the Lempel Zev
-- * Welch (LZW) compression technique employed in the CompuServe GIF
-- * image file format as well as in other formats. Unisys has made it
-- * clear, however, that it does not require licensing or fees to be
-- * paid for freely distributed, non-commercial applications (such as
-- * xearth) that employ LZW/GIF technology. Those wishing further
-- * information about licensing the LZW patent should contact Unisys
-- * directly at (lzw_info@unisys.com) or by writing to
-- *
-- * Unisys Corporation
-- * Welch Licensing Department
-- * M/S-C1SW19
-- * P.O. Box 500
-- * Blue Bell, PA 19424
-- *
-- * The author makes no representations about the suitability of this
-- * software for any purpose. It is provided "as is" without express or
-- * implied warranty.
-- *
-- * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
-- * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ * Authors:
-+ * Jonathan Blandford <jrb@redhat.com>
-+ * Matthias Clasen <mclasen@redhat.com>
- */
--
--#include <assert.h>
--#include <math.h>
-+
- #include <time.h>
-+#include <gtk/gtk.h>
-+#include <math.h>
-
--#include "intlclock-sunpos.h"
--
--#define TWOPI (2*M_PI)
--#define DegsToRads(x) ((x)*(TWOPI/360))
--
--/*
-- * the epoch upon which these astronomical calculations are based is
-- * 1990 january 0.0, 631065600 seconds since the beginning of the
-- * "unix epoch" (00:00:00 GMT, Jan. 1, 1970)
-- *
-- * given a number of seconds since the start of the unix epoch,
-- * DaysSinceEpoch() computes the number of days since the start of the
-- * astronomical epoch (1990 january 0.0)
-- */
--
--#define EpochStart (631065600)
--#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
--
--/*
-- * assuming the apparent orbit of the sun about the earth is circular,
-- * the rate at which the orbit progresses is given by RadsPerDay --
-- * TWOPI radians per orbit divided by 365.242191 days per year:
-- */
--
--#define RadsPerDay (TWOPI/365.242191)
--
--/*
-- * details of sun's apparent orbit at epoch 1990.0 (after
-- * duffett-smith, table 6, section 46)
-- *
-- * Epsilon_g (ecliptic longitude at epoch 1990.0) 279.403303 degrees
-- * OmegaBar_g (ecliptic longitude of perigee) 282.768422 degrees
-- * Eccentricity (eccentricity of orbit) 0.016713
-+/* Calculated with the methods and figures from "Practical Astronomy With Your
-+ * Calculator, version 3" by Peter Duffet-Smith.
- */
-+/* Table 6. Details of the Sun's apparent orbit at epoch 1990.0 */
-
--#define Epsilon_g (DegsToRads(279.403303))
--#define OmegaBar_g (DegsToRads(282.768422))
--#define Eccentricity (0.016713)
-+#define EPOCH 2447891.5 /* days */ /* epoch 1990 */
-+#define UNIX_EPOCH 2440586.5 /* days */ /* epoch 1970 */
-+#define EPSILON_G 279.403303 /* degrees */ /* ecliptic longitude at epoch 1990.0 */
-+#define MU_G 282.768422 /* degrees */ /* ecliptic longitude at perigree */
-+#define ECCENTRICITY 0.016713 /* eccentricity of orbit */
-+#define R_0 149598500 /* km */ /* semi-major access */
-+#define THETA_0 0.533128 /* degrees */ /* angular diameter at r = r_0 */
-+#define MEAN_OBLIQUITY 23.440592 /* degrees */ /* mean obliquity of earths axis at epoch 1990.0 */
-
--/*
-- * MeanObliquity gives the mean obliquity of the earth's axis at epoch
-- * 1990.0 (computed as 23.440592 degrees according to the method given
-- * in duffett-smith, section 27)
-- */
--#define MeanObliquity (23.440592*(TWOPI/360))
-+#define NORMALIZE(x) \
-+ while (x>360) x-=360; while (x<0) x+= 360;
-
--/*
-- * Lunar parameters, epoch January 0, 1990.0
-- */
--#define MoonMeanLongitude DegsToRads(318.351648)
--#define MoonMeanLongitudePerigee DegsToRads( 36.340410)
--#define MoonMeanLongitudeNode DegsToRads(318.510107)
--#define MoonInclination DegsToRads( 5.145396)
-+#define DEG_TO_RADS(x) \
-+ (x * G_PI/180.0)
-
--#define SideralMonth (27.3217)
-+#define RADS_TO_DEG(x) \
-+ (x * 180.0/G_PI)
-
--/*
-- * Force an angular value into the range [-PI, +PI]
-+/* Calculate number of days since 4713BC.
- */
--#define Normalize(x) \
-- do { \
-- if ((x) < -M_PI) \
-- do (x) += TWOPI; while ((x) < -M_PI); \
-- else if ((x) > M_PI) \
-- do (x) -= TWOPI; while ((x) > M_PI); \
-- } while (0)
--
--static double solve_keplers_equation (double);
--static double mean_sun (double);
--static double sun_ecliptic_longitude (time_t);
--static void ecliptic_to_equatorial (double, double, double *, double *);
--static double julian_date (int, int, int);
--static double GST (time_t);
--
--/*
-- * solve Kepler's equation via Newton's method
-- * (after duffett-smith, section 47)
-- */
--static double solve_keplers_equation(M)
-- double M;
-+static gdouble
-+unix_time_to_julian_date (gint unix_time)
- {
-- double E;
-- double delta;
--
-- E = M;
-- while (1)
-- {
-- delta = E - Eccentricity*sin(E) - M;
-- if (fabs(delta) <= 1e-10) break;
-- E -= delta / (1 - Eccentricity*cos(E));
-- }
--
-- return E;
-+ return UNIX_EPOCH + (double) unix_time / (60 * 60 * 24);
- }
-
-+/* Finds an iterative solution for [ E - e sin (E) = M ] for values of e less
-+ than 0.1. Page 90 */
-
--/*
-- * Calculate the position of the mean sun: where the sun would
-- * be if the earth's orbit were circular instead of ellipictal.
-- */
-+#define ERROR_ACCURACY 1e-6 /* radians */
-
--static double mean_sun (D)
-- double D; /* days since ephemeris epoch */
-+static gdouble
-+solve_keplers_equation (gdouble e,
-+ gdouble M)
- {
-- double N, M;
-+ gdouble d, E;
-
-- N = RadsPerDay * D;
-- N = fmod(N, TWOPI);
-- if (N < 0) N += TWOPI;
-+ /* start with an initial estimate */
-+ E = M;
-+
-+ d = E - e * sin (E) - M;
-+
-+ while (ABS (d) > ERROR_ACCURACY)
-+ {
-+ E = E - (d / (1 - e * cos (E)));
-+ d = E - e * sin (E) - M;
-+ }
-
-- M = N + Epsilon_g - OmegaBar_g;
-- if (M < 0) M += TWOPI;
-- return M;
-+ return E;
- }
-
--/*
-- * compute ecliptic longitude of sun (in radians)
-- * (after duffett-smith, section 47)
-- */
--static double sun_ecliptic_longitude(ssue)
-- time_t ssue; /* seconds since unix epoch */
-+ /* convert the ecliptic longitude to right ascension and declination. Section 27. */
-+static void
-+ecliptic_to_equatorial (gdouble lambda,
-+ gdouble beta,
-+ gdouble *ra,
-+ gdouble *dec)
- {
-- double D;
-- double M_sun, E;
-- double v;
-+ gdouble cos_mo;
-+ gdouble sin_mo;
-
-- D = DaysSinceEpoch(ssue);
-- M_sun = mean_sun(D);
-+ g_assert (ra != NULL);
-+ g_assert (dec != NULL);
-
-- E = solve_keplers_equation(M_sun);
-- v = 2 * atan(sqrt((1+Eccentricity)/(1-Eccentricity)) * tan(E/2));
-+ sin_mo = sin (DEG_TO_RADS (MEAN_OBLIQUITY));
-+ cos_mo = cos (DEG_TO_RADS (MEAN_OBLIQUITY));
-
-- return (v + OmegaBar_g);
-+ *ra = atan2 (sin (lambda) * cos_mo - tan (beta) * sin_mo, cos (lambda));
-+ *dec = asin (sin (beta) * cos_mo + cos (beta) * sin_mo * sin (lambda));
- }
-
--
--/*
-- * convert from ecliptic to equatorial coordinates
-- * (after duffett-smith, section 27)
-- */
--static void ecliptic_to_equatorial(lambda, beta, alpha, delta)
-- double lambda; /* ecliptic longitude */
-- double beta; /* ecliptic latitude */
-- double *alpha; /* (return) right ascension */
-- double *delta; /* (return) declination */
-+/* calculate GST. Section 12 */
-+static gdouble
-+greenwich_sidereal_time (gdouble unix_time)
- {
-- double sin_e, cos_e;
-+ gdouble u, JD, T, T0, UT;
-
-- sin_e = sin(MeanObliquity);
-- cos_e = cos(MeanObliquity);
-+ u = fmod (unix_time, 24 * 60 * 60);
-+ JD = unix_time_to_julian_date (unix_time - u);
-+ T = (JD - 2451545) / 36525;
-+ T0 = 6.697374558 + (2400.051336 * T) + (0.000025862 * T * T);
-+ T0 = fmod (T0, 24);
-+ UT = u / (60 * 60);
-+ T0 = T0 + UT * 1.002737909;
-+ T0 = fmod (T0, 24);
-
-- *alpha = atan2(sin(lambda)*cos_e - tan(beta)*sin_e, cos(lambda));
-- *delta = asin(sin(beta)*cos_e + cos(beta)*sin_e*sin(lambda));
-+ return T0;
- }
-
--
--/*
-- * computing julian dates (assuming gregorian calendar, thus this is
-- * only valid for dates of 1582 oct 15 or later)
-- * (after duffett-smith, section 4)
-- */
--static double julian_date(y, m, d)
-- int y; /* year (e.g. 19xx) */
-- int m; /* month (jan=1, feb=2, ...) */
-- int d; /* day of month */
-+/* Calculate the position of the sun at a given time. pages 89-91 */
-+void
-+sun_position (gint unix_time, gdouble *lat, gdouble *lon)
- {
-- int A, B, C, D;
-- double JD;
-+ gdouble jd, D, N, M, E, x, v, lambda;
-+ gdouble ra, dec;
-+ jd = unix_time_to_julian_date (unix_time);
-
-- /* lazy test to ensure gregorian calendar */
-- assert(y >= 1583);
-+ /* Calculate number of days since the epoch */
-+ D = jd - EPOCH;
-
-- if ((m == 1) || (m == 2))
-- {
-- y -= 1;
-- m += 12;
-- }
-+ N = D*360/365.242191;
-
-- A = y / 100;
-- B = 2 - A + (A / 4);
-- C = 365.25 * y;
-- D = 30.6001 * (m + 1);
-+ /* normalize to 0 - 360 degrees */
-+ NORMALIZE (N);
-
-- JD = B + C + D + d + 1720994.5;
-+ /* Step 4: */
-+ M = N + EPSILON_G - MU_G;
-+ NORMALIZE (M);
-
-- return JD;
--}
--
--
--/*
-- * compute greenwich mean sidereal time (GST) corresponding to a given
-- * number of seconds since the unix epoch
-- * (after duffett-smith, section 12)
-- */
--static double GST(ssue)
-- time_t ssue; /* seconds since unix epoch */
--{
-- double JD;
-- double T, T0;
-- double UT;
-- struct tm *tm;
-+ /* Step 5: convert to radians */
-+ M = DEG_TO_RADS (M);
-
-- tm = gmtime(&ssue);
-+ /* Step 6: */
-+ E = solve_keplers_equation (ECCENTRICITY, M);
-
-- JD = julian_date(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
-- T = (JD - 2451545) / 36525;
-+ /* Step 7: */
-+ x = sqrt ((1 + ECCENTRICITY)/(1 - ECCENTRICITY)) * tan (E/2);
-
-- T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
-+ /* Step 8, 9 */
-+ v = 2 * RADS_TO_DEG (atan (x));
-+ NORMALIZE (v);
-
-- T0 = fmod(T0, 24.0);
-- if (T0 < 0) T0 += 24;
-+ /* Step 10 */
-+ lambda = v + MU_G;
-+ NORMALIZE (lambda);
-
-- UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
-+ /* convert the ecliptic longitude to right ascension and declination */
-+ ecliptic_to_equatorial (DEG_TO_RADS (lambda), 0.0, &ra, &dec);
-
-- T0 += UT * 1.002737909;
-- T0 = fmod(T0, 24.0);
-- if (T0 < 0) T0 += 24;
-+ ra = ra - (G_PI/12) * greenwich_sidereal_time (unix_time);
-+ ra = RADS_TO_DEG (ra);
-+ dec = RADS_TO_DEG (dec);
-+ NORMALIZE (ra);
-+ NORMALIZE (dec);
-
-- return T0;
-+ *lat = dec;
-+ *lon = ra;
- }
-
-
--/*
-- * given a particular time (expressed in seconds since the unix
-- * epoch), compute position on the earth (lat, lon) such that sun is
-- * directly overhead.
-- */
--void sun_position(ssue, lat, lon)
-- time_t ssue; /* seconds since unix epoch */
-- double *lat; /* (return) latitude */
-- double *lon; /* (return) longitude */
-+#if 0
-+int
-+main (int argc, char *argv[])
- {
-- double lambda;
-- double alpha, delta;
-- double tmp;
-+ gint i;
-+ gint now;
-+ GTimeVal timeval;
-+ gdouble lat, lon;
-
-- lambda = sun_ecliptic_longitude(ssue);
-- ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta);
-+ gtk_init (&argc, &argv);
-
-- tmp = alpha - (TWOPI/24)*GST(ssue);
-- Normalize(tmp);
-- *lon = tmp * (360/TWOPI);
-- *lat = delta * (360/TWOPI);
--}
-+ g_get_current_time (&timeval);
-+ now = timeval.tv_sec;
-
-+ for (i = 0; i < now; i += 15 * 60)
-+ {
-+ sun_position (i, &lat, &lon);
-+ g_print ("%d: %f %f\n", lat, lon);
-+ }
-
--/*
-- * given a particular time (expressed in seconds since the unix
-- * epoch), compute position on the earth (lat, lon) such that the
-- * moon is directly overhead.
-- *
-- * Based on duffett-smith **2nd ed** section 61; combines some steps
-- * into single expressions to reduce the number of extra variables.
-- */
--void moon_position(ssue, lat, lon)
-- time_t ssue; /* seconds since unix epoch */
-- double *lat; /* (return) latitude */
-- double *lon; /* (return) longitude */
--{
-- double lambda, beta;
-- double D, L, Ms, Mm, N, Ev, Ae, Ec, alpha, delta;
--
-- D = DaysSinceEpoch(ssue);
-- lambda = sun_ecliptic_longitude(ssue);
-- Ms = mean_sun(D);
--
-- L = fmod(D/SideralMonth, 1.0)*TWOPI + MoonMeanLongitude;
-- Normalize(L);
-- Mm = L - DegsToRads(0.1114041*D) - MoonMeanLongitudePerigee;
-- Normalize(Mm);
-- N = MoonMeanLongitudeNode - DegsToRads(0.0529539*D);
-- Normalize(N);
-- Ev = DegsToRads(1.2739) * sin(2.0*(L-lambda)-Mm);
-- Ae = DegsToRads(0.1858) * sin(Ms);
-- Mm += Ev - Ae - DegsToRads(0.37)*sin(Ms);
-- Ec = DegsToRads(6.2886) * sin(Mm);
-- L += Ev + Ec - Ae + DegsToRads(0.214) * sin(2.0*Mm);
-- L += DegsToRads(0.6583) * sin(2.0*(L-lambda));
-- N -= DegsToRads(0.16) * sin(Ms);
--
-- L -= N;
-- lambda =(fabs(cos(L)) < 1e-12) ?
-- (N + sin(L) * cos(MoonInclination) * M_PI/2) :
-- (N + atan2(sin(L) * cos(MoonInclination), cos(L)));
-- Normalize(lambda);
-- beta = asin(sin(L) * sin(MoonInclination));
-- ecliptic_to_equatorial(lambda, beta, &alpha, &delta);
-- alpha -= (TWOPI/24)*GST(ssue);
-- Normalize(alpha);
-- *lon = alpha * (360/TWOPI);
-- *lat = delta * (360/TWOPI);
-+ return 0;
- }
-+
-+#endif
-diff --git a/src/intlclock-ui.c b/src/intlclock-ui.c
-index f51e4de..f0d70bd 100644
---- a/src/intlclock-ui.c
-+++ b/src/intlclock-ui.c
-@@ -14,6 +14,7 @@
- #include <libgnome/gnome-i18n.h>
- #include <locale.h>
- #include <math.h>
-+#include <time.h>
- #include <panel-applet-gconf.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -26,18 +27,18 @@
- #include "intlclock-map.h"
- #include "intlclock-zoneinfo.h"
- #include "intlclock-zonetable.h"
-+#include "set-timezone.h"
-+#include "gweather-xml.h"
-
- G_DEFINE_TYPE (IntlClockUI, intlclock_ui, G_TYPE_OBJECT)
-
- /* GConf keys for compatibility with the older GNOME clock */
--#define N_GCONF_PREFS 7
-+#define N_GCONF_PREFS 5
- static const char *KEY_CITIES = "cities";
- static const char *KEY_FORMAT = "format";
- static const char *KEY_SHOW_SECONDS = "show_seconds";
- static const char *KEY_SHOW_DATE = "show_date";
- static const char *KEY_SHOW_WEEK = "show_week_numbers";
--static const char *KEY_SHOW_LOCATIONS = "show_locations";
--static const char *KEY_SHOW_MAP = "show_map";
-
- /* Needs to match the indices in the combo */
- typedef enum {
-@@ -78,12 +79,14 @@ typedef struct {
- GtkWidget *panel_box;
- GtkWidget *panel_button;
- GtkWidget *panel_label;
-+ GtkWidget *panel_weather_icon;
-
- GtkTooltips *panel_tips;
-
- GtkWidget *panel_button_popup;
-
- GtkWidget *clock_vbox;
-+ GtkSizeGroup *clock_group;
-
- GtkWidget *main_section;
- GtkWidget *clock_calendar;
-@@ -97,17 +100,34 @@ typedef struct {
-
- GtkListStore *cities_store;
-
-- gboolean show_locations;
-- gboolean show_map;
--
- GtkWidget *prefs_window;
- GtkTreeView *prefs_locations;
-
-+ GtkWidget *prefs_location_add_button;
-+ GtkWidget *prefs_location_edit_button;
-+ GtkWidget *prefs_location_remove_button;
-+
-+ GtkWidget *location_tree;
-+ GtkWidget *find_next_location_button;
-+ GtkWidget *find_location_entry;
-+ GtkWidget *find_location_ok_button;
-+
-+ GtkWidget *set_time_window;
-+ GtkWidget *hours_spin;
-+ GtkWidget *minutes_spin;
-+ GtkWidget *seconds_spin;
-+ GtkWidget *calendar;
-+ GtkWidget *current_time_label;
-+ GtkWidget *set_time_button;
-+ GtkWidget *time_settings_button;
-+
- gboolean format_12hr;
- gboolean format_show_seconds;
- gboolean format_show_date;
- gboolean format_show_week;
-
-+ gulong zone_combo_changed;
-+
- guint listeners [N_GCONF_PREFS];
- } IntlClockUIPrivate;
-
-@@ -118,51 +138,51 @@ static gboolean update_panel_label (gpointer this);
- static void setup_gconf (IntlClockUI *this);
- static void load_gconf_settings (IntlClockUI *this);
-
--static void bonobo_run_time_configuration (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname);
- static void bonobo_display_properties_dialog (BonoboUIComponent *uic,
- IntlClockUI *this,
- const gchar *verbname);
--static void display_help_dialog (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname);
--static void display_about_dialog (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname);
--
--static void config_date (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname);
-
- static void intlclock_reposition_events_window (IntlClockUI *this);
--
- static void position_popup_window (IntlClockUI *this,
- GtkWindow *window,
- GtkWidget *origin);
-
--static void display_prefs_window_cb (GtkButton *button, gpointer this);
--static void run_time_configuration (IntlClockUI *this);
--static void run_time_configuration_cb (GtkButton *button, gpointer this);
-+static void display_prefs_window (IntlClockUI *this, gboolean locations);
- static void run_prefs_locations_add (GtkButton *button, gpointer this);
- static void run_prefs_locations_edit (GtkButton *button, gpointer this);
- static void run_prefs_locations_remove (GtkButton *button, gpointer this);
- static void run_prefs_edit_save (GtkButton *button, gpointer this);
--
-+static void run_find_location (GtkButton *button, gpointer this);
-+static void run_find_location_save (GtkButton *button, gpointer this);
-+static void intlclock_edit_hide (GtkWidget *widget, IntlClockUI *this);
-+static void intlclock_find_hide (GtkWidget *widget, IntlClockUI *this);
- static void intlclock_ui_save_cities_store (IntlClockUI *this);
-
- static void intlclock_ui_locations_changed (IntlClock *clock, IntlClockUI *this);
-
- static void create_cities_section (IntlClockUI *this);
- static void create_events_window (IntlClockUI *this);
--static void create_main_section (IntlClockUI *this);
- static void create_map_section (IntlClockUI *this);
-
- static void zone_combo_changed (GtkComboBox *widget, gpointer this);
-+static void update_coords (IntlClockUI *this, gboolean valid, gfloat lat, gfloat lon);
-+static void fill_location_tree (IntlClockUI *this);
-+static void copy_time (BonoboUIComponent *uic,
-+ IntlClockUI *this,
-+ const gchar *verbname);
-+static void copy_date (BonoboUIComponent *uic,
-+ IntlClockUI *this,
-+ const gchar *verbname);
-+static void config_date (BonoboUIComponent *uic,
-+ IntlClockUI *this,
-+ const gchar *verbname);
-+
-
- static const BonoboUIVerb intlclock_menu_verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("IntlClockPreferences", bonobo_display_properties_dialog),
-- BONOBO_UI_UNSAFE_VERB ("IntlClockConfig", bonobo_run_time_configuration),
-+ BONOBO_UI_UNSAFE_VERB ("ClockCopyTime", copy_time),
-+ BONOBO_UI_UNSAFE_VERB ("ClockCopyDate", copy_date),
-+ BONOBO_UI_UNSAFE_VERB ("ClockConfig", config_date),
- BONOBO_UI_VERB_END
- };
-
-@@ -190,11 +210,6 @@ intlclock_ui_is_12hr (IntlClockUI *this)
- static gboolean
- panel_button_press_cb (GtkWidget *button, GdkEventButton *event, gpointer data)
- {
-- IntlClockUI *this = INTLCLOCK_UI (data);
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- GtkToggleButton *toggle = GTK_TOGGLE_BUTTON (button);
--
- if (event->button != 1)
- g_signal_stop_emission_by_name (button, "button_press_event");
-
-@@ -206,7 +221,9 @@ intlclock_ui_reset_timeout (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-
-- if (GTK_WIDGET_VISIBLE (priv->events_window) || priv->format_show_seconds) {
-+ if (GTK_WIDGET_VISIBLE (priv->events_window) ||
-+ (priv->set_time_window && GTK_WIDGET_VISIBLE (priv->set_time_window)) ||
-+ priv->format_show_seconds) {
- intlclock_set_tick_timeout (INTLCLOCK (priv->clock), 1);
- } else {
- intlclock_set_tick_timeout (INTLCLOCK (priv->clock), 60);
-@@ -244,20 +261,6 @@ panel_button_clicked_cb (GtkButton *button, gpointer data)
- intlclock_ui_reset_timeout (this);
- }
-
--static gboolean
--panel_events_button_press_cb (GtkWidget *button, GdkEventButton *event, gpointer data)
--{
-- IntlClockUI *this = INTLCLOCK_UI (data);
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- GtkToggleButton *toggle = GTK_TOGGLE_BUTTON (button);
--
-- if (event->button != 1)
-- g_signal_stop_emission_by_name (button, "button_press_event");
--
-- return FALSE;
--}
--
- static void
- position_popup_window (IntlClockUI *this,
- GtkWindow *window,
-@@ -375,147 +378,6 @@ intlclock_events_window_size_allocate_cb (GtkWidget *widget, GtkAllocation *allo
- intlclock_reposition_events_window (this);
- }
-
--static gboolean
--intlclock_window_expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
--{
-- IntlClockUIPrivate *priv = PRIVATE (user_data);
--
-- cairo_t *cr;
--
-- cr = gdk_cairo_create (widget->window);
--
-- cairo_rectangle (
-- cr,
-- event->area.x, event->area.y,
-- event->area.width, event->area.height);
--
-- cairo_clip (cr);
--
--/* draw window background */
--
-- cairo_rectangle (
-- cr,
-- widget->allocation.x + 0.5, widget->allocation.y + 0.5,
-- widget->allocation.width - 1, widget->allocation.height - 1);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->bg [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->bg [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->bg [GTK_STATE_ACTIVE].blue / 65535.0);
--
-- cairo_fill_preserve (cr);
--
--/* draw window outline */
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
--
-- cairo_set_line_width (cr, 1.0);
-- cairo_stroke (cr);
--
--/* draw main pane background */
--
-- cairo_rectangle (
-- cr,
-- priv->main_section->allocation.x + 0.5, priv->main_section->allocation
--.y + 0.5,
-- priv->main_section->allocation.width - 1, priv->main_section->allocation.height - 1);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->bg [GTK_STATE_NORMAL].red / 65535.0,
-- widget->style->bg [GTK_STATE_NORMAL].green / 65535.0,
-- widget->style->bg [GTK_STATE_NORMAL].blue / 65535.0);
--
-- cairo_fill (cr);
--
--/* draw map pane background */
--
-- if (priv->show_map) {
-- cairo_rectangle (
-- cr,
-- priv->map_section->allocation.x + 0.5,
-- priv->map_section->allocation.y + 0.5,
-- priv->map_section->allocation.width - 1,
-- priv->map_section->allocation.height - 1);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->bg [GTK_STATE_NORMAL].red / 65535.0,
-- widget->style->bg [GTK_STATE_NORMAL].green / 65535.0,
-- widget->style->bg [GTK_STATE_NORMAL].blue / 65535.0);
--
-- cairo_fill (cr);
-- }
--
--/* draw internal window outline */
--
-- cairo_rectangle (
-- cr,
-- priv->clock_vbox->allocation.x + 0.5, priv->clock_vbox->allocation.y + 0.5,
-- priv->clock_vbox->allocation.width - 1, priv->clock_vbox->allocation.height - 1);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
--
-- cairo_stroke (cr);
--
--/* draw map/cities pane separator */
--
-- if (priv->show_map) {
-- cairo_move_to (
-- cr,
-- priv->map_section->allocation.x + 0.5,
-- priv->map_section->allocation.y + priv->map_section->allocation.height - 0.5);
--
-- cairo_line_to (
-- cr,
-- priv->map_section->allocation.x + priv->map_section->allocation.width - 0.5,
-- priv->map_section->allocation.y + priv->map_section->allocation.height - 0.5);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
--
-- cairo_stroke (cr);
-- }
--
--/* draw cities/main pane separator */
--
-- if (priv->show_locations) {
-- cairo_move_to (
-- cr,
-- priv->cities_section->allocation.x + 0.5,
-- priv->cities_section->allocation.y + priv->cities_section->allocation.height - 0.5);
--
-- cairo_line_to (
-- cr,
-- priv->cities_section->allocation.x + priv->cities_section->allocation.width - 0.5,
-- priv->cities_section->allocation.y + priv->cities_section->allocation.height - 0.5);
--
-- cairo_set_source_rgb (
-- cr,
-- widget->style->dark [GTK_STATE_ACTIVE].red / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].green / 65535.0,
-- widget->style->dark [GTK_STATE_ACTIVE].blue / 65535.0);
--
-- cairo_stroke (cr);
-- }
--
-- cairo_destroy (cr);
--
-- return FALSE;
--}
--
- static void
- intlclock_ui_tick (IntlClock *clock, IntlClockUI *this)
- {
-@@ -529,10 +391,7 @@ intlclock_ui_tick (IntlClock *clock, IntlClockUI *this)
- static void
- intlclock_ui_locations_changed (IntlClock *clock, IntlClockUI *this)
- {
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- create_cities_section (this);
-- intlclock_map_refresh (INTLCLOCK_MAP (priv->map_widget));
-+ create_cities_section (this);
- }
-
- static gboolean
-@@ -550,12 +409,20 @@ update_panel_label (gpointer this)
- time (&now_t);
- localtime_r (&now_t, &now);
-
-+ if (priv->current_time_label &&
-+ GTK_WIDGET_VISIBLE (priv->current_time_label)) {
-+ date = intlclock_format_time (priv->clock, &now,
-+ FALSE, FALSE, TRUE,
-+ FALSE, FALSE, NULL, TRUE);
-+ gtk_label_set_markup (GTK_LABEL (priv->current_time_label), date);
-+ g_free (date);
-+ }
-+
- date = intlclock_format_time (priv->clock, &now,
- priv->format_show_date,
- priv->format_12hr,
- priv->format_show_seconds,
- FALSE, priv->format_show_date, NULL, TRUE);
--
- gtk_label_set_markup (GTK_LABEL (priv->panel_label), date);
- g_free (date);
-
-@@ -583,6 +450,7 @@ create_panel_buttons (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
- PanelAppletOrient orient;
-+ GtkWidget *box;
-
- orient = panel_applet_get_orient (priv->panel_applet);
-
-@@ -590,13 +458,18 @@ create_panel_buttons (IntlClockUI *this)
- case PANEL_APPLET_ORIENT_UP:
- case PANEL_APPLET_ORIENT_DOWN:
- priv->panel_box = gtk_hbox_new (FALSE, 0);
-+ box = gtk_hbox_new (FALSE, 6);
- break;
- case PANEL_APPLET_ORIENT_RIGHT:
- case PANEL_APPLET_ORIENT_LEFT:
- priv->panel_box = gtk_vbox_new (FALSE, 0);
-+ box = gtk_vbox_new (FALSE, 6);
- break;
-+ default:
-+ g_assert_not_reached ();
- }
- priv->panel_label = gtk_label_new (NULL);
-+ priv->panel_weather_icon = gtk_image_new ();
- priv->panel_button = gtk_toggle_button_new ();
- priv->panel_tips = gtk_tooltips_new ();
-
-@@ -626,8 +499,9 @@ create_panel_buttons (IntlClockUI *this)
- gtk_button_set_relief (GTK_BUTTON (priv->panel_button),
- GTK_RELIEF_NONE);
-
-- gtk_container_add (GTK_CONTAINER (priv->panel_button),
-- priv->panel_label);
-+ gtk_container_add (GTK_CONTAINER (priv->panel_button), box);
-+ gtk_container_add (GTK_CONTAINER (box), priv->panel_weather_icon);
-+ gtk_container_add (GTK_CONTAINER (box), priv->panel_label);
-
- g_signal_connect (
- G_OBJECT (priv->panel_button), "clicked",
-@@ -655,12 +529,13 @@ create_panel_buttons (IntlClockUI *this)
- );
-
- gtk_widget_show (priv->panel_label);
-+ gtk_widget_show (priv->panel_weather_icon);
-+ gtk_widget_show (box);
-
- gtk_box_pack_start (GTK_BOX (priv->panel_box), priv->panel_button,
- FALSE, FALSE, 0);
-
-- gtk_container_add (GTK_CONTAINER (priv->panel_applet),
-- priv->panel_box);
-+ gtk_container_add (GTK_CONTAINER (priv->panel_applet), priv->panel_box);
-
- gtk_widget_show_all (priv->panel_box);
- }
-@@ -671,10 +546,16 @@ intlclock_ui_change_orient (PanelApplet *applet,
- IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- if (GTK_IS_WIDGET (priv->panel_box))
-- gtk_widget_destroy (priv->panel_box);
-+ GdkPixbuf *pixbuf = NULL;
-+
-+ if (GTK_IS_WIDGET (priv->panel_box)) {
-+ pixbuf = g_object_ref (gtk_image_get_pixbuf (GTK_IMAGE (priv->panel_weather_icon)));
-+ gtk_widget_destroy (priv->panel_box);
-+ }
- create_panel_buttons (this);
-+ intlclock_ui_update_weather_icon (this, pixbuf);
-+ if (pixbuf)
-+ g_object_unref (pixbuf);
- }
-
- static void
-@@ -706,6 +587,16 @@ create_panel_button_popup (IntlClockUI *this)
- "hidden", "1",
- NULL);
- }
-+
-+ if (!can_set_system_time ()) {
-+ popup_component = panel_applet_get_popup_component
-+ (PANEL_APPLET (priv->panel_applet));
-+
-+ bonobo_ui_component_set_prop (popup_component,
-+ "/commands/IntlClockConfig",
-+ "sensitive", "0",
-+ NULL);
-+ }
- }
-
- static void
-@@ -714,7 +605,7 @@ create_events_window (IntlClockUI *this)
- IntlClockUIPrivate *priv = PRIVATE (this);
-
- priv->events_window =
-- GTK_WIDGET (intlclock_events_popup_new (priv->clock, priv->panel_applet));
-+ GTK_WIDGET (intlclock_events_popup_new (priv->clock, priv->panel_applet, this));
-
- g_signal_connect (G_OBJECT (priv->events_window), "size-allocate",
- G_CALLBACK (intlclock_events_window_size_allocate_cb), this);
-@@ -723,41 +614,32 @@ create_events_window (IntlClockUI *this)
- }
-
- static void
--create_clock_window (IntlClockUI *this)
-+add_to_group (GtkWidget *child, gpointer data)
- {
-- IntlClockUIPrivate *priv = PRIVATE (this);
-- GtkSettings *settings;
-- GtkStyle *style;
-+ GtkSizeGroup *group = data;
-
-- priv->clock_vbox = intlclock_events_popup_get_clock_container
-- (INTLCLOCK_EVENTS_POPUP (priv->events_window));
-- gtk_widget_show (priv->clock_vbox);
-+ gtk_size_group_add_widget (group, child);
- }
-
- static void
--create_main_section (IntlClockUI *this)
-+create_clock_window (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-- IntlClockLocation *loc;
-- GtkWidget *header, *subheader;
-- GtkWidget *prefs_button;
-- GtkWidget *prefs_button_box;
--
-- if (!priv->main_section) {
-- priv->main_section = gtk_vbox_new (FALSE, 6);
-- gtk_container_set_border_width
-- (GTK_CONTAINER (priv->main_section),
-- MAIN_SECTION_PADDING);
-- gtk_box_pack_end (GTK_BOX (priv->clock_vbox),
-- priv->main_section, FALSE, FALSE, 0);
-+ GtkWidget *clock_container;
-
-- } else {
-- gtk_container_foreach (GTK_CONTAINER (priv->main_section),
-- (GtkCallback)gtk_widget_destroy,
-- NULL);
-- }
-+ clock_container = intlclock_events_popup_get_clock_container
-+ (INTLCLOCK_EVENTS_POPUP (priv->events_window));
-+ gtk_widget_show (clock_container);
-+
-+ priv->clock_vbox = gtk_vbox_new (FALSE, 6);
-+ gtk_container_add (GTK_CONTAINER (clock_container), priv->clock_vbox);
-
-- gtk_widget_show_all (priv->main_section);
-+ priv->clock_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-+ gtk_size_group_set_ignore_hidden (priv->clock_group, FALSE);
-+
-+ gtk_container_foreach (GTK_CONTAINER (clock_container),
-+ (GtkCallback)add_to_group,
-+ priv->clock_group);
- }
-
- static gint
-@@ -824,7 +706,6 @@ create_cities_section (IntlClockUI *this)
- IntlClockUIPrivate *priv = PRIVATE (this);
- GList *node;
- IntlClockLocationTile *city;
-- GtkWidget *header, *subheader, *image;;
- GList *cities;
-
- if (priv->cities_section) {
-@@ -832,12 +713,8 @@ create_cities_section (IntlClockUI *this)
- priv->cities_section = NULL;
- }
-
-- if (!priv->show_locations) {
-- return;
-- }
--
- priv->cities_section = gtk_vbox_new (FALSE, 6);
-- gtk_container_set_border_width (GTK_CONTAINER (priv->cities_section), 8);
-+ gtk_container_set_border_width (GTK_CONTAINER (priv->cities_section), 0);
-
- cities = intlclock_get_locations (priv->clock);
- if (g_list_length (cities) == 0) {
-@@ -884,10 +761,6 @@ create_map_section (IntlClockUI *this)
- priv->map_widget = NULL;
- }
-
-- if (!priv->show_map) {
-- return;
-- }
--
- map = intlclock_map_new (priv->clock);
-
- priv->map_section = gtk_alignment_new (0, 0, 1, 1);
-@@ -895,11 +768,10 @@ create_map_section (IntlClockUI *this)
-
- gtk_container_add (GTK_CONTAINER (priv->map_section), priv->map_widget);
-
-- gtk_box_pack_start (GTK_BOX (priv->clock_vbox),
-- priv->map_section, FALSE, FALSE, 0);
--
- gtk_alignment_set_padding (GTK_ALIGNMENT (priv->map_section),
- 1, 1, 1, 1);
-+ gtk_box_pack_start (GTK_BOX (priv->clock_vbox),
-+ priv->map_section, FALSE, FALSE, 0);
-
- gtk_widget_show (priv->map_widget);
- gtk_widget_show (priv->map_section);
-@@ -927,7 +799,6 @@ create_cities_store (IntlClockUI *this)
-
- while (list) {
- IntlClockLocation *loc = INTLCLOCK_LOCATION (list->data);
-- gfloat latitude, longitude;
-
- gtk_list_store_append (priv->cities_store, &iter);
- gtk_list_store_set (priv->cities_store, &iter,
-@@ -953,12 +824,16 @@ intlclock_prefs_hide (GtkWidget *widget, IntlClockUI *this)
- IntlClockUIPrivate *priv = PRIVATE (this);
- GtkWidget *tree;
-
-+ intlclock_edit_hide (widget, this);
-+
- gtk_widget_hide (priv->prefs_window);
-
- tree = glade_xml_get_widget (priv->glade_xml, "cities_list");
-
- gtk_tree_selection_unselect_all
- (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)));
-+
-+ intlclock_ui_reset_timeout (this);
- }
-
- static gboolean
-@@ -974,8 +849,6 @@ intlclock_edit_clear (GtkWidget *widget, IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-
-- GtkWidget *edit_window = glade_xml_get_widget (priv->glade_xml, "edit-location-window");
--
- GtkWidget *zone_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-timezone-combo");
- GtkWidget *name_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-name-entry");
-
-@@ -1003,6 +876,8 @@ intlclock_edit_hide (GtkWidget *widget, IntlClockUI *this)
-
- GtkWidget *edit_window = glade_xml_get_widget (priv->glade_xml, "edit-location-window");
-
-+ intlclock_find_hide (widget, this);
-+
- gtk_widget_hide (edit_window);
-
- intlclock_edit_clear (widget, this);
-@@ -1016,6 +891,23 @@ intlclock_edit_hide_event (GtkWidget *widget, GdkEvent *event, IntlClockUI *this
- return TRUE;
- }
-
-+static void
-+intlclock_find_hide (GtkWidget *widget, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+
-+ GtkWidget *find_window = glade_xml_get_widget (priv->glade_xml, "find-location-window");
-+
-+ gtk_widget_hide (find_window);
-+}
-+
-+static gboolean
-+intlclock_find_hide_event (GtkWidget *widget, GdkEvent *event, IntlClockUI *this)
-+{
-+ intlclock_find_hide (widget, this);
-+
-+ return TRUE;
-+}
-
- static void
- set_12hr_format_radio_cb (GtkWidget *widget, IntlClockUI *this)
-@@ -1057,28 +949,6 @@ set_seconds_check_cb (GtkWidget *widget, IntlClockUI *this)
- }
-
- static void
--set_locations_check_cb (GtkWidget *widget, IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- panel_applet_gconf_set_bool (PANEL_APPLET (priv->panel_applet),
-- KEY_SHOW_LOCATIONS,
-- GTK_TOGGLE_BUTTON (widget)->active,
-- NULL);
--}
--
--static void
--set_map_check_cb (GtkWidget *widget, IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- panel_applet_gconf_set_bool (PANEL_APPLET (priv->panel_applet),
-- KEY_SHOW_MAP,
-- GTK_TOGGLE_BUTTON (widget)->active,
-- NULL);
--}
--
--static void
- fill_prefs_window (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-@@ -1087,6 +957,9 @@ fill_prefs_window (IntlClockUI *this)
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *col;
-
-+ time_t now_t;
-+ struct tm now;
-+
- /* Set the 12 hour / 24 hour widget */
- widget = glade_xml_get_widget (priv->glade_xml, "12hr_radio");
- g_signal_connect (widget, "toggled",
-@@ -1109,18 +982,6 @@ fill_prefs_window (IntlClockUI *this)
- g_signal_connect (widget, "toggled", G_CALLBACK (set_seconds_check_cb),
- this);
-
-- /* Set the "Show Locations" checkbox */
-- widget = glade_xml_get_widget (priv->glade_xml, "show_locations_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), priv->show_locations);
-- g_signal_connect (widget, "toggled", G_CALLBACK (set_locations_check_cb),
-- this);
--
-- /* Set the "Show Map" checkbox */
-- widget = glade_xml_get_widget (priv->glade_xml, "show_map_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), priv->show_map);
-- g_signal_connect (widget, "toggled", G_CALLBACK (set_map_check_cb),
-- this);
--
- /* Fill the Cities list */
- widget = glade_xml_get_widget (priv->glade_xml, "cities_list");
-
-@@ -1136,6 +997,15 @@ fill_prefs_window (IntlClockUI *this)
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
- GTK_TREE_MODEL (priv->cities_store));
-+
-+ /* Fill the time settings */
-+ tzset ();
-+ time (&now_t);
-+ localtime_r (&now_t, &now);
-+
-+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->seconds_spin), now.tm_sec);
-+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->minutes_spin), now.tm_min);
-+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->hours_spin), now.tm_hour);
- }
-
- static gint
-@@ -1150,19 +1020,334 @@ sort_zoneinfo_by_l10n_name (gconstpointer a, gconstpointer b)
- return strcmp (name_a, name_b);
- }
-
-+static void
-+intlclock_prefs_locations_changed (GtkTreeSelection *selection,
-+ IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ gint n;
-+
-+ n = gtk_tree_selection_count_selected_rows (selection);
-+ gtk_widget_set_sensitive (priv->prefs_location_edit_button, n > 0);
-+ gtk_widget_set_sensitive (priv->prefs_location_remove_button, n > 0);
-+}
-+
- static void
--display_prefs_window (IntlClockUI *this)
-+location_tree_selection_changed (GtkTreeSelection *selection,
-+ IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ GtkTreeModel *model;
-+ GtkTreeIter iter;
-+ WeatherLocation *loc = NULL;
-+ gboolean can_save = FALSE;
-+
-+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-+ gtk_tree_model_get (model, &iter, GWEATHER_XML_COL_POINTER, &loc, -1);
-+ if (loc != NULL)
-+ can_save = TRUE;
-+ }
-+
-+ gtk_widget_set_sensitive (priv->find_location_ok_button, can_save);
-+}
-+
-+static void
-+wrap_cb (GtkSpinButton *spin,
-+ IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ gdouble value;
-+ gdouble min, max;
-+ GtkSpinType direction;
-+
-+ value = gtk_spin_button_get_value (spin);
-+ gtk_spin_button_get_range (spin, &min, &max);
-+
-+ if (value == min)
-+ direction = GTK_SPIN_STEP_FORWARD;
-+ else
-+ direction = GTK_SPIN_STEP_BACKWARD;
-+
-+ if (spin == (GtkSpinButton *)priv->seconds_spin)
-+ gtk_spin_button_spin (GTK_SPIN_BUTTON (priv->minutes_spin),
-+ direction, 1.0);
-+ else if (spin == (GtkSpinButton *)priv->minutes_spin)
-+ gtk_spin_button_spin (GTK_SPIN_BUTTON (priv->hours_spin),
-+ direction, 1.0);
-+ else {
-+ guint year, month, day;
-+ GDate *date;
-+
-+ gtk_calendar_get_date (GTK_CALENDAR (priv->calendar),
-+ &year, &month, &day);
-+
-+ date = g_date_new_dmy (day, month + 1, year);
-+
-+ if (direction == GTK_SPIN_STEP_FORWARD)
-+ g_date_add_days (date, 1);
-+ else
-+ g_date_subtract_days (date, 1);
-+
-+ year = g_date_get_year (date);
-+ month = g_date_get_month (date) - 1;
-+ day = g_date_get_day (date);
-+
-+ gtk_calendar_select_month (GTK_CALENDAR (priv->calendar),
-+ month, year);
-+ gtk_calendar_select_day (GTK_CALENDAR (priv->calendar),
-+ day);
-+
-+ g_date_free (date);
-+ }
-+}
-+
-+static void
-+update_set_time_button (IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ gint can_set;
-+
-+ can_set = can_set_system_time ();
-+
-+ if (priv->time_settings_button)
-+ gtk_widget_set_sensitive (priv->time_settings_button, can_set != 0);
-+ if (priv->set_time_button)
-+ gtk_button_set_label (GTK_BUTTON (priv->set_time_button),
-+ can_set == 1 ?
-+ _("Set System Time...") :
-+ _("Set System Time"));
-+}
-+
-+static void
-+set_time_callback (IntlClockUI *this, GError *error)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ GtkWidget *window;
-+ GtkWidget *dialog;
-+
-+ if (error) {
-+ dialog = gtk_message_dialog_new (NULL,
-+ 0,
-+ GTK_MESSAGE_ERROR,
-+ GTK_BUTTONS_OK,
-+ _("Failed to set the system time"));
-+
-+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), error->message);
-+ g_signal_connect (dialog, "response",
-+ G_CALLBACK (gtk_widget_destroy), NULL);
-+ gtk_window_present (GTK_WINDOW (dialog));
-+
-+ g_error_free (error);
-+ }
-+ else
-+ update_set_time_button (this);
-+
-+ window = glade_xml_get_widget (priv->glade_xml, "set-time-window");
-+ gtk_widget_hide (window);
-+}
-+
-+static void
-+set_time (GtkWidget *widget, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ struct tm t;
-+ gint64 time;
-+ guint year, month, day;
-+
-+ t.tm_sec = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->seconds_spin));
-+ t.tm_min = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->minutes_spin));
-+ t.tm_hour = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (priv->hours_spin));
-+ gtk_calendar_get_date (GTK_CALENDAR (priv->calendar), &year, &month, &day);
-+ t.tm_year = year - 1900;
-+ t.tm_mon = month;
-+ t.tm_mday = day;
-+
-+ time = mktime (&t);
-+
-+ set_system_time_async (time, (GFunc)set_time_callback, this, NULL);
-+}
-+
-+static gboolean
-+find_location (GtkTreeModel *model,
-+ GtkTreeIter *iter,
-+ const gchar *location,
-+ gboolean go_parent)
-+{
-+ GtkTreeIter iter_child;
-+ GtkTreeIter iter_parent;
-+ gchar *aux_loc;
-+ gboolean valid;
-+ int len;
-+
-+ len = strlen (location);
-+
-+ if (len <= 0) {
-+ return FALSE;
-+ }
-+
-+ do {
-+ gtk_tree_model_get (model, iter, GWEATHER_XML_COL_LOC, &aux_loc, -1);
-+
-+ if (g_ascii_strncasecmp (aux_loc, location, len) == 0) {
-+ g_free (aux_loc);
-+ return TRUE;
-+ }
-+
-+ if (gtk_tree_model_iter_has_child (model, iter)) {
-+ gtk_tree_model_iter_nth_child (model, &iter_child, iter, 0);
-+ if (find_location (model, &iter_child, location, FALSE)) {
-+ /* Manual copying of the iter */
-+ iter->stamp = iter_child.stamp;
-+ iter->user_data = iter_child.user_data;
-+ iter->user_data2 = iter_child.user_data2;
-+ iter->user_data3 = iter_child.user_data3;
-+
-+ g_free (aux_loc);
-+
-+ return TRUE;
-+ }
-+ }
-+
-+ g_free (aux_loc);
-+
-+ valid = gtk_tree_model_iter_next (model, iter);
-+ } while (valid);
-+
-+ if (go_parent) {
-+ iter_parent = *iter;
-+ while (gtk_tree_model_iter_parent (model, iter, &iter_parent)) {
-+ if (gtk_tree_model_iter_next (model, iter))
-+ return find_location (model, iter, location, TRUE);
-+ iter_parent = *iter;
-+ }
-+ }
-+
-+ return FALSE;
-+}
-+
-+static void
-+find_next_location (GtkButton *button, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ GtkTreeView *tree;
-+ GtkTreeModel *model;
-+ GtkEntry *entry;
-+ GtkTreeSelection *selection;
-+ GtkTreeIter iter;
-+ GtkTreeIter iter_parent;
-+ GtkTreePath *path;
-+ const gchar *location;
-+
-+ tree = GTK_TREE_VIEW (priv->location_tree);
-+ model = gtk_tree_view_get_model (tree);
-+ entry = GTK_ENTRY (priv->find_location_entry);
-+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
-+
-+ if (gtk_tree_selection_count_selected_rows (selection) >= 1) {
-+ gtk_tree_selection_get_selected (selection, &model, &iter);
-+ /* Select next or select parent */
-+ if (!gtk_tree_model_iter_next (model, &iter)) {
-+ iter_parent = iter;
-+ if (!gtk_tree_model_iter_parent (model, &iter, &iter_parent) ||
-+ !gtk_tree_model_iter_next (model, &iter))
-+ gtk_tree_model_get_iter_first (model, &iter);
-+ }
-+ }
-+ else {
-+ gtk_tree_model_get_iter_first (model, &iter);
-+ }
-+ location = gtk_entry_get_text (entry);
-+
-+ if (find_location (model, &iter, location, TRUE)) {
-+ gtk_widget_set_sensitive (priv->find_next_location_button, TRUE);
-+ path = gtk_tree_model_get_path (model, &iter);
-+ gtk_tree_view_expand_to_path (tree, path);
-+ gtk_tree_selection_select_path (selection, path);
-+ gtk_tree_view_scroll_to_cell (tree, path, NULL, TRUE, 0.5, 0);
-+
-+ gtk_tree_path_free (path);
-+ }
-+ else {
-+ gtk_widget_set_sensitive (priv->find_next_location_button, FALSE);
-+ }
-+}
-+
-+static void
-+find_entry_changed (GtkEditable *entry, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ GtkTreeView *tree;
-+ GtkTreeModel *model;
-+ GtkTreeSelection *selection;
-+ GtkTreeIter iter;
-+ GtkTreePath *path;
-+ const gchar *location;
-+
-+ tree = GTK_TREE_VIEW (priv->location_tree);
-+ model = gtk_tree_view_get_model (tree);
-+
-+ selection = gtk_tree_view_get_selection (tree);
-+ gtk_tree_model_get_iter_first (model, &iter);
-+
-+ location = gtk_entry_get_text (GTK_ENTRY (entry));
-+ if (find_location (model, &iter, location, TRUE)) {
-+ gtk_widget_set_sensitive (priv->find_next_location_button, TRUE);
-+ path = gtk_tree_model_get_path (model, &iter);
-+ gtk_tree_view_expand_to_path (tree, path);
-+ gtk_tree_selection_select_iter (selection, &iter);
-+ gtk_tree_view_scroll_to_cell (tree, path, NULL, TRUE, 0.5, 0);
-+ gtk_tree_path_free (path);
-+ }
-+ else {
-+ gtk_widget_set_sensitive (priv->find_next_location_button, FALSE);
-+ }
-+}
-+
-+static void
-+cancel_time_settings (GtkWidget *button, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+
-+ gtk_widget_hide (priv->set_time_window);
-+
-+ intlclock_ui_reset_timeout (this);
-+}
-+
-+static void
-+run_time_settings (GtkWidget *button, IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (this);
-+ GtkWidget *cancel_set_time_button;
-+
-+ if (!priv->set_time_button) {
-+ priv->set_time_button = glade_xml_get_widget (priv->glade_xml, "set-time-button");
-+ g_signal_connect (priv->set_time_button, "clicked", G_CALLBACK (set_time), this);
-+
-+ cancel_set_time_button = glade_xml_get_widget (priv->glade_xml, "cancel-set-time-button");
-+ g_signal_connect (cancel_set_time_button, "clicked", G_CALLBACK (cancel_time_settings), this);
-+
-+ priv->current_time_label = glade_xml_get_widget (priv->glade_xml, "current_time_label");
-+ }
-+
-+ priv->set_time_window = glade_xml_get_widget (priv->glade_xml, "set-time-window");
-+ gtk_window_present (GTK_WINDOW (priv->set_time_window));
-+
-+ intlclock_ui_reset_timeout (this);
-+}
-+
-+static void
-+display_prefs_window (IntlClockUI *this, gboolean locations)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
- GtkWidget *edit_window;
-- GtkWidget *prefs_window;
- GtkWidget *prefs_close_button;
-- GtkWidget *prefs_settings_button;
- GtkWidget *edit_cancel_button;
- GtkWidget *edit_ok_button;
- GtkWidget *zone_combo;
--
-- GtkWidget *tmp_button;
-+ GtkWidget *find_window;
-+ GtkWidget *find_location_button;
-+ GtkWidget *find_location_cancel_button;
-+ GtkTreeSelection *selection;
-
- if (!priv->prefs_window) {
- priv->prefs_window =
-@@ -1170,43 +1355,42 @@ display_prefs_window (IntlClockUI *this)
-
- prefs_close_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-close-button");
--
-- prefs_settings_button =
-- glade_xml_get_widget (priv->glade_xml, "prefs-time-settings-button");
--
- priv->prefs_locations =
- GTK_TREE_VIEW (glade_xml_get_widget (priv->glade_xml, "cities_list"));
-
-+ selection = gtk_tree_view_get_selection (priv->prefs_locations);
-+ g_signal_connect (G_OBJECT (selection), "changed",
-+ G_CALLBACK (intlclock_prefs_locations_changed), this);
-+
- g_signal_connect (G_OBJECT (priv->prefs_window), "delete_event",
- G_CALLBACK (intlclock_prefs_hide_event), this);
-
- g_signal_connect (G_OBJECT (prefs_close_button), "clicked",
- G_CALLBACK (intlclock_prefs_hide), this);
-
-- g_signal_connect (G_OBJECT (prefs_settings_button), "clicked",
-- G_CALLBACK (run_time_configuration_cb), this);
--
-- tmp_button =
-+ priv->prefs_location_remove_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-locations-remove-button");
-
-- g_signal_connect (G_OBJECT (tmp_button), "clicked",
-+ g_signal_connect (G_OBJECT (priv->prefs_location_remove_button), "clicked",
- G_CALLBACK (run_prefs_locations_remove), this);
--
-- tmp_button =
-+
-+ priv->prefs_location_add_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-locations-add-button");
-
-- g_signal_connect (G_OBJECT (tmp_button), "clicked",
-+ g_signal_connect (G_OBJECT (priv->prefs_location_add_button), "clicked",
- G_CALLBACK (run_prefs_locations_add), this);
-
-- tmp_button =
-+ priv->prefs_location_edit_button =
- glade_xml_get_widget (priv->glade_xml, "prefs-locations-edit-button");
-
-- g_signal_connect (G_OBJECT (tmp_button), "clicked",
-+ g_signal_connect (G_OBJECT (priv->prefs_location_edit_button), "clicked",
- G_CALLBACK (run_prefs_locations_edit), this);
-
- edit_window = glade_xml_get_widget (priv->glade_xml,
- "edit-location-window");
-
-+ gtk_window_set_transient_for (GTK_WINDOW (edit_window),
-+ GTK_WINDOW (priv->prefs_window));
-
- g_signal_connect (G_OBJECT (edit_window), "delete_event",
- G_CALLBACK (intlclock_edit_hide_event), this);
-@@ -1219,7 +1403,35 @@ display_prefs_window (IntlClockUI *this)
-
- zone_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-timezone-combo");
-
-- g_signal_connect (G_OBJECT (zone_combo), "changed",
-+ find_window = glade_xml_get_widget (priv->glade_xml,
-+ "find-location-window");
-+
-+ gtk_window_set_transient_for (GTK_WINDOW (find_window),
-+ GTK_WINDOW (edit_window));
-+
-+ g_signal_connect (G_OBJECT (find_window), "delete_event",
-+ G_CALLBACK (intlclock_find_hide_event), this);
-+
-+ find_location_button =
-+ glade_xml_get_widget (priv->glade_xml, "find-location-button");
-+
-+ priv->find_location_ok_button =
-+ glade_xml_get_widget (priv->glade_xml, "find-location-ok-button");
-+
-+ find_location_cancel_button =
-+ glade_xml_get_widget (priv->glade_xml, "find-location-cancel-button");
-+
-+ priv->find_next_location_button =
-+ glade_xml_get_widget (priv->glade_xml, "find-next-location-button");
-+
-+ priv->find_location_entry =
-+ glade_xml_get_widget (priv->glade_xml, "find-location-entry");
-+
-+ priv->location_tree =
-+ glade_xml_get_widget (priv->glade_xml, "find-location-tree");
-+
-+ priv->zone_combo_changed =
-+ g_signal_connect (G_OBJECT (zone_combo), "changed",
- G_CALLBACK (zone_combo_changed), this);
-
-
-@@ -1229,16 +1441,72 @@ display_prefs_window (IntlClockUI *this)
- g_signal_connect (G_OBJECT (edit_ok_button), "clicked",
- G_CALLBACK (run_prefs_edit_save), this);
-
-+ g_signal_connect (find_location_button, "clicked",
-+ G_CALLBACK (run_find_location), this);
-+
-+ g_signal_connect (G_OBJECT (find_location_cancel_button), "clicked",
-+ G_CALLBACK (intlclock_find_hide), this);
-+
-+ g_signal_connect (G_OBJECT (priv->find_location_ok_button), "clicked",
-+ G_CALLBACK (run_find_location_save), this);
-+
-+ g_signal_connect (G_OBJECT (priv->find_next_location_button), "clicked",
-+ G_CALLBACK (find_next_location), this);
-+
-+ g_signal_connect (G_OBJECT (priv->find_location_entry), "changed",
-+ G_CALLBACK (find_entry_changed), this);
-+
-+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->location_tree));
-+ g_signal_connect (selection, "changed",
-+ G_CALLBACK (location_tree_selection_changed), this);
-+
- /* We have to put an item in the combo box in the glade file
- to get the simpler, string-only store. Here we remove that
- item. */
- gtk_combo_box_remove_text (GTK_COMBO_BOX (zone_combo), 0);
-
-+ /* Set up the time setting section */
-+
-+ priv->time_settings_button = glade_xml_get_widget (priv->glade_xml, "time-settings-button");
-+ g_signal_connect (priv->time_settings_button, "clicked", G_CALLBACK (run_time_settings), this);
-+
-+ priv->calendar = glade_xml_get_widget (priv->glade_xml, "calendar");
-+ priv->hours_spin = glade_xml_get_widget (priv->glade_xml, "hours_spin");
-+ priv->minutes_spin = glade_xml_get_widget (priv->glade_xml, "minutes_spin");
-+ priv->seconds_spin = glade_xml_get_widget (priv->glade_xml, "seconds_spin");
-+
-+ gtk_entry_set_width_chars (GTK_ENTRY (priv->hours_spin), 2);
-+ gtk_entry_set_width_chars (GTK_ENTRY (priv->minutes_spin), 2);
-+ gtk_entry_set_width_chars (GTK_ENTRY (priv->seconds_spin), 2);
-+
-+ gtk_entry_set_alignment (GTK_ENTRY (priv->hours_spin), 1.0);
-+ gtk_entry_set_alignment (GTK_ENTRY (priv->minutes_spin), 1.0);
-+ gtk_entry_set_alignment (GTK_ENTRY (priv->seconds_spin), 1.0);
-+ g_signal_connect (priv->seconds_spin, "wrapped", G_CALLBACK (wrap_cb), this);
-+ g_signal_connect (priv->minutes_spin, "wrapped", G_CALLBACK (wrap_cb), this);
-+ g_signal_connect (priv->hours_spin, "wrapped", G_CALLBACK (wrap_cb), this);
-+
- /* fill it with the current preferences */
- fill_prefs_window (this);
- }
-
-+ if (locations) {
-+ GtkWidget *notebook =
-+ glade_xml_get_widget (priv->glade_xml, "notebook");
-+ gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1);
-+ }
-+
-+ update_set_time_button (this);
-+
- gtk_window_present (GTK_WINDOW (priv->prefs_window));
-+
-+ intlclock_ui_reset_timeout (this);
-+}
-+
-+void
-+intlclock_ui_edit_locations (IntlClockUI *ui)
-+{
-+ display_prefs_window (ui, TRUE);
- }
-
- static void
-@@ -1306,16 +1574,11 @@ intlclock_ui_new (IntlClock *clock, PanelApplet *applet)
- create_events_window (this);
- create_clock_window (this);
- create_cities_store (this);
--
-- if (priv->show_locations) {
-- create_cities_section (this);
-- }
--
-- if (priv->show_map) {
-- create_map_section (this);
-- intlclock_map_refresh (INTLCLOCK_MAP (priv->map_widget));
-- }
--
-+ create_cities_section (this);
-+ create_map_section (this);
-+
-+ intlclock_map_refresh (INTLCLOCK_MAP (priv->map_widget));
-+
- intlclock_ui_reset_timeout (this);
-
- return this;
-@@ -1365,9 +1628,6 @@ intlclock_ui_init (IntlClockUI *this)
-
- priv->cities_store = NULL;
-
-- priv->show_locations = TRUE;
-- priv->show_map = TRUE;
--
- priv->prefs_window = NULL;
-
- priv->format_12hr = TRUE;
-@@ -1547,56 +1807,6 @@ gconf_show_week_changed (GConfClient *client,
- }
-
- static void
--gconf_show_locations_changed (GConfClient *client,
-- guint cnxn_id,
-- GConfEntry *entry,
-- IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
-- GtkWidget *widget;
--
-- gboolean value;
--
-- if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-- return;
--
-- value = gconf_value_get_bool (entry->value);
--
-- priv->show_locations = (value != 0);
--
-- widget = glade_xml_get_widget (priv->glade_xml, "show_locations_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
-- priv->show_locations);
--
-- create_cities_section (this);
--}
--
--static void
--gconf_show_map_changed (GConfClient *client,
-- guint cnxn_id,
-- GConfEntry *entry,
-- IntlClockUI *this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
-- GtkWidget *widget;
--
-- gboolean value;
--
-- if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
-- return;
--
-- value = gconf_value_get_bool (entry->value);
--
-- priv->show_map = (value != 0);
--
-- widget = glade_xml_get_widget (priv->glade_xml, "show_map_check");
-- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
-- priv->show_map);
--
-- create_map_section (this);
--}
--
--static void
- location_start_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
-@@ -1614,6 +1824,7 @@ location_start_element (GMarkupParseContext *context,
- gchar *timezone = NULL;
- gfloat latitude = 0.0;
- gfloat longitude = 0.0;
-+ gchar *code = NULL;
-
- int index = 0;
-
-@@ -1633,6 +1844,8 @@ location_start_element (GMarkupParseContext *context,
- sscanf (attribute_values[index], "%f", &latitude);
- } else if (strcmp (att_name, "longitude") == 0) {
- sscanf (attribute_values[index], "%f", &longitude);
-+ } else if (strcmp (att_name, "code") == 0) {
-+ code = (gchar *)attribute_values[index];
- }
- }
-
-@@ -1642,7 +1855,7 @@ location_start_element (GMarkupParseContext *context,
- return;
- }
-
-- loc = intlclock_location_new (name, timezone, latitude, longitude);
-+ loc = intlclock_location_new (name, timezone, latitude, longitude, code);
-
- *(GList **)user_data = g_list_append (ret, loc);
- }
-@@ -1713,10 +1926,11 @@ gconf_loc_to_string (IntlClockLocation *loc)
- prev_locale = setlocale (LC_NUMERIC, "POSIX");
-
- ret = g_markup_printf_escaped
-- ("<location name=\"%s\" timezone=\"%s\" latitude=\"%f\" longitude=\"%f\" />",
-+ ("<location name=\"%s\" timezone=\"%s\" latitude=\"%f\" longitude=\"%f\" code=\"%s\"/>",
- intlclock_location_get_name (loc),
- intlclock_location_get_timezone (loc),
-- latitude, longitude);
-+ latitude, longitude,
-+ intlclock_location_get_weather_code (loc));
-
- setlocale (LC_NUMERIC, "");
-
-@@ -1727,7 +1941,7 @@ static void
- intlclock_ui_save_cities_store (IntlClockUI *this)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-- IntlClockLocation *loc, *cur;
-+ IntlClockLocation *loc;
- GList *node = intlclock_get_locations (priv->clock);
-
- GSList *root = NULL;
-@@ -1803,24 +2017,6 @@ setup_gconf (IntlClockUI *this)
- g_free (key);
-
- key = panel_applet_gconf_get_full_key
-- (PANEL_APPLET (priv->panel_applet), KEY_SHOW_LOCATIONS);
-- priv->listeners [index++] =
-- gconf_client_notify_add (
-- client, key,
-- (GConfClientNotifyFunc) gconf_show_locations_changed,
-- this, NULL, NULL);
-- g_free (key);
--
-- key = panel_applet_gconf_get_full_key
-- (PANEL_APPLET (priv->panel_applet), KEY_SHOW_MAP);
-- priv->listeners [index++] =
-- gconf_client_notify_add (
-- client, key,
-- (GConfClientNotifyFunc) gconf_show_map_changed,
-- this, NULL, NULL);
-- g_free (key);
--
-- key = panel_applet_gconf_get_full_key
- (PANEL_APPLET (priv->panel_applet), KEY_CITIES);
- priv->listeners [index++] =
- gconf_client_notify_add (
-@@ -1868,14 +2064,6 @@ load_gconf_settings (IntlClockUI *this)
- panel_applet_gconf_get_bool (priv->panel_applet,
- KEY_SHOW_WEEK, NULL);
-
-- priv->show_locations =
-- panel_applet_gconf_get_bool (priv->panel_applet,
-- KEY_SHOW_LOCATIONS, NULL);
--
-- priv->show_map =
-- panel_applet_gconf_get_bool (priv->panel_applet,
-- KEY_SHOW_MAP, NULL);
--
- values = panel_applet_gconf_get_list (priv->panel_applet, KEY_CITIES,
- GCONF_VALUE_STRING, NULL);
-
-@@ -1892,92 +2080,72 @@ static void bonobo_display_properties_dialog (BonoboUIComponent *uic,
- IntlClockUI *this,
- const gchar *verbname)
- {
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- display_prefs_window (this);
-+ display_prefs_window (this, FALSE);
- }
-
--static void bonobo_run_time_configuration (BonoboUIComponent *uic,
-- IntlClockUI *this,
-- const gchar *verbname)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- run_time_configuration (this);
--}
--
--static void display_prefs_window_cb (GtkButton *button, gpointer this)
-+static void
-+copy_time (BonoboUIComponent *uic,
-+ IntlClockUI *this,
-+ const gchar *verbname)
- {
- IntlClockUIPrivate *priv = PRIVATE (this);
-+ gchar *utf8;
-+ time_t now_t;
-+ struct tm now;
-
-- display_prefs_window (this);
--}
-+ tzset ();
-+ time (&now_t);
-+ localtime_r (&now_t, &now);
-
--static void
--run_time_configuration_cb (GtkButton *button, gpointer this)
--{
-- IntlClockUIPrivate *priv = PRIVATE (this);
-+ utf8 = intlclock_format_time (priv->clock, &now, FALSE,
-+ priv->format_12hr,
-+ priv->format_show_seconds,
-+ FALSE, FALSE, NULL, FALSE);
-+
-+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
-+ utf8, -1);
-+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
-+ utf8, -1);
-
-- run_time_configuration (this);
-+ g_free (utf8);
- }
-
- static void
--run_time_configuration (IntlClockUI *this)
-+copy_date (BonoboUIComponent *uic,
-+ IntlClockUI *this,
-+ const gchar *verbname)
- {
-- IntlClockUIPrivate *priv = PRIVATE (this);
--
-- GtkWidget *dialog;
-- GError *err;
-- char **argv;
-- char *path;
-+ char string[256];
-+ char *utf8, *loc;
-
-- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (priv->events_window));
-- gchar *tool = "/opt/gnome/bin/gnomesu /sbin/yast2 timezone";
--
-- if (!tool || tool[0] == '\0')
-- return;
--
-- if (!g_shell_parse_argv (tool, NULL, &argv, NULL))
-- return;
--
-- if (!(path = g_find_program_in_path (argv [0]))) {
-- g_strfreev (argv);
-- return;
-- }
--
-- g_free (path);
--
-- err = NULL;
-- if (gdk_spawn_on_screen (screen,
-- NULL,
-- argv,
-- NULL,
-- G_SPAWN_SEARCH_PATH,
-- NULL,
-- NULL,
-- NULL,
-- &err)) {
-- g_strfreev (argv);
-- return;
-- }
--
-- g_strfreev (argv);
-+ time_t now_t;
-+ struct tm now;
-
-- dialog = gtk_message_dialog_new (NULL,
-- GTK_DIALOG_DESTROY_WITH_PARENT,
-- GTK_MESSAGE_ERROR,
-- GTK_BUTTONS_OK,
-- _("Failed to launch time configuration tool: %s"),
-- err->message);
-- g_error_free (err);
-+ tzset ();
-+ time (&now_t);
-+ localtime_r (&now_t, &now);
-
-- g_signal_connect (dialog, "response",
-- G_CALLBACK (gtk_widget_destroy), NULL);
-+ loc = g_locale_from_utf8 (_("%A, %B %d %Y"), -1, NULL, NULL, NULL);
-+ if (!loc)
-+ strcpy (string, "???");
-+ else if (strftime (string, sizeof (string), loc, &now) <= 0)
-+ strcpy (string, "???");
-+ g_free (loc);
-
-- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-- gtk_window_set_screen (GTK_WINDOW (dialog), screen);
-+ utf8 = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
-+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
-+ utf8, -1);
-+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
-+ utf8, -1);
-+ g_free (utf8);
-+}
-
-- gtk_widget_show_all (dialog);
-+static void
-+config_date (BonoboUIComponent *uic,
-+ IntlClockUI *this,
-+ const char *verbname)
-+{
-+ run_time_settings (NULL, this);
- }
-
- static void
-@@ -2000,6 +2168,46 @@ remove_tree_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
- }
-
- static void
-+update_coords (IntlClockUI *this, gboolean valid, gfloat lat, gfloat lon)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-+ GtkWidget *lat_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-latitude-entry");
-+ GtkWidget *lon_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-longitude-entry");
-+ GtkWidget *lat_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-latitude-combo");
-+ GtkWidget *lon_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-longitude-combo");
-+ gchar *tmp;
-+
-+ if (!valid) {
-+ gtk_entry_set_text (GTK_ENTRY (lat_entry), "");
-+ gtk_entry_set_text (GTK_ENTRY (lon_entry), "");
-+ gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), -1);
-+ gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), -1);
-+
-+ return;
-+ }
-+
-+ tmp = g_strdup_printf ("%f", fabsf(lat));
-+ gtk_entry_set_text (GTK_ENTRY (lat_entry), tmp);
-+ g_free (tmp);
-+
-+ if (lat > 0) {
-+ gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), 0);
-+ } else {
-+ gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), 1);
-+ }
-+
-+ tmp = g_strdup_printf ("%f", fabsf(lon));
-+ gtk_entry_set_text (GTK_ENTRY (lon_entry), tmp);
-+ g_free (tmp);
-+
-+ if (lon > 0) {
-+ gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), 0);
-+ } else {
-+ gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), 1);
-+ }
-+}
-+
-+static void
- zone_combo_changed (GtkComboBox *widget, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-@@ -2009,17 +2217,12 @@ zone_combo_changed (GtkComboBox *widget, gpointer this)
- gchar *city = NULL;
- gfloat lat = 0;
- gfloat lon = 0;
-- gchar *tmp;
-+ GtkTreeModel *model;
-+ gchar *name;
-
- GtkWidget *name_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-name-entry");
--
-- GtkWidget *lat_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-latitude-entry");
--
-- GtkWidget *lon_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-longitude-entry");
--
-- GtkWidget *lat_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-latitude-combo");
--
-- GtkWidget *lon_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-longitude-combo");
-+ GtkWidget *edit_window = glade_xml_get_widget (priv->glade_xml, "edit-location-window");
-+ gchar *weather_code;
-
- IntlClockCountry *country;
- IntlClockZoneInfo *info;
-@@ -2028,6 +2231,14 @@ zone_combo_changed (GtkComboBox *widget, gpointer this)
- return;
- }
-
-+ /* only fill in other field if name is not set yet, to
-+ * allow correcting a guessed timezone
-+ */
-+ name = gtk_entry_get_text (name_entry);
-+ if (name && name[0]) {
-+ return;
-+ }
-+
- info = intlclock_zonetable_get_l10n_zone (zones, timezone);
- g_free (timezone);
-
-@@ -2049,26 +2260,13 @@ zone_combo_changed (GtkComboBox *widget, gpointer this)
- g_free (city);
-
- intlclock_zoneinfo_get_coords (info, &lat, &lon);
-+ update_coords (this, TRUE, lat, lon);
-
-- tmp = g_strdup_printf ("%f", fabsf(lat));
-- gtk_entry_set_text (GTK_ENTRY (lat_entry), tmp);
-- g_free (tmp);
--
-- if (lat > 0) {
-- gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), 0);
-- } else {
-- gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), 1);
-- }
--
-- tmp = g_strdup_printf ("%f", fabsf(lon));
-- gtk_entry_set_text (GTK_ENTRY (lon_entry), tmp);
-- g_free (tmp);
--
-- if (lon > 0) {
-- gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), 0);
-- } else {
-- gtk_combo_box_set_active (GTK_COMBO_BOX (lon_combo), 1);
-- }
-+ fill_location_tree (this);
-+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->location_tree));
-+ weather_code = find_weather_code (model, city, lat * M_PI/180.0, lon * M_PI/180.0);
-+ g_object_set_data_full (G_OBJECT (edit_window), "weather-code",
-+ weather_code, g_free);
- }
-
- static void
-@@ -2144,12 +2342,8 @@ edit_tree_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-
- IntlClockLocation *loc;
-- int i;
-- int timezone_idx = -1;
- gchar *tmp;
- gfloat lat, lon;
-- GList *list;
-- GList *cur;
-
- /* fill the dialog with this location's data, show it */
- GtkWidget *edit_window = glade_xml_get_widget (priv->glade_xml, "edit-location-window");
-@@ -2205,13 +2399,165 @@ static void
- run_prefs_locations_remove (GtkButton *button, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-- GtkTreeModel *model = gtk_tree_view_get_model (priv->prefs_locations);;
- GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->prefs_locations));
-
- gtk_tree_selection_selected_foreach (sel, remove_tree_row, this);
- }
-
- static void
-+run_find_location (GtkButton *button, gpointer this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-+
-+ GtkWidget *window = glade_xml_get_widget (priv->glade_xml, "find-location-window");
-+
-+ gtk_tree_view_collapse_all (priv->location_tree);
-+ gtk_widget_grab_focus (priv->find_location_entry);
-+ gtk_window_present (GTK_WINDOW (window));
-+}
-+
-+static gdouble
-+distance (gdouble lat1, gdouble lon1,
-+ gdouble lat2, gdouble lon2)
-+{
-+ gdouble radius = 6372.795;
-+
-+ return acos (cos (lat1) * cos (lat2) * cos (lon1 - lon2) + sin (lat1) * sin (lat2)) * radius;
-+}
-+
-+static gchar *
-+find_timezone (IntlClockUI *this,
-+ const char *name,
-+ gfloat lat,
-+ gfloat lon)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-+ IntlClockZoneTable *zonetab = intlclock_get_zonetable (priv->clock);
-+ GList *zones, *l;
-+ double dist, d;
-+ gfloat zlat, zlon;
-+ IntlClockZoneInfo *best;
-+
-+ g_print ("find zone for %s (%f %f)\n", name, lat, lon);
-+ dist = 1e6;
-+ best = NULL;
-+ zones = intlclock_zonetable_get_zones (zonetab);
-+ for (l = zones; l; l = l->next) {
-+ IntlClockZoneInfo *info = l->data;
-+ intlclock_zoneinfo_get_coords (info, &zlat, &zlon);
-+
-+ d = distance (lat, lon, zlat*M_PI/180.0, zlon*M_PI/180.0);
-+
-+ if (d < dist) {
-+ best = info;
-+ dist = d;
-+ }
-+ }
-+
-+ intlclock_zoneinfo_get_coords (best, &zlat, &zlon);
-+ g_print ("best: %s (%f, %f), distance: %f\n",
-+ intlclock_zoneinfo_get_name (best), zlat, zlon, dist);
-+
-+ return g_strdup (intlclock_zoneinfo_get_name (best));
-+}
-+
-+static void
-+update_timezone (IntlClockUI *this,
-+ const char *name,
-+ gfloat lat,
-+ gfloat lon)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-+ GtkWidget *zone_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-timezone-combo");
-+ GtkTreeModel *model;
-+ gchar *timezone;
-+ IntlClockLocation *loc;
-+
-+ timezone = find_timezone (this, name, lat, lon);
-+ loc = intlclock_location_new (name, timezone, lat*180.0/M_PI, lon*180.0/M_PI, NULL);
-+
-+ g_signal_handler_block (zone_combo, priv->zone_combo_changed);
-+
-+ fill_timezone_combo_from_location (this, zone_combo, loc);
-+
-+ g_signal_handler_unblock (zone_combo, priv->zone_combo_changed);
-+
-+ g_object_unref (loc);
-+ g_free (timezone);
-+}
-+
-+static void
-+run_find_location_save (GtkButton *button, gpointer this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-+ GtkTreeSelection *selection;
-+ GtkTreeModel *model;
-+ GtkTreeIter iter;
-+ WeatherLocation *loc = NULL;
-+ GtkWidget *name_entry;
-+ GtkWidget *edit_window;
-+
-+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->location_tree));
-+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
-+ return;
-+
-+ gtk_tree_model_get (model, &iter, GWEATHER_XML_COL_POINTER, &loc, -1);
-+
-+ if (!loc)
-+ return;
-+
-+ edit_window = glade_xml_get_widget (priv->glade_xml, "edit-location-window");
-+ name_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-name-entry");
-+ gtk_entry_set_text (GTK_ENTRY (name_entry), loc->name);
-+ g_object_set_data_full (G_OBJECT (edit_window), "weather-code",
-+ g_strdup (loc->code), g_free);
-+
-+ update_coords (this, loc->latlon_valid, loc->latitude*180.0/M_PI, loc->longitude*180.0/M_PI);
-+
-+ update_timezone (this, loc->name, loc->latitude, loc->longitude);
-+
-+ intlclock_find_hide (button, this);
-+}
-+
-+static void
-+location_row_activated (GtkTreeView *tree_view,
-+ GtkTreePath *path,
-+ GtkTreeViewColumn *column,
-+ IntlClockUI *this)
-+{
-+ run_find_location_save (tree_view, this);
-+}
-+
-+static void
-+fill_location_tree (IntlClockUI *this)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-+ GtkTreeView *tree;
-+ GtkTreeModel *model;
-+ GtkTreeViewColumn *column;
-+ GtkCellRenderer *cell;
-+
-+ tree = (GtkTreeView*)priv->location_tree;
-+
-+ if (gtk_tree_view_get_model (tree) != NULL)
-+ return;
-+
-+ model = (GtkTreeModel*)gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
-+ gtk_tree_view_set_model (tree, model);
-+
-+ cell = gtk_cell_renderer_text_new ();
-+ column = gtk_tree_view_column_new_with_attributes ("not used", cell,
-+ "text", GWEATHER_XML_COL_LOC, NULL);
-+ gtk_tree_view_append_column (tree, column);
-+ gtk_tree_view_set_expander_column (tree, column);
-+
-+ g_signal_connect (tree, "row-activated",
-+ G_CALLBACK (location_row_activated), this);
-+
-+ gweather_xml_load_locations (tree, NULL);
-+}
-+
-+static void
- run_prefs_locations_add (GtkButton *button, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-@@ -2220,7 +2566,8 @@ run_prefs_locations_add (GtkButton *button, gpointer this)
- GtkWidget *zone_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-timezone-combo");
-
- fill_timezone_combo_from_location (this, zone_combo, NULL);
--
-+ fill_location_tree (this);
-+
- g_object_set_data (G_OBJECT (edit_window), "intlclock-location", NULL);
- gtk_window_present (GTK_WINDOW (edit_window));
- }
-@@ -2230,7 +2577,6 @@ run_prefs_locations_edit (GtkButton *button, gpointer this)
- {
- IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (this));
-
-- GtkTreeModel *model = gtk_tree_view_get_model (priv->prefs_locations);;
- GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->prefs_locations));
-
- gtk_tree_selection_selected_foreach (sel, edit_tree_row, this);
-@@ -2245,7 +2591,6 @@ run_prefs_edit_save (GtkButton *button, gpointer this)
- IntlClockZoneTable *zones = intlclock_get_zonetable (priv->clock);
-
- IntlClockLocation *loc = g_object_get_data (G_OBJECT (edit_window), "intlclock-location");
--
- GtkWidget *zone_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-timezone-combo");
- GtkWidget *name_entry = glade_xml_get_widget (priv->glade_xml, "edit-location-name-entry");
-
-@@ -2255,6 +2600,8 @@ run_prefs_edit_save (GtkButton *button, gpointer this)
- GtkWidget *lon_combo = glade_xml_get_widget (priv->glade_xml, "edit-location-longitude-combo");
-
- gchar *timezone_l10n = gtk_combo_box_get_active_text (GTK_COMBO_BOX (zone_combo));
-+ gchar *weather_code = g_object_get_data (G_OBJECT (edit_window), "weather-code");
-+
- IntlClockZoneInfo *info = intlclock_zonetable_get_l10n_zone (zones, timezone_l10n);
-
- if (!info) {
-@@ -2281,9 +2628,11 @@ run_prefs_edit_save (GtkButton *button, gpointer this)
- intlclock_location_set_timezone (loc, intlclock_zoneinfo_get_name (info));
- intlclock_location_set_name (loc, name);
- intlclock_location_set_coords (loc, lat, lon);
-+ intlclock_location_set_weather_code (loc, weather_code);
- } else {
- GList *locs;
-- loc = intlclock_location_new (name, intlclock_zoneinfo_get_name (info), lat, lon);
-+
-+ loc = intlclock_location_new (name, intlclock_zoneinfo_get_name (info), lat, lon, weather_code);
-
- locs = g_list_copy (intlclock_get_locations (priv->clock));
- locs = g_list_append (locs, loc);
-@@ -2294,3 +2643,11 @@ run_prefs_edit_save (GtkButton *button, gpointer this)
-
- intlclock_edit_hide (edit_window, this);
- }
-+
-+void
-+intlclock_ui_update_weather_icon (IntlClockUI *ui, GdkPixbuf *pixbuf)
-+{
-+ IntlClockUIPrivate *priv = PRIVATE (INTLCLOCK_UI (ui));
-+
-+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->panel_weather_icon), pixbuf);
-+}
-diff --git a/src/intlclock-ui.h b/src/intlclock-ui.h
-index ecbee03..a10099a 100644
---- a/src/intlclock-ui.h
-+++ b/src/intlclock-ui.h
-@@ -29,6 +29,8 @@ GType intlclock_ui_get_type (void);
-
- IntlClockUI *intlclock_ui_new (IntlClock *clock, PanelApplet *applet);
- gboolean intlclock_ui_is_12hr (IntlClockUI *ui);
-+void intlclock_ui_edit_locations (IntlClockUI *ui);
-+void intlclock_ui_update_weather_icon (IntlClockUI *ui, GdkPixbuf *pixbuf);
-
- G_END_DECLS
- #endif /* __INTLCLOCK_UI_H__ */
-diff --git a/src/intlclock-zonetable.c b/src/intlclock-zonetable.c
-index a2a0b6f..e6e27cb 100644
---- a/src/intlclock-zonetable.c
-+++ b/src/intlclock-zonetable.c
-@@ -27,8 +27,6 @@ typedef struct {
- GHashTable *country_table;
- } IntlClockZoneTablePrivate;
-
--#define USE_CRIPPLED_ZONELIST 1
--
- /* Seeded with the list from Nat's Blackberry */
- char *available_zones[] = {
- /* Eniwetok (-12) */
-diff --git a/src/intlclock.c b/src/intlclock.c
-index 02f5b0a..552c45c 100644
---- a/src/intlclock.c
-+++ b/src/intlclock.c
-@@ -32,6 +32,8 @@ typedef struct {
- enum {
- TICK,
- LOCATIONS_CHANGED,
-+ BLINK_LOCATION,
-+ CURRENT_TIMEZONE_CHANGED,
- LAST_SIGNAL
- };
-
-@@ -87,7 +89,25 @@ intlclock_class_init (IntlClockClass *this_class)
- _intlclock_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
-- g_type_class_add_private (this_class, sizeof (IntlClockPrivate));
-+ intlclock_signals[BLINK_LOCATION] = g_signal_new
-+ ("blink-location",
-+ G_OBJECT_CLASS_TYPE (obj_class),
-+ G_SIGNAL_RUN_FIRST,
-+ G_STRUCT_OFFSET (IntlClockClass, blink_location),
-+ NULL, NULL,
-+ _intlclock_marshal_VOID__OBJECT,
-+ G_TYPE_NONE, 1, INTLCLOCK_LOCATION_TYPE);
-+
-+ intlclock_signals[CURRENT_TIMEZONE_CHANGED] = g_signal_new
-+ ("current-timezone-changed",
-+ G_OBJECT_CLASS_TYPE (obj_class),
-+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-+ G_STRUCT_OFFSET (IntlClockClass, current_timezone_changed),
-+ NULL, NULL,
-+ _intlclock_marshal_VOID__VOID,
-+ G_TYPE_NONE, 0);
-+
-+ g_type_class_add_private (this_class, sizeof (IntlClockPrivate));
- }
-
- static void
-@@ -133,7 +153,7 @@ intlclock_set_locations (IntlClock *this, GList *locations)
-
- priv->locations = locations;
-
-- g_signal_emit_by_name (this, "locations-changed");
-+ g_signal_emit (this, intlclock_signals[LOCATIONS_CHANGED], 0);
- }
-
- GList *
-@@ -202,7 +222,7 @@ intlclock_emit_tick (gpointer data)
- IntlClock *this = INTLCLOCK (data);
- IntlClockPrivate *priv = PRIVATE (this);
-
-- g_signal_emit_by_name (this, "tick");
-+ g_signal_emit (this, intlclock_signals[TICK], 0);
-
- if (priv->in_partial_timeout) {
- intlclock_reset_timeout (this);
-@@ -353,3 +373,9 @@ intlclock_free_locations (IntlClock *this)
- g_list_free (priv->locations);
- priv->locations = NULL;
- }
-+
-+void
-+intlclock_blink_location (IntlClock *this, IntlClockLocation *loc)
-+{
-+ g_signal_emit (this, intlclock_signals[BLINK_LOCATION], 0, loc);
-+}
-diff --git a/src/intlclock.h b/src/intlclock.h
-index 3b0012c..20c681d 100644
---- a/src/intlclock.h
-+++ b/src/intlclock.h
-@@ -27,6 +27,9 @@ typedef struct
-
- void (* tick) (IntlClock *clock);
- void (* locations_changed) (IntlClock *clock);
-+ void (* blink_location) (IntlClock *clock, IntlClockLocation *loc);
-+ void (* current_timezone_changed) (IntlClock *clock);
-+
- } IntlClockClass;
-
- GType intlclock_get_type (void);
-@@ -35,6 +38,7 @@ IntlClock *intlclock_new (void);
-
- void intlclock_set_locations (IntlClock *this, GList *list);
- GList *intlclock_get_locations (IntlClock *this);
-+void intlclock_blink_location (IntlClock *this, IntlClockLocation *loc);
-
- IntlClockZoneTable *intlclock_get_zonetable (IntlClock *this);
- gchar *intlclock_format_time (IntlClock *this, struct tm *now,
-diff --git a/src/set-timezone.c b/src/set-timezone.c
-new file mode 100644
-index 0000000..5c96149
---- /dev/null
-+++ b/src/set-timezone.c
-@@ -0,0 +1,426 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
-+ *
-+ * Copyright (C) 2007 David Zeuthen <david@fubar.dk>
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#ifdef HAVE_CONFIG_H
-+# include "config.h"
-+#endif
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <sys/wait.h>
-+
-+#include <dbus/dbus-glib.h>
-+#include <dbus/dbus-glib-lowlevel.h>
-+
-+#include <polkit/polkit.h>
-+#include <polkit-dbus/polkit-dbus.h>
-+
-+static DBusGConnection *
-+get_session_bus (void)
-+{
-+ GError *error;
-+ static DBusGConnection *bus = NULL;
-+
-+ if (bus == NULL) {
-+ error = NULL;
-+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-+ if (bus == NULL) {
-+ g_warning ("Couldn't connect to session bus: %s",
-+ error->message);
-+ g_error_free (error);
-+ }
-+ }
-+
-+ return bus;
-+}
-+
-+static DBusGConnection *
-+get_system_bus (void)
-+{
-+ GError *error;
-+ static DBusGConnection *bus = NULL;
-+
-+ if (bus == NULL) {
-+ error = NULL;
-+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
-+ if (bus == NULL) {
-+ g_warning ("Couldn't connect to system bus: %s",
-+ error->message);
-+ g_error_free (error);
-+ }
-+ }
-+
-+ return bus;
-+}
-+
-+static PolKitContext *
-+get_pk_context (void)
-+{
-+ static PolKitContext *pk_context = NULL;
-+
-+ if (pk_context == NULL) {
-+ pk_context = polkit_context_new ();
-+ if (!polkit_context_init (pk_context, NULL)) {
-+ polkit_context_unref (pk_context);
-+ pk_context = NULL;
-+ }
-+ }
-+
-+ return pk_context;
-+}
-+
-+gboolean
-+set_system_timezone (const char *filename, GError **err)
-+{
-+ DBusGConnection *session_bus;
-+ DBusGConnection *system_bus;
-+ DBusGProxy *mechanism_proxy;
-+ DBusGProxy *polkit_gnome_proxy;
-+ gboolean ret = FALSE;
-+
-+ session_bus = get_session_bus ();
-+ if (session_bus == NULL)
-+ goto out;
-+
-+ system_bus = get_system_bus ();
-+ if (system_bus == NULL)
-+ goto out;
-+
-+ mechanism_proxy = dbus_g_proxy_new_for_name (system_bus,
-+ "org.gnome.ClockApplet.Mechanism",
-+ "/",
-+ "org.gnome.ClockApplet.Mechanism");
-+
-+ polkit_gnome_proxy = dbus_g_proxy_new_for_name (session_bus,
-+ "org.gnome.PolicyKit",
-+ "/org/gnome/PolicyKit/Manager",
-+ "org.gnome.PolicyKit.Manager");
-+
-+ if (filename != NULL) {
-+ GError *error;
-+
-+ g_debug ("Trying to set timezone '%s'", filename);
-+ try_again:
-+ error = NULL;
-+ /* first, try to call into the mechanism */
-+ if (!dbus_g_proxy_call_with_timeout (mechanism_proxy,
-+ "SetTimezone",
-+ INT_MAX,
-+ &error,
-+ /* parameters: */
-+ G_TYPE_STRING, filename,
-+ G_TYPE_INVALID,
-+ /* return values: */
-+ G_TYPE_INVALID)) {
-+ if (dbus_g_error_has_name (error, "org.gnome.ClockApplet.Mechanism.NotPrivileged")) {
-+ char **tokens;
-+ char *polkit_result_textual;
-+ char *polkit_action;
-+ gboolean gained_privilege;
-+
-+ tokens = g_strsplit (error->message, " ", 2);
-+ g_error_free (error);
-+ if (g_strv_length (tokens) != 2) {
-+ g_warning ("helper return string malformed");
-+ g_strfreev (tokens);
-+ goto out;
-+ }
-+ polkit_action = tokens[0];
-+ polkit_result_textual = tokens[1];
-+
-+ g_debug ("helper refused; returned polkit_result='%s' and polkit_action='%s'",
-+ polkit_result_textual, polkit_action);
-+
-+ /* Now ask the user for auth... */
-+ if (!dbus_g_proxy_call_with_timeout (polkit_gnome_proxy,
-+ "ShowDialog",
-+ INT_MAX,
-+ &error,
-+ /* parameters: */
-+ G_TYPE_STRING, polkit_action,
-+ G_TYPE_UINT, 0, /* X11 window ID; none */
-+ G_TYPE_INVALID,
-+ /* return values: */
-+ G_TYPE_BOOLEAN, &gained_privilege,
-+ G_TYPE_INVALID)) {
-+ g_propagate_error (err, error);
-+ g_strfreev (tokens);
-+ goto out;
-+ }
-+ g_strfreev (tokens);
-+
-+ if (gained_privilege) {
-+ g_debug ("Gained privilege; trying to set timezone again");
-+ goto try_again;
-+ }
-+
-+ } else {
-+ g_propagate_error (err, error);
-+ }
-+ goto out;
-+ }
-+
-+ g_debug ("Successfully set time zone to '%s'", filename);
-+ }
-+
-+ ret = TRUE;
-+out:
-+ g_object_unref (mechanism_proxy);
-+ g_object_unref (polkit_gnome_proxy);
-+
-+ return ret;
-+}
-+
-+static gint
-+can_do (const gchar *pk_action_id)
-+{
-+ DBusConnection *system_bus;
-+ PolKitCaller *pk_caller;
-+ PolKitAction *pk_action;
-+ PolKitResult pk_result;
-+ PolKitContext *pk_context;
-+ DBusError dbus_error;
-+ gint res = 0;
-+
-+ system_bus = dbus_g_connection_get_connection (get_system_bus ());
-+ if (system_bus == NULL)
-+ goto out;
-+
-+ pk_context = get_pk_context ();
-+ if (pk_context == NULL)
-+ goto out;
-+
-+ pk_caller = NULL;
-+ pk_action = NULL;
-+
-+ pk_action = polkit_action_new ();
-+ polkit_action_set_action_id (pk_action, pk_action_id);
-+
-+ dbus_error_init (&dbus_error);
-+ pk_caller = polkit_caller_new_from_pid (system_bus, getpid (), &dbus_error);
-+ if (pk_caller == NULL) {
-+ fprintf (stderr, "cannot get caller from dbus name\n");
-+ goto out;
-+ }
-+
-+ pk_result = polkit_context_can_caller_do_action (pk_context, pk_action, pk_caller);
-+
-+ switch (pk_result) {
-+ default:
-+ case POLKIT_RESULT_UNKNOWN:
-+ case POLKIT_RESULT_NO:
-+ res = 0;
-+ break;
-+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH:
-+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_SESSION:
-+ case POLKIT_RESULT_ONLY_VIA_ADMIN_AUTH_KEEP_ALWAYS:
-+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH:
-+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION:
-+ case POLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS:
-+ res = 1;
-+ break;
-+ case POLKIT_RESULT_YES:
-+ res = 2;
-+ break;
-+ }
-+
-+out:
-+ if (pk_action != NULL)
-+ polkit_action_unref (pk_action);
-+ if (pk_caller != NULL)
-+ polkit_caller_unref (pk_caller);
-+
-+ return res;
-+}
-+
-+gint
-+can_set_system_timezone (void)
-+{
-+ return can_do ("org.gnome.clockapplet.mechanism.settimezone");
-+}
-+
-+gint
-+can_set_system_time (void)
-+{
-+ return can_do ("org.gnome.clockapplet.mechanism.settime");
-+}
-+
-+typedef struct {
-+ gint ref_count;
-+ gint64 time;
-+ GFunc callback;
-+ gpointer data;
-+ GDestroyNotify notify;
-+} SetTimeCallbackData;
-+
-+static void
-+free_data (gpointer d)
-+{
-+ SetTimeCallbackData *data = d;
-+
-+ data->ref_count--;
-+ if (data->ref_count == 0) {
-+ if (data->notify)
-+ data->notify (data->data);
-+ g_free (data);
-+ }
-+}
-+
-+static void set_time_async (SetTimeCallbackData *data);
-+
-+static void
-+auth_notify (DBusGProxy *proxy,
-+ DBusGProxyCall *call,
-+ void *user_data)
-+{
-+ SetTimeCallbackData *data = user_data;
-+ GError *error = NULL;
-+ gboolean gained_privilege;
-+
-+ if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &gained_privilege, G_TYPE_INVALID)) {
-+ if (gained_privilege)
-+ set_time_async (data);
-+ }
-+ else {
-+ if (data->callback)
-+ data->callback (data->data, error);
-+ else
-+ g_error_free (error);
-+ }
-+}
-+
-+static void
-+do_auth_async (const gchar *action,
-+ const gchar *result,
-+ SetTimeCallbackData *data)
-+{
-+ DBusGConnection *bus;
-+ DBusGProxy *proxy;
-+
-+ g_debug ("helper refused; returned polkit_result='%s' and polkit_action='%s'",
-+ result, action);
-+
-+ /* Now ask the user for auth... */
-+ bus = get_session_bus ();
-+ if (bus == NULL)
-+ return;
-+
-+ proxy = dbus_g_proxy_new_for_name (bus,
-+ "org.gnome.PolicyKit",
-+ "/org/gnome/PolicyKit/Manager",
-+ "org.gnome.PolicyKit.Manager");
-+
-+ data->ref_count++;
-+ dbus_g_proxy_begin_call_with_timeout (proxy,
-+ "ShowDialog",
-+ auth_notify,
-+ data, free_data,
-+ INT_MAX,
-+ G_TYPE_STRING, action,
-+ G_TYPE_UINT, 0,
-+ G_TYPE_INVALID);
-+}
-+
-+static void
-+set_time_notify (DBusGProxy *proxy,
-+ DBusGProxyCall *call,
-+ void *user_data)
-+{
-+ SetTimeCallbackData *data = user_data;
-+ GError *error = NULL;
-+
-+ if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
-+ if (data->callback)
-+ data->callback (data->data, NULL);
-+ }
-+ else {
-+ if (dbus_g_error_has_name (error, "org.gnome.ClockApplet.Mechanism.NotPrivileged")) {
-+ gchar **tokens;
-+
-+ tokens = g_strsplit (error->message, " ", 2);
-+ g_error_free (error);
-+ if (g_strv_length (tokens) == 2)
-+ do_auth_async (tokens[0], tokens[1], data);
-+ else
-+ g_warning ("helper return string malformed");
-+ g_strfreev (tokens);
-+ }
-+ else {
-+ if (data->callback)
-+ data->callback (data->data, error);
-+ else
-+ g_error_free (error);
-+ }
-+ }
-+}
-+
-+static void
-+set_time_async (SetTimeCallbackData *data)
-+{
-+ DBusGConnection *bus;
-+ DBusGProxy *proxy;
-+ DBusGProxyCall *call;
-+
-+ bus = get_system_bus ();
-+ if (bus == NULL)
-+ return;
-+
-+ proxy = dbus_g_proxy_new_for_name (bus,
-+ "org.gnome.ClockApplet.Mechanism",
-+ "/",
-+ "org.gnome.ClockApplet.Mechanism");
-+
-+ data->ref_count++;
-+ dbus_g_proxy_begin_call_with_timeout (proxy,
-+ "SetTime",
-+ set_time_notify,
-+ data, free_data,
-+ INT_MAX,
-+ /* parameters: */
-+ G_TYPE_INT64, data->time,
-+ G_TYPE_INVALID,
-+ /* return values: */
-+ G_TYPE_INVALID);
-+}
-+
-+void
-+set_system_time_async (gint64 time,
-+ GFunc callback,
-+ gpointer d,
-+ GDestroyNotify notify)
-+{
-+ SetTimeCallbackData *data;
-+
-+ if (time == -1)
-+ return;
-+
-+ data = g_new (SetTimeCallbackData, 1);
-+ data->ref_count = 1;
-+ data->time = time;
-+ data->callback = callback;
-+ data->data = d;
-+ data->notify = notify;
-+
-+ set_time_async (data);
-+ free_data (data);
-+}
-diff --git a/src/set-timezone.h b/src/set-timezone.h
-new file mode 100644
-index 0000000..c71622c
---- /dev/null
-+++ b/src/set-timezone.h
-@@ -0,0 +1,36 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
-+ *
-+ * Copyright (C) 2007 David Zeuthen <david@fubar.dk>
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#ifndef __SET_SYSTEM_TIMEZONE_H__
-+
-+#include <time.h>
-+
-+gboolean set_system_timezone (const char *filename,
-+ GError **err);
-+gint can_set_system_timezone (void);
-+
-+gint can_set_system_time (void);
-+
-+void set_system_time_async (gint64 time,
-+ GFunc callback,
-+ gpointer data,
-+ GDestroyNotify notify);
-+
-+#endif
diff --git a/intlclock-changes-20071013.patch b/intlclock-changes-20071014.patch
index b414c42..2dd2910 100644
--- a/intlclock-changes-20071013.patch
+++ b/intlclock-changes-20071014.patch
@@ -8455,7 +8455,7 @@ index 40d96e3..3535d8d 100644
+}
+
diff --git a/src/intlclock-location.c b/src/intlclock-location.c
-index 384b2aa..30154e4 100644
+index 384b2aa..dbb8f75 100644
--- a/src/intlclock-location.c
+++ b/src/intlclock-location.c
@@ -1,4 +1,3 @@
@@ -8463,7 +8463,7 @@ index 384b2aa..30154e4 100644
#ifdef HAVE_CONFIG_H
#include <config.h>
-@@ -13,9 +12,16 @@
+@@ -13,9 +12,21 @@
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
@@ -8473,6 +8473,11 @@ index 384b2aa..30154e4 100644
#include <libgnome/gnome-i18n.h>
+#include <libgnomevfs/gnome-vfs.h>
+
++#include <dbus/dbus-glib.h>
++#include <dbus/dbus-glib-lowlevel.h>
++#include <NetworkManager/NetworkManager.h>
++
++
+#include "intlclock-location.h"
+#include "intlclock-marshallers.h"
+#include "set-timezone.h"
@@ -8480,7 +8485,7 @@ index 384b2aa..30154e4 100644
G_DEFINE_TYPE (IntlClockLocation, intlclock_location, G_TYPE_OBJECT)
-@@ -29,17 +35,31 @@ typedef struct {
+@@ -29,17 +40,33 @@ typedef struct {
gfloat latitude;
gfloat longitude;
@@ -8502,6 +8507,8 @@ index 384b2aa..30154e4 100644
static void intlclock_location_set_tz (IntlClockLocation *this);
static void intlclock_location_unset_tz (IntlClockLocation *this);
+static void setup_weather_updates (IntlClockLocation *loc);
++static void add_to_network_monitor (IntlClockLocation *loc);
++static void remove_from_network_monitor (IntlClockLocation *loc);
#define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INTLCLOCK_LOCATION_TYPE, IntlClockLocationPrivate))
@@ -8513,7 +8520,7 @@ index 384b2aa..30154e4 100644
{
IntlClockLocation *this;
IntlClockLocationPrivate *priv;
-@@ -62,6 +82,9 @@ intlclock_location_new (const gchar *name, const gchar *timezone,
+@@ -62,6 +89,9 @@ intlclock_location_new (const gchar *name, const gchar *timezone,
priv->latitude = latitude;
priv->longitude = longitude;
@@ -8523,7 +8530,7 @@ index 384b2aa..30154e4 100644
return this;
}
-@@ -193,6 +216,77 @@ guess_zone_from_tree (const gchar *localtime, IntlClockZoneTable *zones)
+@@ -193,6 +223,77 @@ guess_zone_from_tree (const gchar *localtime, IntlClockZoneTable *zones)
return ret;
}
@@ -8601,7 +8608,7 @@ index 384b2aa..30154e4 100644
static gchar *
intlclock_location_guess_zone (IntlClockZoneTable *zones)
{
-@@ -200,6 +294,12 @@ intlclock_location_guess_zone (IntlClockZoneTable *zones)
+@@ -200,6 +301,12 @@ intlclock_location_guess_zone (IntlClockZoneTable *zones)
const char *localtime = "/etc/localtime";
gchar *linkfile = NULL;
GError *err = NULL;
@@ -8614,7 +8621,7 @@ index 384b2aa..30154e4 100644
/* guess the current time zone by readlink() on /etc/localtime */
linkfile = g_file_read_link (localtime, &err);
-@@ -235,14 +335,14 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
+@@ -235,14 +342,14 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
if (zone == NULL) {
/* make a fake location with a null TZ */
@@ -8631,7 +8638,7 @@ index 384b2aa..30154e4 100644
}
g_free (zone);
-@@ -260,7 +360,7 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
+@@ -260,7 +367,7 @@ intlclock_location_new_from_env (IntlClockZoneTable *zones)
}
ret = intlclock_location_new (name, intlclock_zoneinfo_get_name (info),
@@ -8640,7 +8647,7 @@ index 384b2aa..30154e4 100644
g_free (name);
-@@ -274,6 +374,15 @@ intlclock_location_class_init (IntlClockLocationClass *this_class)
+@@ -274,6 +381,15 @@ intlclock_location_class_init (IntlClockLocationClass *this_class)
g_obj_class->finalize = intlclock_location_finalize;
@@ -8656,7 +8663,16 @@ index 384b2aa..30154e4 100644
g_type_class_add_private (this_class, sizeof (IntlClockLocationPrivate));
}
-@@ -318,6 +427,21 @@ intlclock_location_finalize (GObject *g_obj)
+@@ -297,6 +413,8 @@ static void
+ intlclock_location_finalize (GObject *g_obj)
+ {
+ IntlClockLocationPrivate *priv = PRIVATE (g_obj);
++
++ remove_from_network_monitor (INTLCLOCK_LOCATION (g_obj));
+
+ if (priv->name) {
+ g_free (priv->name);
+@@ -318,6 +436,21 @@ intlclock_location_finalize (GObject *g_obj)
priv->tzname = NULL;
}
@@ -8678,7 +8694,7 @@ index 384b2aa..30154e4 100644
G_OBJECT_CLASS (intlclock_location_parent_class)->finalize (g_obj);
}
-@@ -467,3 +591,188 @@ intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm)
+@@ -467,3 +600,266 @@ intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm)
intlclock_location_unset_tz (loc);
}
@@ -8822,6 +8838,82 @@ index 384b2aa..30154e4 100644
+ (int)deg2, (int)min2, h2);
+}
+
++static GList *locations = NULL;
++
++static void
++update_weather_infos (void)
++{
++ GList *l;
++
++ for (l = locations; l; l = l->next) {
++ update_weather_info (l->data);
++ }
++}
++
++static DBusHandlerResult
++filter_func (DBusConnection *connection,
++ DBusMessage *message,
++ void *user_data)
++{
++ guint32 state = NM_DEVICE_STATE_UNKNOWN;
++
++ if (dbus_message_is_signal (message,
++ NM_DBUS_INTERFACE_DEVICE, "StateChanged")) {
++ dbus_message_get_args (message, NULL,
++ DBUS_TYPE_UINT32, &state,
++ DBUS_TYPE_INVALID);
++ if (state == NM_DEVICE_STATE_ACTIVATED) {
++ update_weather_infos ();
++ }
++
++ return DBUS_HANDLER_RESULT_HANDLED;
++ }
++
++ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++}
++
++static void
++setup_network_monitor (void)
++{
++ GError *error;
++ static DBusGConnection *bus = NULL;
++ DBusConnection *dbus;
++
++ if (bus == NULL) {
++ error = NULL;
++ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
++ if (bus == NULL) {
++ g_warning ("Couldn't connect to system bus: %s",
++ error->message);
++ g_error_free (error);
++
++ return;
++ }
++
++ dbus = dbus_g_connection_get_connection (bus);
++ dbus_connection_add_filter (dbus, filter_func, NULL, NULL);
++ dbus_bus_add_match (dbus,
++ "type='signal',"
++ "interface='" NM_DBUS_INTERFACE_DEVICE "'",
++ NULL);
++ }
++}
++
++static void
++add_to_network_monitor (IntlClockLocation *loc)
++{
++ setup_network_monitor ();
++
++ if (!g_list_find (locations, loc))
++ locations = g_list_prepend (locations, loc);
++}
++
++static void
++remove_from_network_monitor (IntlClockLocation *loc)
++{
++ locations = g_list_remove (locations, loc);
++}
++
+static void
+setup_weather_updates (IntlClockLocation *loc)
+{
@@ -8865,6 +8957,8 @@ index 384b2aa..30154e4 100644
+
+ weather_location_free (wl);
+ g_free (dms);
++
++ add_to_network_monitor (loc);
+}
+
diff --git a/src/intlclock-location.h b/src/intlclock-location.h