summaryrefslogtreecommitdiffstats
path: root/intlclock-changes-20071014.patch
diff options
context:
space:
mode:
Diffstat (limited to 'intlclock-changes-20071014.patch')
-rw-r--r--intlclock-changes-20071014.patch12308
1 files changed, 12308 insertions, 0 deletions
diff --git a/intlclock-changes-20071014.patch b/intlclock-changes-20071014.patch
new file mode 100644
index 0000000..2dd2910
--- /dev/null
+++ b/intlclock-changes-20071014.patch
@@ -0,0 +1,12308 @@
+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/Makefile.am b/pixmaps/Makefile.am
+index f5dd164..27aec65 100644
+--- a/pixmaps/Makefile.am
++++ b/pixmaps/Makefile.am
+@@ -3,8 +3,14 @@ icon_DATA = \
+ intlclock-calendar-icon.png \
+ intlclock-face-large.svg \
+ intlclock-face-small.svg \
++ intlclock-face-small-morning.svg \
++ intlclock-face-small-day.svg \
++ intlclock-face-small-evening.svg \
++ intlclock-face-small-night.svg \
+ intlclock-map.svg \
+- intlclock-map-location-marker.svg
++ intlclock-map-location-marker.svg \
++ intlclock-map-location-current.svg \
++ intlclock-map-location-hilight.svg
+
+ EXTRA_DIST = $(icon_DATA)
+
+diff --git a/pixmaps/intlclock-face-small-day.svg b/pixmaps/intlclock-face-small-day.svg
+new file mode 100644
+index 0000000..bd4b5b2
+--- /dev/null
++++ b/pixmaps/intlclock-face-small-day.svg
+@@ -0,0 +1,290 @@
++<?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:xlink="http://www.w3.org/1999/xlink"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ width="36"
++ height="36"
++ id="svg5416"
++ sodipodi:version="0.32"
++ inkscape:version="0.45+devel"
++ version="1.0"
++ sodipodi:docbase="/home/garrett/Desktop"
++ sodipodi:docname="clock-face-small-2.svg"
++ inkscape:output_extension="org.inkscape.output.svg.inkscape">
++ <defs
++ id="defs5418">
++ <linearGradient
++ id="linearGradient10653">
++ <stop
++ id="stop10655"
++ offset="0.0000000"
++ style="stop-color:#f3f4ff;stop-opacity:1.0000000;" />
++ <stop
++ id="stop10657"
++ offset="1.0000000"
++ style="stop-color:#9193af;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient42174">
++ <stop
++ id="stop42176"
++ offset="0.0000000"
++ style="stop-color:#a0a0a0;stop-opacity:1.0000000;" />
++ <stop
++ id="stop42178"
++ offset="1.0000000"
++ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient2145">
++ <stop
++ id="stop2147"
++ offset="0.0000000"
++ style="stop-color:#fffffd;stop-opacity:1.0000000;" />
++ <stop
++ id="stop2149"
++ offset="1"
++ style="stop-color:#d9d9d8;stop-opacity:1;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient37935">
++ <stop
++ style="stop-color:#9497b3;stop-opacity:1.0000000;"
++ offset="0.0000000"
++ id="stop37937" />
++ <stop
++ style="stop-color:#4c4059;stop-opacity:1.0000000;"
++ offset="1.0000000"
++ id="stop37939" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient3816"
++ inkscape:collect="always">
++ <stop
++ id="stop3818"
++ offset="0"
++ style="stop-color:#000000;stop-opacity:1;" />
++ <stop
++ id="stop3820"
++ offset="1"
++ style="stop-color:#000000;stop-opacity:0;" />
++ </linearGradient>
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient3816"
++ id="radialGradient5847"
++ gradientUnits="userSpaceOnUse"
++ cx="31.112698"
++ cy="19.008621"
++ fx="31.112698"
++ fy="19.008621"
++ r="8.6620579" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient37935"
++ id="radialGradient5849"
++ gradientUnits="userSpaceOnUse"
++ cx="8.7468252"
++ cy="6.8283234"
++ fx="8.7468252"
++ fy="6.8283234"
++ r="29.889715" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient2145"
++ id="radialGradient5851"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5853"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient10653"
++ id="radialGradient5855"
++ gradientUnits="userSpaceOnUse"
++ cx="11.3292"
++ cy="10.58397"
++ fx="11.3292"
++ fy="10.58397"
++ r="15.532059" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient2145"
++ id="radialGradient5857"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5859"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ </defs>
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="26.388889"
++ inkscape:cx="18"
++ inkscape:cy="18"
++ inkscape:document-units="px"
++ inkscape:current-layer="layer1"
++ inkscape:window-width="1600"
++ inkscape:window-height="1154"
++ inkscape:window-x="0"
++ inkscape:window-y="0"
++ width="36px"
++ height="36px" />
++ <metadata
++ id="metadata5421">
++ <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"
++ style="display:inline">
++ <path
++ d="M 39.774755,19.008621 A 8.6620579,8.6620579 0 1 1 22.45064,19.008621 A 8.6620579,8.6620579 0 1 1 39.774755,19.008621 z"
++ sodipodi:ry="8.6620579"
++ sodipodi:rx="8.6620579"
++ sodipodi:cy="19.008621"
++ sodipodi:cx="31.112698"
++ id="path4415"
++ style="color:#000000;fill:url(#radialGradient5847);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
++ sodipodi:type="arc"
++ transform="matrix(1.6624224,0,0,0.7910143,-33.728278,14.112097)" />
++ <path
++ transform="matrix(1.1148631,0,0,1.1148631,-0.1165205,-0.8531387)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4417"
++ style="fill:url(#radialGradient5849);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:1.6359601;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4419"
++ style="fill:url(#radialGradient5851);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5853);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ sodipodi:type="arc"
++ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient5855);stroke-width:1.72497916;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ id="path4421"
++ sodipodi:cx="16.25"
++ sodipodi:cy="16.910715"
++ sodipodi:rx="14.910714"
++ sodipodi:ry="14.910714"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ transform="matrix(1.0573301,0,0,1.0573301,0.8183498,5.0961231e-2)" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4429"
++ style="opacity:0.53921569;fill:url(#radialGradient5857);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5859);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
++ sodipodi:type="arc" />
++ <path
++ id="path5543"
++ d="M 19,18 C 19,18.552 18.551999,19 18,19 C 17.448,19 17,18.552 17,18 C 17,17.448 17.448,17 18,17 C 18.551999,17 19,17.448 19,18 z"
++ style="fill:#999c9c;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <g
++ id="g5802"
++ style="fill:#888a85;fill-opacity:1"
++ transform="matrix(0.9954167,0,0,0.9954167,8.2499251e-2,8.2498405e-2)">
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 7.9470493,18 C 7.9470493,18.414 7.6110484,18.75 7.1970493,18.75 C 6.7830492,18.75 6.4470493,18.414 6.4470493,18 C 6.4470493,17.586 6.7830492,17.25 7.1970493,17.25 C 7.6110484,17.25 7.9470493,17.586 7.9470493,18 z"
++ id="path5545" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 29.552951,18 C 29.552951,18.414 29.21695,18.75 28.802951,18.75 C 28.388951,18.75 28.052951,18.414 28.052951,18 C 28.052951,17.586 28.388951,17.25 28.802951,17.25 C 29.21695,17.25 29.552951,17.586 29.552951,18 z"
++ id="path5557" />
++ <path
++ id="path5649"
++ d="M 9.2938893,23.026476 C 9.5008893,23.38501 9.377904,23.843995 9.0193703,24.050995 C 8.6608357,24.257995 8.2018512,24.13501 7.9948512,23.776476 C 7.7878512,23.417941 7.9108357,22.958957 8.2693703,22.751956 C 8.627904,22.544957 9.0868893,22.667941 9.2938893,23.026476 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5651"
++ d="M 28.005149,12.223525 C 28.212149,12.582059 28.089164,13.041044 27.73063,13.248044 C 27.372095,13.455044 26.913111,13.332059 26.706111,12.973525 C 26.499111,12.61499 26.622095,12.156006 26.98063,11.949006 C 27.339164,11.742006 27.798149,11.86499 28.005149,12.223525 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.973525,26.706111 C 13.332059,26.913111 13.455043,27.372097 13.248044,27.730631 C 13.041044,28.089165 12.582059,28.21215 12.223525,28.00515 C 11.86499,27.79815 11.742006,27.339165 11.949006,26.980631 C 12.156005,26.622097 12.61499,26.499111 12.973525,26.706111 z"
++ id="path5655" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.776476,7.9948518 C 24.13501,8.2018518 24.257994,8.6608372 24.050995,9.0193708 C 23.843995,9.3779054 23.38501,9.5008899 23.026476,9.2938899 C 22.667941,9.0868899 22.544956,8.6279054 22.751956,8.2693708 C 22.958956,7.9108372 23.417941,7.7878518 23.776476,7.9948518 z"
++ id="path5657" />
++ <path
++ id="path5661"
++ d="M 18,28.052952 C 18.414,28.052952 18.75,28.388953 18.75,28.802952 C 18.75,29.216952 18.414,29.552952 18,29.552952 C 17.586,29.552952 17.25,29.216952 17.25,28.802952 C 17.25,28.388953 17.586,28.052952 18,28.052952 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5663"
++ d="M 18,6.44705 C 18.414,6.44705 18.75,6.783051 18.75,7.19705 C 18.75,7.61105 18.414,7.94705 18,7.94705 C 17.586,7.94705 17.25,7.61105 17.25,7.19705 C 17.25,6.783051 17.586,6.44705 18,6.44705 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.026476,26.706111 C 23.38501,26.499111 23.843995,26.622097 24.050995,26.980631 C 24.257995,27.339165 24.13501,27.79815 23.776476,28.00515 C 23.417941,28.21215 22.958957,28.089165 22.751956,27.730631 C 22.544957,27.372097 22.667941,26.913111 23.026476,26.706111 z"
++ id="path5667" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.223525,7.9948518 C 12.582059,7.7878518 13.041044,7.9108372 13.248044,8.2693708 C 13.455044,8.6279054 13.332059,9.0868899 12.973525,9.2938899 C 12.61499,9.5008899 12.156006,9.3779054 11.949006,9.0193708 C 11.742006,8.6608372 11.86499,8.2018518 12.223525,7.9948518 z"
++ id="path5669" />
++ <path
++ id="path5673"
++ d="M 26.706111,23.026476 C 26.913111,22.667942 27.372097,22.544958 27.730631,22.751957 C 28.089165,22.958957 28.21215,23.417942 28.00515,23.776476 C 27.79815,24.135011 27.339165,24.257995 26.980631,24.050995 C 26.622097,23.843996 26.499111,23.385011 26.706111,23.026476 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5675"
++ d="M 7.9948518,12.223525 C 8.2018518,11.864991 8.6608372,11.742007 9.0193708,11.949006 C 9.3779054,12.156006 9.5008899,12.614991 9.2938899,12.973525 C 9.0868899,13.33206 8.6279054,13.455044 8.2693708,13.248044 C 7.9108372,13.041045 7.7878518,12.58206 7.9948518,12.223525 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ </g>
++ </g>
++</svg>
+diff --git a/pixmaps/intlclock-face-small-evening.svg b/pixmaps/intlclock-face-small-evening.svg
+new file mode 100644
+index 0000000..17a9840
+--- /dev/null
++++ b/pixmaps/intlclock-face-small-evening.svg
+@@ -0,0 +1,290 @@
++<?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:xlink="http://www.w3.org/1999/xlink"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ width="36"
++ height="36"
++ id="svg5416"
++ sodipodi:version="0.32"
++ inkscape:version="0.45.1"
++ version="1.0"
++ sodipodi:docbase="/home/mclasen/Desktop/intlclock-1.0/pixmaps"
++ sodipodi:docname="intlclock-face-small-morning.svg"
++ inkscape:output_extension="org.inkscape.output.svg.inkscape">
++ <defs
++ id="defs5418">
++ <linearGradient
++ id="linearGradient10653">
++ <stop
++ id="stop10655"
++ offset="0.0000000"
++ style="stop-color:#f3f4ff;stop-opacity:1.0000000;" />
++ <stop
++ id="stop10657"
++ offset="1.0000000"
++ style="stop-color:#9193af;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient42174">
++ <stop
++ id="stop42176"
++ offset="0"
++ style="stop-color:#434343;stop-opacity:0.53535354;" />
++ <stop
++ id="stop42178"
++ offset="1.0000000"
++ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient2145">
++ <stop
++ id="stop2147"
++ offset="0.0000000"
++ style="stop-color:#fffffd;stop-opacity:1.0000000;" />
++ <stop
++ id="stop2149"
++ offset="1"
++ style="stop-color:#d9d9d8;stop-opacity:1;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient37935">
++ <stop
++ style="stop-color:#9497b3;stop-opacity:1.0000000;"
++ offset="0.0000000"
++ id="stop37937" />
++ <stop
++ style="stop-color:#4c4059;stop-opacity:1.0000000;"
++ offset="1.0000000"
++ id="stop37939" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient3816"
++ inkscape:collect="always">
++ <stop
++ id="stop3818"
++ offset="0"
++ style="stop-color:#000000;stop-opacity:1;" />
++ <stop
++ id="stop3820"
++ offset="1"
++ style="stop-color:#000000;stop-opacity:0;" />
++ </linearGradient>
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient3816"
++ id="radialGradient5847"
++ gradientUnits="userSpaceOnUse"
++ cx="31.112698"
++ cy="19.008621"
++ fx="31.112698"
++ fy="19.008621"
++ r="8.6620579" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient37935"
++ id="radialGradient5849"
++ gradientUnits="userSpaceOnUse"
++ cx="8.7468252"
++ cy="6.8283234"
++ fx="8.7468252"
++ fy="6.8283234"
++ r="29.889715" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient2145"
++ id="radialGradient5851"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5853"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient10653"
++ id="radialGradient5855"
++ gradientUnits="userSpaceOnUse"
++ cx="11.3292"
++ cy="10.58397"
++ fx="11.3292"
++ fy="10.58397"
++ r="15.532059" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="radialGradient5857"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5859"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ </defs>
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="26.388889"
++ inkscape:cx="18"
++ inkscape:cy="39.221053"
++ inkscape:document-units="px"
++ inkscape:current-layer="layer1"
++ inkscape:window-width="1600"
++ inkscape:window-height="1115"
++ inkscape:window-x="0"
++ inkscape:window-y="31"
++ width="36px"
++ height="36px" />
++ <metadata
++ id="metadata5421">
++ <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"
++ style="display:inline">
++ <path
++ d="M 39.774755,19.008621 A 8.6620579,8.6620579 0 1 1 22.45064,19.008621 A 8.6620579,8.6620579 0 1 1 39.774755,19.008621 z"
++ sodipodi:ry="8.6620579"
++ sodipodi:rx="8.6620579"
++ sodipodi:cy="19.008621"
++ sodipodi:cx="31.112698"
++ id="path4415"
++ style="color:#000000;fill:url(#radialGradient5847);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
++ sodipodi:type="arc"
++ transform="matrix(1.6624224,0,0,0.7910143,-33.728278,14.112097)" />
++ <path
++ transform="matrix(1.1148631,0,0,1.1148631,-0.1165205,-0.8531387)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4417"
++ style="fill:url(#radialGradient5849);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:1.6359601;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4419"
++ style="fill:url(#radialGradient5851);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5853);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ sodipodi:type="arc"
++ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient5855);stroke-width:1.72497916;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ id="path4421"
++ sodipodi:cx="16.25"
++ sodipodi:cy="16.910715"
++ sodipodi:rx="14.910714"
++ sodipodi:ry="14.910714"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ transform="matrix(1.0573301,0,0,1.0573301,0.8183498,5.0961231e-2)" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4429"
++ style="opacity:0.53921569;fill:url(#radialGradient5857);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient5859);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
++ sodipodi:type="arc" />
++ <path
++ id="path5543"
++ d="M 19,18 C 19,18.552 18.551999,19 18,19 C 17.448,19 17,18.552 17,18 C 17,17.448 17.448,17 18,17 C 18.551999,17 19,17.448 19,18 z"
++ style="fill:#999c9c;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <g
++ id="g5802"
++ style="fill:#888a85;fill-opacity:1"
++ transform="matrix(0.9954167,0,0,0.9954167,8.2499251e-2,8.2498405e-2)">
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 7.9470493,18 C 7.9470493,18.414 7.6110484,18.75 7.1970493,18.75 C 6.7830492,18.75 6.4470493,18.414 6.4470493,18 C 6.4470493,17.586 6.7830492,17.25 7.1970493,17.25 C 7.6110484,17.25 7.9470493,17.586 7.9470493,18 z"
++ id="path5545" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 29.552951,18 C 29.552951,18.414 29.21695,18.75 28.802951,18.75 C 28.388951,18.75 28.052951,18.414 28.052951,18 C 28.052951,17.586 28.388951,17.25 28.802951,17.25 C 29.21695,17.25 29.552951,17.586 29.552951,18 z"
++ id="path5557" />
++ <path
++ id="path5649"
++ d="M 9.2938893,23.026476 C 9.5008893,23.38501 9.377904,23.843995 9.0193703,24.050995 C 8.6608357,24.257995 8.2018512,24.13501 7.9948512,23.776476 C 7.7878512,23.417941 7.9108357,22.958957 8.2693703,22.751956 C 8.627904,22.544957 9.0868893,22.667941 9.2938893,23.026476 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5651"
++ d="M 28.005149,12.223525 C 28.212149,12.582059 28.089164,13.041044 27.73063,13.248044 C 27.372095,13.455044 26.913111,13.332059 26.706111,12.973525 C 26.499111,12.61499 26.622095,12.156006 26.98063,11.949006 C 27.339164,11.742006 27.798149,11.86499 28.005149,12.223525 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.973525,26.706111 C 13.332059,26.913111 13.455043,27.372097 13.248044,27.730631 C 13.041044,28.089165 12.582059,28.21215 12.223525,28.00515 C 11.86499,27.79815 11.742006,27.339165 11.949006,26.980631 C 12.156005,26.622097 12.61499,26.499111 12.973525,26.706111 z"
++ id="path5655" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.776476,7.9948518 C 24.13501,8.2018518 24.257994,8.6608372 24.050995,9.0193708 C 23.843995,9.3779054 23.38501,9.5008899 23.026476,9.2938899 C 22.667941,9.0868899 22.544956,8.6279054 22.751956,8.2693708 C 22.958956,7.9108372 23.417941,7.7878518 23.776476,7.9948518 z"
++ id="path5657" />
++ <path
++ id="path5661"
++ d="M 18,28.052952 C 18.414,28.052952 18.75,28.388953 18.75,28.802952 C 18.75,29.216952 18.414,29.552952 18,29.552952 C 17.586,29.552952 17.25,29.216952 17.25,28.802952 C 17.25,28.388953 17.586,28.052952 18,28.052952 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5663"
++ d="M 18,6.44705 C 18.414,6.44705 18.75,6.783051 18.75,7.19705 C 18.75,7.61105 18.414,7.94705 18,7.94705 C 17.586,7.94705 17.25,7.61105 17.25,7.19705 C 17.25,6.783051 17.586,6.44705 18,6.44705 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.026476,26.706111 C 23.38501,26.499111 23.843995,26.622097 24.050995,26.980631 C 24.257995,27.339165 24.13501,27.79815 23.776476,28.00515 C 23.417941,28.21215 22.958957,28.089165 22.751956,27.730631 C 22.544957,27.372097 22.667941,26.913111 23.026476,26.706111 z"
++ id="path5667" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.223525,7.9948518 C 12.582059,7.7878518 13.041044,7.9108372 13.248044,8.2693708 C 13.455044,8.6279054 13.332059,9.0868899 12.973525,9.2938899 C 12.61499,9.5008899 12.156006,9.3779054 11.949006,9.0193708 C 11.742006,8.6608372 11.86499,8.2018518 12.223525,7.9948518 z"
++ id="path5669" />
++ <path
++ id="path5673"
++ d="M 26.706111,23.026476 C 26.913111,22.667942 27.372097,22.544958 27.730631,22.751957 C 28.089165,22.958957 28.21215,23.417942 28.00515,23.776476 C 27.79815,24.135011 27.339165,24.257995 26.980631,24.050995 C 26.622097,23.843996 26.499111,23.385011 26.706111,23.026476 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5675"
++ d="M 7.9948518,12.223525 C 8.2018518,11.864991 8.6608372,11.742007 9.0193708,11.949006 C 9.3779054,12.156006 9.5008899,12.614991 9.2938899,12.973525 C 9.0868899,13.33206 8.6279054,13.455044 8.2693708,13.248044 C 7.9108372,13.041045 7.7878518,12.58206 7.9948518,12.223525 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ </g>
++ </g>
++</svg>
+diff --git a/pixmaps/intlclock-face-small-morning.svg b/pixmaps/intlclock-face-small-morning.svg
+new file mode 100644
+index 0000000..17a9840
+--- /dev/null
++++ b/pixmaps/intlclock-face-small-morning.svg
+@@ -0,0 +1,290 @@
++<?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:xlink="http://www.w3.org/1999/xlink"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ width="36"
++ height="36"
++ id="svg5416"
++ sodipodi:version="0.32"
++ inkscape:version="0.45.1"
++ version="1.0"
++ sodipodi:docbase="/home/mclasen/Desktop/intlclock-1.0/pixmaps"
++ sodipodi:docname="intlclock-face-small-morning.svg"
++ inkscape:output_extension="org.inkscape.output.svg.inkscape">
++ <defs
++ id="defs5418">
++ <linearGradient
++ id="linearGradient10653">
++ <stop
++ id="stop10655"
++ offset="0.0000000"
++ style="stop-color:#f3f4ff;stop-opacity:1.0000000;" />
++ <stop
++ id="stop10657"
++ offset="1.0000000"
++ style="stop-color:#9193af;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient42174">
++ <stop
++ id="stop42176"
++ offset="0"
++ style="stop-color:#434343;stop-opacity:0.53535354;" />
++ <stop
++ id="stop42178"
++ offset="1.0000000"
++ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient2145">
++ <stop
++ id="stop2147"
++ offset="0.0000000"
++ style="stop-color:#fffffd;stop-opacity:1.0000000;" />
++ <stop
++ id="stop2149"
++ offset="1"
++ style="stop-color:#d9d9d8;stop-opacity:1;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient37935">
++ <stop
++ style="stop-color:#9497b3;stop-opacity:1.0000000;"
++ offset="0.0000000"
++ id="stop37937" />
++ <stop
++ style="stop-color:#4c4059;stop-opacity:1.0000000;"
++ offset="1.0000000"
++ id="stop37939" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient3816"
++ inkscape:collect="always">
++ <stop
++ id="stop3818"
++ offset="0"
++ style="stop-color:#000000;stop-opacity:1;" />
++ <stop
++ id="stop3820"
++ offset="1"
++ style="stop-color:#000000;stop-opacity:0;" />
++ </linearGradient>
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient3816"
++ id="radialGradient5847"
++ gradientUnits="userSpaceOnUse"
++ cx="31.112698"
++ cy="19.008621"
++ fx="31.112698"
++ fy="19.008621"
++ r="8.6620579" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient37935"
++ id="radialGradient5849"
++ gradientUnits="userSpaceOnUse"
++ cx="8.7468252"
++ cy="6.8283234"
++ fx="8.7468252"
++ fy="6.8283234"
++ r="29.889715" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient2145"
++ id="radialGradient5851"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5853"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient10653"
++ id="radialGradient5855"
++ gradientUnits="userSpaceOnUse"
++ cx="11.3292"
++ cy="10.58397"
++ fx="11.3292"
++ fy="10.58397"
++ r="15.532059" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="radialGradient5857"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5859"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ </defs>
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="26.388889"
++ inkscape:cx="18"
++ inkscape:cy="39.221053"
++ inkscape:document-units="px"
++ inkscape:current-layer="layer1"
++ inkscape:window-width="1600"
++ inkscape:window-height="1115"
++ inkscape:window-x="0"
++ inkscape:window-y="31"
++ width="36px"
++ height="36px" />
++ <metadata
++ id="metadata5421">
++ <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"
++ style="display:inline">
++ <path
++ d="M 39.774755,19.008621 A 8.6620579,8.6620579 0 1 1 22.45064,19.008621 A 8.6620579,8.6620579 0 1 1 39.774755,19.008621 z"
++ sodipodi:ry="8.6620579"
++ sodipodi:rx="8.6620579"
++ sodipodi:cy="19.008621"
++ sodipodi:cx="31.112698"
++ id="path4415"
++ style="color:#000000;fill:url(#radialGradient5847);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
++ sodipodi:type="arc"
++ transform="matrix(1.6624224,0,0,0.7910143,-33.728278,14.112097)" />
++ <path
++ transform="matrix(1.1148631,0,0,1.1148631,-0.1165205,-0.8531387)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4417"
++ style="fill:url(#radialGradient5849);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:1.6359601;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4419"
++ style="fill:url(#radialGradient5851);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5853);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ sodipodi:type="arc"
++ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient5855);stroke-width:1.72497916;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ id="path4421"
++ sodipodi:cx="16.25"
++ sodipodi:cy="16.910715"
++ sodipodi:rx="14.910714"
++ sodipodi:ry="14.910714"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ transform="matrix(1.0573301,0,0,1.0573301,0.8183498,5.0961231e-2)" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4429"
++ style="opacity:0.53921569;fill:url(#radialGradient5857);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient5859);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
++ sodipodi:type="arc" />
++ <path
++ id="path5543"
++ d="M 19,18 C 19,18.552 18.551999,19 18,19 C 17.448,19 17,18.552 17,18 C 17,17.448 17.448,17 18,17 C 18.551999,17 19,17.448 19,18 z"
++ style="fill:#999c9c;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <g
++ id="g5802"
++ style="fill:#888a85;fill-opacity:1"
++ transform="matrix(0.9954167,0,0,0.9954167,8.2499251e-2,8.2498405e-2)">
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 7.9470493,18 C 7.9470493,18.414 7.6110484,18.75 7.1970493,18.75 C 6.7830492,18.75 6.4470493,18.414 6.4470493,18 C 6.4470493,17.586 6.7830492,17.25 7.1970493,17.25 C 7.6110484,17.25 7.9470493,17.586 7.9470493,18 z"
++ id="path5545" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 29.552951,18 C 29.552951,18.414 29.21695,18.75 28.802951,18.75 C 28.388951,18.75 28.052951,18.414 28.052951,18 C 28.052951,17.586 28.388951,17.25 28.802951,17.25 C 29.21695,17.25 29.552951,17.586 29.552951,18 z"
++ id="path5557" />
++ <path
++ id="path5649"
++ d="M 9.2938893,23.026476 C 9.5008893,23.38501 9.377904,23.843995 9.0193703,24.050995 C 8.6608357,24.257995 8.2018512,24.13501 7.9948512,23.776476 C 7.7878512,23.417941 7.9108357,22.958957 8.2693703,22.751956 C 8.627904,22.544957 9.0868893,22.667941 9.2938893,23.026476 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5651"
++ d="M 28.005149,12.223525 C 28.212149,12.582059 28.089164,13.041044 27.73063,13.248044 C 27.372095,13.455044 26.913111,13.332059 26.706111,12.973525 C 26.499111,12.61499 26.622095,12.156006 26.98063,11.949006 C 27.339164,11.742006 27.798149,11.86499 28.005149,12.223525 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.973525,26.706111 C 13.332059,26.913111 13.455043,27.372097 13.248044,27.730631 C 13.041044,28.089165 12.582059,28.21215 12.223525,28.00515 C 11.86499,27.79815 11.742006,27.339165 11.949006,26.980631 C 12.156005,26.622097 12.61499,26.499111 12.973525,26.706111 z"
++ id="path5655" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.776476,7.9948518 C 24.13501,8.2018518 24.257994,8.6608372 24.050995,9.0193708 C 23.843995,9.3779054 23.38501,9.5008899 23.026476,9.2938899 C 22.667941,9.0868899 22.544956,8.6279054 22.751956,8.2693708 C 22.958956,7.9108372 23.417941,7.7878518 23.776476,7.9948518 z"
++ id="path5657" />
++ <path
++ id="path5661"
++ d="M 18,28.052952 C 18.414,28.052952 18.75,28.388953 18.75,28.802952 C 18.75,29.216952 18.414,29.552952 18,29.552952 C 17.586,29.552952 17.25,29.216952 17.25,28.802952 C 17.25,28.388953 17.586,28.052952 18,28.052952 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5663"
++ d="M 18,6.44705 C 18.414,6.44705 18.75,6.783051 18.75,7.19705 C 18.75,7.61105 18.414,7.94705 18,7.94705 C 17.586,7.94705 17.25,7.61105 17.25,7.19705 C 17.25,6.783051 17.586,6.44705 18,6.44705 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.026476,26.706111 C 23.38501,26.499111 23.843995,26.622097 24.050995,26.980631 C 24.257995,27.339165 24.13501,27.79815 23.776476,28.00515 C 23.417941,28.21215 22.958957,28.089165 22.751956,27.730631 C 22.544957,27.372097 22.667941,26.913111 23.026476,26.706111 z"
++ id="path5667" />
++ <path
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.223525,7.9948518 C 12.582059,7.7878518 13.041044,7.9108372 13.248044,8.2693708 C 13.455044,8.6279054 13.332059,9.0868899 12.973525,9.2938899 C 12.61499,9.5008899 12.156006,9.3779054 11.949006,9.0193708 C 11.742006,8.6608372 11.86499,8.2018518 12.223525,7.9948518 z"
++ id="path5669" />
++ <path
++ id="path5673"
++ d="M 26.706111,23.026476 C 26.913111,22.667942 27.372097,22.544958 27.730631,22.751957 C 28.089165,22.958957 28.21215,23.417942 28.00515,23.776476 C 27.79815,24.135011 27.339165,24.257995 26.980631,24.050995 C 26.622097,23.843996 26.499111,23.385011 26.706111,23.026476 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5675"
++ d="M 7.9948518,12.223525 C 8.2018518,11.864991 8.6608372,11.742007 9.0193708,11.949006 C 9.3779054,12.156006 9.5008899,12.614991 9.2938899,12.973525 C 9.0868899,13.33206 8.6279054,13.455044 8.2693708,13.248044 C 7.9108372,13.041045 7.7878518,12.58206 7.9948518,12.223525 z"
++ style="fill:#888a85;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ </g>
++ </g>
++</svg>
+diff --git a/pixmaps/intlclock-face-small-night.svg b/pixmaps/intlclock-face-small-night.svg
+new file mode 100644
+index 0000000..d5a7d8e
+--- /dev/null
++++ b/pixmaps/intlclock-face-small-night.svg
+@@ -0,0 +1,291 @@
++<?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:xlink="http://www.w3.org/1999/xlink"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ width="36"
++ height="36"
++ id="svg5416"
++ sodipodi:version="0.32"
++ inkscape:version="0.45.1"
++ version="1.0"
++ sodipodi:docbase="/home/mclasen/Desktop/intlclock-1.0/pixmaps"
++ sodipodi:docname="intlclock-face-dark-small.svg"
++ inkscape:output_extension="org.inkscape.output.svg.inkscape">
++ <defs
++ id="defs5418">
++ <linearGradient
++ id="linearGradient10653">
++ <stop
++ id="stop10655"
++ offset="0.0000000"
++ style="stop-color:#f3f4ff;stop-opacity:1.0000000;" />
++ <stop
++ id="stop10657"
++ offset="1.0000000"
++ style="stop-color:#9193af;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient42174">
++ <stop
++ id="stop42176"
++ offset="0.0000000"
++ style="stop-color:#a0a0a0;stop-opacity:1.0000000;" />
++ <stop
++ id="stop42178"
++ offset="1.0000000"
++ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient2145">
++ <stop
++ id="stop2147"
++ offset="0.0000000"
++ style="stop-color:#fffffd;stop-opacity:1.0000000;" />
++ <stop
++ id="stop2149"
++ offset="1"
++ style="stop-color:#d9d9d8;stop-opacity:1;" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient37935">
++ <stop
++ style="stop-color:#27293c;stop-opacity:1;"
++ offset="0"
++ id="stop37937" />
++ <stop
++ style="stop-color:#d6cae3;stop-opacity:1;"
++ offset="1"
++ id="stop37939" />
++ </linearGradient>
++ <linearGradient
++ id="linearGradient3816"
++ inkscape:collect="always">
++ <stop
++ id="stop3818"
++ offset="0"
++ style="stop-color:#000000;stop-opacity:1;" />
++ <stop
++ id="stop3820"
++ offset="1"
++ style="stop-color:#000000;stop-opacity:0;" />
++ </linearGradient>
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient3816"
++ id="radialGradient5847"
++ gradientUnits="userSpaceOnUse"
++ cx="31.112698"
++ cy="19.008621"
++ fx="31.112698"
++ fy="19.008621"
++ r="8.6620579" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient37935"
++ id="radialGradient5849"
++ gradientUnits="userSpaceOnUse"
++ cx="8.7468252"
++ cy="6.8283234"
++ fx="8.7468252"
++ fy="6.8283234"
++ r="29.889715" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient2145"
++ id="radialGradient5851"
++ gradientUnits="userSpaceOnUse"
++ cx="11.901996"
++ cy="10.045444"
++ fx="11.901996"
++ fy="10.045444"
++ r="29.292715" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient42174"
++ id="linearGradient5853"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ <radialGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient10653"
++ id="radialGradient5855"
++ gradientUnits="userSpaceOnUse"
++ cx="11.3292"
++ cy="10.58397"
++ fx="11.3292"
++ fy="10.58397"
++ r="15.532059" />
++ <linearGradient
++ inkscape:collect="always"
++ xlink:href="#linearGradient10653"
++ id="linearGradient5859"
++ gradientUnits="userSpaceOnUse"
++ x1="6.342216"
++ y1="7.7893324"
++ x2="22.218424"
++ y2="25.884274" />
++ </defs>
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="26.388889"
++ inkscape:cx="18"
++ inkscape:cy="18"
++ inkscape:document-units="px"
++ inkscape:current-layer="layer1"
++ inkscape:window-width="1600"
++ inkscape:window-height="1115"
++ inkscape:window-x="0"
++ inkscape:window-y="31"
++ width="36px"
++ height="36px"
++ showguides="true"
++ inkscape:guide-bbox="true" />
++ <metadata
++ id="metadata5421">
++ <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"
++ style="display:inline">
++ <path
++ d="M 39.774755,19.008621 A 8.6620579,8.6620579 0 1 1 22.45064,19.008621 A 8.6620579,8.6620579 0 1 1 39.774755,19.008621 z"
++ sodipodi:ry="8.6620579"
++ sodipodi:rx="8.6620579"
++ sodipodi:cy="19.008621"
++ sodipodi:cx="31.112698"
++ id="path4415"
++ style="color:#000000;fill:url(#radialGradient5847);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
++ sodipodi:type="arc"
++ transform="matrix(1.6624224,0,0,0.7910143,-33.728278,14.112097)" />
++ <path
++ transform="matrix(1.1148631,0,0,1.1148631,-0.1165205,-0.8531387)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4417"
++ style="fill:url(#radialGradient5849);fill-opacity:1.0;fill-rule:evenodd;stroke:#605773;stroke-width:1.6359601;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4419"
++ style="fill:url(#radialGradient5851);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5853);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ sodipodi:type="arc" />
++ <path
++ sodipodi:type="arc"
++ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient5855);stroke-width:1.72497916;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
++ id="path4421"
++ sodipodi:cx="16.25"
++ sodipodi:cy="16.910715"
++ sodipodi:rx="14.910714"
++ sodipodi:ry="14.910714"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ transform="matrix(1.0573301,0,0,1.0573301,0.8183498,5.0961231e-2)" />
++ <path
++ transform="matrix(0.9318866,0,0,0.9318866,2.7831211,2.1674291)"
++ d="M 31.160714,16.910715 A 14.910714,14.910714 0 1 1 1.3392859,16.910715 A 14.910714,14.910714 0 1 1 31.160714,16.910715 z"
++ sodipodi:ry="14.910714"
++ sodipodi:rx="14.910714"
++ sodipodi:cy="16.910715"
++ sodipodi:cx="16.25"
++ id="path4429"
++ style="opacity:0.53921569;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5859);stroke-width:1.6660347;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
++ sodipodi:type="arc" />
++ <path
++ id="path5543"
++ d="M 19,18 C 19,18.552 18.551999,19 18,19 C 17.448,19 17,18.552 17,18 C 17,17.448 17.448,17 18,17 C 18.551999,17 19,17.448 19,18 z"
++ style="fill:#c3c9c9;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <g
++ id="g5802"
++ style="fill:#eaece7;fill-opacity:1"
++ transform="matrix(0.9954167,0,0,0.9954167,8.2499251e-2,8.2498405e-2)">
++ <path
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 7.9470493,18 C 7.9470493,18.414 7.6110484,18.75 7.1970493,18.75 C 6.7830492,18.75 6.4470493,18.414 6.4470493,18 C 6.4470493,17.586 6.7830492,17.25 7.1970493,17.25 C 7.6110484,17.25 7.9470493,17.586 7.9470493,18 z"
++ id="path5545" />
++ <path
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 29.552951,18 C 29.552951,18.414 29.21695,18.75 28.802951,18.75 C 28.388951,18.75 28.052951,18.414 28.052951,18 C 28.052951,17.586 28.388951,17.25 28.802951,17.25 C 29.21695,17.25 29.552951,17.586 29.552951,18 z"
++ id="path5557" />
++ <path
++ id="path5649"
++ d="M 9.2938893,23.026476 C 9.5008893,23.38501 9.377904,23.843995 9.0193703,24.050995 C 8.6608357,24.257995 8.2018512,24.13501 7.9948512,23.776476 C 7.7878512,23.417941 7.9108357,22.958957 8.2693703,22.751956 C 8.627904,22.544957 9.0868893,22.667941 9.2938893,23.026476 z"
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5651"
++ d="M 28.005149,12.223525 C 28.212149,12.582059 28.089164,13.041044 27.73063,13.248044 C 27.372095,13.455044 26.913111,13.332059 26.706111,12.973525 C 26.499111,12.61499 26.622095,12.156006 26.98063,11.949006 C 27.339164,11.742006 27.798149,11.86499 28.005149,12.223525 z"
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.973525,26.706111 C 13.332059,26.913111 13.455043,27.372097 13.248044,27.730631 C 13.041044,28.089165 12.582059,28.21215 12.223525,28.00515 C 11.86499,27.79815 11.742006,27.339165 11.949006,26.980631 C 12.156005,26.622097 12.61499,26.499111 12.973525,26.706111 z"
++ id="path5655" />
++ <path
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.776476,7.9948518 C 24.13501,8.2018518 24.257994,8.6608372 24.050995,9.0193708 C 23.843995,9.3779054 23.38501,9.5008899 23.026476,9.2938899 C 22.667941,9.0868899 22.544956,8.6279054 22.751956,8.2693708 C 22.958956,7.9108372 23.417941,7.7878518 23.776476,7.9948518 z"
++ id="path5657" />
++ <path
++ id="path5661"
++ d="M 18,28.052952 C 18.414,28.052952 18.75,28.388953 18.75,28.802952 C 18.75,29.216952 18.414,29.552952 18,29.552952 C 17.586,29.552952 17.25,29.216952 17.25,28.802952 C 17.25,28.388953 17.586,28.052952 18,28.052952 z"
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5663"
++ d="M 18,6.44705 C 18.414,6.44705 18.75,6.783051 18.75,7.19705 C 18.75,7.61105 18.414,7.94705 18,7.94705 C 17.586,7.94705 17.25,7.61105 17.25,7.19705 C 17.25,6.783051 17.586,6.44705 18,6.44705 z"
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 23.026476,26.706111 C 23.38501,26.499111 23.843995,26.622097 24.050995,26.980631 C 24.257995,27.339165 24.13501,27.79815 23.776476,28.00515 C 23.417941,28.21215 22.958957,28.089165 22.751956,27.730631 C 22.544957,27.372097 22.667941,26.913111 23.026476,26.706111 z"
++ id="path5667" />
++ <path
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
++ d="M 12.223525,7.9948518 C 12.582059,7.7878518 13.041044,7.9108372 13.248044,8.2693708 C 13.455044,8.6279054 13.332059,9.0868899 12.973525,9.2938899 C 12.61499,9.5008899 12.156006,9.3779054 11.949006,9.0193708 C 11.742006,8.6608372 11.86499,8.2018518 12.223525,7.9948518 z"
++ id="path5669" />
++ <path
++ id="path5673"
++ d="M 26.706111,23.026476 C 26.913111,22.667942 27.372097,22.544958 27.730631,22.751957 C 28.089165,22.958957 28.21215,23.417942 28.00515,23.776476 C 27.79815,24.135011 27.339165,24.257995 26.980631,24.050995 C 26.622097,23.843996 26.499111,23.385011 26.706111,23.026476 z"
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ <path
++ id="path5675"
++ d="M 7.9948518,12.223525 C 8.2018518,11.864991 8.6608372,11.742007 9.0193708,11.949006 C 9.3779054,12.156006 9.5008899,12.614991 9.2938899,12.973525 C 9.0868899,13.33206 8.6279054,13.455044 8.2693708,13.248044 C 7.9108372,13.041045 7.7878518,12.58206 7.9948518,12.223525 z"
++ style="fill:#eaece7;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1" />
++ </g>
++ <path
++ sodipodi:type="arc"
++ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:10.30000019;stroke-miterlimit:3.9000001;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
++ id="path6095"
++ sodipodi:cx="34.673683"
++ sodipodi:cy="29.804211"
++ sodipodi:rx="0"
++ sodipodi:ry="2.103158"
++ d="M 34.673683 29.804211 A 0 2.103158 0 1 1 34.673683,29.804211 A 0 2.103158 0 1 1 34.673683 29.804211 z" />
++ </g>
++</svg>
+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-face.c b/src/intlclock-face.c
+index 537e8e7..b2e1eb0 100644
+--- a/src/intlclock-face.c
++++ b/src/intlclock-face.c
+@@ -33,6 +33,13 @@ static void intlclock_face_load_face (IntlClockFace *this,
+ gint width, gint height);
+ typedef struct _IntlClockFacePrivate IntlClockFacePrivate;
+
++typedef enum {
++ INTLCLOCK_FACE_MORNING,
++ INTLCLOCK_FACE_DAY,
++ INTLCLOCK_FACE_EVENING,
++ INTLCLOCK_FACE_NIGHT
++} IntlClockFaceTimeOfDay;
++
+ struct _IntlClockFacePrivate
+ {
+ struct tm time; /* the time on the clock face */
+@@ -40,8 +47,8 @@ struct _IntlClockFacePrivate
+
+ gboolean running;
+ IntlClockFaceSize size;
++ IntlClockFaceTimeOfDay timeofday;
+ IntlClockLocation *location;
+- RsvgHandle *face;
+ GdkPixbuf *face_pixbuf;
+ GtkWidget *size_widget;
+ };
+@@ -80,6 +87,7 @@ intlclock_face_init (IntlClockFace *this)
+ IntlClockFacePrivate *priv = INTLCLOCK_FACE_GET_PRIVATE (this);
+
+ priv->size = INTLCLOCK_FACE_SMALL;
++ priv->timeofday = INTLCLOCK_FACE_DAY;
+ priv->location = NULL;
+ priv->size_widget = NULL;
+
+@@ -281,6 +289,48 @@ static void intlclock_face_size_request (GtkWidget *this,
+ requisition->height = h;
+ }
+
++static void
++update_timeofday (IntlClockFace *this)
++{
++ IntlClockFacePrivate *priv;
++ IntlClockFaceTimeOfDay timeofday;
++
++ priv = INTLCLOCK_FACE_GET_PRIVATE (this);
++
++ /* FIXME this should be a gconf setting
++ * currently we hardcode
++ * morning 7-9
++ * day 9-17
++ * evening 17-22
++ * night 22-7
++ */
++ if (priv->time.tm_hour < 7)
++ timeofday = INTLCLOCK_FACE_NIGHT;
++ else if (priv->time.tm_hour < 9)
++ timeofday = INTLCLOCK_FACE_MORNING;
++ else if (priv->time.tm_hour < 17)
++ timeofday = INTLCLOCK_FACE_DAY;
++ else if (priv->time.tm_hour < 22)
++ timeofday = INTLCLOCK_FACE_EVENING;
++ else
++ timeofday = INTLCLOCK_FACE_NIGHT;
++
++ if (priv->timeofday != timeofday) {
++ priv->timeofday = timeofday;
++ gint width, height;
++
++ width = GTK_WIDGET (this)->requisition.width;
++ height = GTK_WIDGET (this)->requisition.height;
++
++ if (width == 0)
++ width = -1;
++ if (height == 0)
++ height = -1;
++
++ intlclock_face_load_face (this, width, height);
++ }
++}
++
+ gboolean
+ intlclock_face_refresh (IntlClockFace *this)
+ {
+@@ -301,6 +351,8 @@ intlclock_face_refresh (IntlClockFace *this)
+ localtime_r (&timet, &priv->time);
+ }
+
++ update_timeofday (this);
++
+ intlclock_face_redraw_canvas (this);
+
+ return TRUE; /* keep running this event */
+@@ -343,11 +395,6 @@ intlclock_face_finalize (GObject *obj)
+ priv->location = NULL;
+ }
+
+- if (priv->face) {
+- rsvg_handle_close (priv->face, NULL);
+- priv->face = NULL;
+- }
+-
+ if (priv->face_pixbuf) {
+ gdk_pixbuf_unref (priv->face_pixbuf);
+ priv->face_pixbuf = NULL;
+@@ -375,16 +422,24 @@ static void
+ intlclock_face_load_face (IntlClockFace *this, gint width, gint height)
+ {
+ IntlClockFacePrivate *priv = INTLCLOCK_FACE_GET_PRIVATE (this);
++ const gchar *size_string[2] = { "small", "large" };
++ const gchar *daytime_string[4] = { "morning", "day", "evening", "night" };
++ gchar *name;
+
+ if (priv->face_pixbuf != NULL) {
+ gdk_pixbuf_unref (priv->face_pixbuf);
+ priv->face_pixbuf = NULL;
+ }
+
+- if (priv->size == INTLCLOCK_FACE_SMALL) {
+- priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (INTLCLOCK_ICONDIR "/intlclock-face-small.svg", width, height, NULL);
+- } else {
+- priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (INTLCLOCK_ICONDIR "/intlclock-face-large.svg", width, height, NULL);
+- }
++ name = g_strconcat (INTLCLOCK_ICONDIR, "/intlclock-face-", size_string[priv->size], "-", daytime_string[priv->timeofday], ".svg", NULL);
++
++ priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (name, width, height, NULL);
++ g_free (name);
++
++ if (priv->face_pixbuf)
++ return;
+
++ name = g_strconcat (INTLCLOCK_ICONDIR, "/intlclock-face-", size_string[priv->size], ".svg", NULL);
++ priv->face_pixbuf = rsvg_pixbuf_from_file_at_size (name, width, height, NULL);
++ g_free (name);
+ }
+diff --git a/src/intlclock-location-tile.c b/src/intlclock-location-tile.c
+index 40d96e3..3535d8d 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);
+ }
+@@ -226,10 +365,25 @@ static void
+ intlclock_location_tile_refresh (IntlClockLocationTile *this)
+ {
+ IntlClockLocationTilePrivate *priv = PRIVATE (this);
+-
+- gchar *tmp, *tzname;
++ gchar *tmp, *tmp2, *tzname;
+ char buf[256];
+ struct tm now;
++ long offset, hours, minutes;
++
++ 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));
+@@ -259,8 +413,22 @@ intlclock_location_tile_refresh (IntlClockLocationTile *this)
+ FALSE, TRUE, TRUE, tzname, TRUE);
+ }
+
+- gtk_label_set_markup (GTK_LABEL (priv->time_label), tmp);
++ offset = - intlclock_location_get_offset (priv->location);
++ hours = offset / 3600;
++ minutes = (offset % 3600) / 60;
++
++ if (hours != 0 && minutes != 0)
++ tmp2 = g_strdup_printf ("%s <small>%+d:%d</small>", tmp, hours, minutes);
++ else if (hours != 0)
++ tmp2 = g_strdup_printf ("%s <small>%+d</small>", tmp, hours);
++ else {
++ tmp2 = tmp;
++ tmp = NULL;
++ }
++
++ gtk_label_set_markup (GTK_LABEL (priv->time_label), tmp2);
+ g_free (tmp);
++ g_free (tmp2);
+ }
+
+ static void
+@@ -271,3 +439,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..dbb8f75 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,21 @@
+ #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 <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"
++#include "gweather-xml.h"
+
+ G_DEFINE_TYPE (IntlClockLocation, intlclock_location, G_TYPE_OBJECT)
+
+@@ -29,17 +40,33 @@ 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);
++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))
+
+ 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 +89,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 +223,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 +301,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 +342,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 +367,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 +381,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));
+ }
+
+@@ -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;
+ }
+
++ 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 +600,266 @@ intlclock_location_localtime (IntlClockLocation *loc, struct tm *tm)
+
+ intlclock_location_unset_tz (loc);
+ }
++
++gboolean
++intlclock_location_is_current (IntlClockLocation *loc)
++{
++ IntlClockLocationPrivate *priv = PRIVATE (loc);
++ const char *zone;
++
++ if ((zone = zone_from_etc_sysconfig_clock ()))
++ return strcmp (zone, priv->timezone) == 0;
++
++ return intlclock_location_get_offset (loc) == 0;
++}
++
++
++glong
++intlclock_location_get_offset (IntlClockLocation *loc)
++{
++ IntlClockLocationPrivate *priv = PRIVATE (loc);
++ glong sys_timezone;
++ glong offset;
++
++ unsetenv ("TZ");
++ tzset ();
++ sys_timezone = timezone;
++
++ setenv ("TZ", priv->timezone, 1);
++ tzset();
++
++ offset = timezone - sys_timezone;
++
++ if (priv->sys_timezone) {
++ setenv ("TZ", priv->sys_timezone, 1);
++ } else {
++ unsetenv ("TZ");
++ }
++ tzset();
++
++ return offset;
++}
++
++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 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)
++{
++ 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);
++
++ add_to_network_monitor (loc);
++}
++
+diff --git a/src/intlclock-location.h b/src/intlclock-location.h
+index 824ee3c..a711ac5 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,14 @@ 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);
++
++glong intlclock_location_get_offset (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