[gnome-clocks/wip/exalm/split: 5/7] world: Split into multiple files



commit 4e01f1963e2d177fe503c9a8264d2fd893c69530
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Sat May 23 04:10:22 2020 +0500

    world: Split into multiple files
    
    Fix ui file names. Rename Tile to Row.

 data/gnome-clocks.gresource.xml                    |   8 +-
 data/ui/{world.ui => world-face.ui}                |   0
 ...dlocationdialog.ui => world-location-dialog.ui} |   0
 data/ui/{worldtile.ui => world-row.ui}             |   4 +-
 .../ui/{worldstandalone.ui => world-standalone.ui} |   0
 src/meson.build                                    |   8 +-
 src/world-face.vala                                | 167 ++++++++++
 src/{world.vala => world-item.vala}                | 335 ---------------------
 src/world-location-dialog.vala                     |  69 +++++
 src/world-row.vala                                 | 109 +++++++
 src/world-shell-world-clocks.vala                  |  82 +++++
 src/world-standalone.vala                          |   2 +-
 12 files changed, 440 insertions(+), 344 deletions(-)
---
diff --git a/data/gnome-clocks.gresource.xml b/data/gnome-clocks.gresource.xml
index 34d6935..afd962c 100644
--- a/data/gnome-clocks.gresource.xml
+++ b/data/gnome-clocks.gresource.xml
@@ -6,10 +6,6 @@
     <file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
     <file preprocess="xml-stripblanks">ui/window.ui</file>
     <file preprocess="xml-stripblanks">ui/headerbar.ui</file>
-    <file preprocess="xml-stripblanks">ui/worldlocationdialog.ui</file>
-    <file preprocess="xml-stripblanks">ui/world.ui</file>
-    <file preprocess="xml-stripblanks">ui/worldstandalone.ui</file>
-    <file preprocess="xml-stripblanks">ui/worldtile.ui</file>
     <file preprocess="xml-stripblanks">ui/alarm-day-picker-row.ui</file>
     <file preprocess="xml-stripblanks">ui/alarm-face.ui</file>
     <file preprocess="xml-stripblanks">ui/alarm-ringing-panel.ui</file>
@@ -20,6 +16,10 @@
     <file preprocess="xml-stripblanks">ui/timer-face.ui</file>
     <file preprocess="xml-stripblanks">ui/timer-row.ui</file>
     <file preprocess="xml-stripblanks">ui/timer-setup.ui</file>
+    <file preprocess="xml-stripblanks">ui/world-face.ui</file>
+    <file preprocess="xml-stripblanks">ui/world-location-dialog.ui</file>
+    <file preprocess="xml-stripblanks">ui/world-row.ui</file>
+    <file preprocess="xml-stripblanks">ui/world-standalone.ui</file>
   </gresource>
   <gresource prefix="/org/gnome/clocks/icons">
     <file alias="globe-symbolic.svg">gtk/icons/globe-symbolic.svg</file>
diff --git a/data/ui/world.ui b/data/ui/world-face.ui
similarity index 100%
rename from data/ui/world.ui
rename to data/ui/world-face.ui
diff --git a/data/ui/worldlocationdialog.ui b/data/ui/world-location-dialog.ui
similarity index 100%
rename from data/ui/worldlocationdialog.ui
rename to data/ui/world-location-dialog.ui
diff --git a/data/ui/worldtile.ui b/data/ui/world-row.ui
similarity index 98%
rename from data/ui/worldtile.ui
rename to data/ui/world-row.ui
index e25ff47..7e1abc1 100644
--- a/data/ui/worldtile.ui
+++ b/data/ui/world-row.ui
@@ -2,7 +2,7 @@
 <!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
-  <template class="ClocksWorldTile" parent="GtkListBoxRow">
+  <template class="ClocksWorldRow" parent="GtkListBoxRow">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <child>
@@ -88,7 +88,7 @@
                 <property name="halign">center</property>
                 <property name="valign">center</property>
                 <property name="relief">none</property>
-                <signal name="clicked" handler="delete" object="ClocksWorldTile" swapped="no"/>
+                <signal name="clicked" handler="delete" object="ClocksWorldRow" swapped="no"/>
                 <child>
                   <object class="GtkImage">
                     <property name="visible">True</property>
diff --git a/data/ui/worldstandalone.ui b/data/ui/world-standalone.ui
similarity index 100%
rename from data/ui/worldstandalone.ui
rename to data/ui/world-standalone.ui
diff --git a/src/meson.build b/src/meson.build
index 5493555..0bb9915 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -26,8 +26,12 @@ clocks_vala_sources = [
   'utils.vala',
   'widgets.vala',
   'window.vala',
-  'world.vala',
-  'world-standalone.vala'
+  'world-face.vala',
+  'world-item.vala',
+  'world-location-dialog.vala',
+  'world-row.vala',
+  'world-shell-world-clocks.vala',
+  'world-standalone.vala',
 ]
 
 clocks_c_sources = [
diff --git a/src/world-face.vala b/src/world-face.vala
new file mode 100644
index 0000000..c84f822
--- /dev/null
+++ b/src/world-face.vala
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2013  Paolo Borelli <pborelli gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+namespace Clocks {
+namespace World {
+
+[GtkTemplate (ui = "/org/gnome/clocks/ui/world-face.ui")]
+public class Face : Gtk.Stack, Clocks.Clock {
+    public signal void show_standalone (Item location);
+
+    public PanelId panel_id { get; construct set; }
+    public ButtonMode button_mode { get; set; default = NEW; }
+    // Translators: Tooltip for the + button
+    public string? new_label { get; default = _("Add Location"); }
+
+    private ContentStore locations;
+    private GLib.Settings settings;
+    [GtkChild]
+    private Gtk.Widget empty_view;
+    [GtkChild]
+    private Gtk.ScrolledWindow list_view;
+    [GtkChild]
+    private Gtk.ListBox listbox;
+
+    construct {
+        panel_id = WORLD;
+        transition_type = CROSSFADE;
+
+        locations = new ContentStore ();
+        settings = new GLib.Settings ("org.gnome.clocks");
+
+        locations.set_sorting ((item1, item2) => {
+            var offset1 = ((GWeather.Timezone) ((Item) item1).location.get_timezone ()).get_offset ();
+            var offset2 = ((GWeather.Timezone) ((Item) item2).location.get_timezone ()).get_offset ();
+            if (offset1 < offset2)
+                return -1;
+            if (offset1 > offset2)
+                return 1;
+            return 0;
+        });
+
+        listbox.bind_model (locations, (item) => {
+            var row = new Row ((Item) item);
+
+            row.remove_clock.connect (() => locations.delete_item ((Item) item));
+
+            return row;
+        });
+
+        load ();
+
+        if (settings.get_boolean ("geolocation")) {
+            use_geolocation.begin ((obj, res) => {
+                use_geolocation.end (res);
+            });
+        }
+
+        locations.items_changed.connect ((position, removed, added) => {
+            save ();
+            reset_view ();
+        });
+
+        reset_view ();
+
+        // Start ticking...
+        Utils.WallClock.get_default ().tick.connect (() => {
+            locations.foreach ((l) => {
+                ((Item)l).tick ();
+            });
+            // TODO Only need to queue what changed
+            listbox.queue_draw ();
+        });
+    }
+
+    [GtkCallback]
+    private void item_activated (Gtk.ListBox list, Gtk.ListBoxRow row) {
+        show_standalone (((Row) row).location);
+    }
+
+    private void load () {
+        locations.deserialize (settings.get_value ("world-clocks"), Item.deserialize);
+    }
+
+    private void save () {
+        settings.set_value ("world-clocks", locations.serialize ());
+    }
+
+    private async void use_geolocation () {
+        Geo.Info geo_info = new Geo.Info ();
+
+        geo_info.location_changed.connect ((found_location) => {
+            var item = (Item?) locations.find ((l) => {
+                return geo_info.is_location_similar (((Item) l).location);
+            });
+
+            if (item != null) {
+                return;
+            }
+
+            var auto_item = new Item (found_location);
+            auto_item.automatic = true;
+            locations.add (auto_item);
+        });
+
+        yield geo_info.seek ();
+    }
+
+    private void add_location_item (Item item) {
+        locations.add (item);
+        save ();
+    }
+
+    public bool location_exists (GWeather.Location location) {
+        var exists = false;
+        var n = locations.get_n_items ();
+        for (int i = 0; i < n; i++) {
+            var l = (Item) locations.get_object (i);
+            if (l.location.equal (location)) {
+                exists = true;
+                break;
+            }
+        }
+
+        return exists;
+    }
+
+    public void add_location (GWeather.Location location) {
+        if (!location_exists (location)) {
+            add_location_item (new Item (location));
+        }
+    }
+
+    public void activate_new () {
+        var dialog = new LocationDialog ((Gtk.Window) get_toplevel (), this);
+
+        dialog.response.connect ((dialog, response) => {
+            if (response == 1) {
+                var location = ((LocationDialog) dialog).get_location ();
+                add_location_item ((Item) location);
+            }
+            dialog.destroy ();
+        });
+        dialog.show ();
+    }
+
+    private void reset_view () {
+        visible_child = locations.get_n_items () == 0 ? empty_view : list_view;
+    }
+}
+
+} // namespace World
+} // namespace Clocks
diff --git a/src/world.vala b/src/world-item.vala
similarity index 56%
rename from src/world.vala
rename to src/world-item.vala
index 4fe513b..ebc345e 100644
--- a/src/world.vala
+++ b/src/world-item.vala
@@ -19,65 +19,6 @@
 namespace Clocks {
 namespace World {
 
-// Export world clock locations to GNOME Shell
-[DBus (name = "org.gnome.Shell.ClocksIntegration")]
-public class ShellWorldClocks : Object {
-    [DBus (signature = "av")]
-    public Variant locations {
-        owned get {
-            Variant dict;
-            Variant[] rv = {};
-            var locations = settings.get_value ("world-clocks");
-            var iter = locations.iterator ();
-
-            while (iter.next ("@a{sv}", out dict)) {
-                string key;
-                Variant val;
-                var dict_iter = dict.iterator ();
-                while (dict_iter.next ("{sv}", out key, out val)) {
-                    if (key == "location") {
-                        rv += val;
-                    }
-                }
-            }
-
-            return rv;
-        }
-    }
-
-    private DBusConnection connection;
-    private string object_path;
-
-    private GLib.Settings settings;
-
-    public ShellWorldClocks (DBusConnection connection, string object_path) {
-        this.connection = connection;
-        this.object_path = object_path;
-
-        settings = new GLib.Settings ("org.gnome.clocks");
-        settings.changed["world-clocks"].connect (() => {
-            var builder = new VariantBuilder (VariantType.ARRAY);
-            var invalid_builder = new VariantBuilder (new VariantType ("as"));
-
-            Variant v = locations;
-            builder.add ("{sv}", "Locations", v);
-
-            try {
-                this.connection.emit_signal (null,
-                                            this.object_path,
-                                            "org.freedesktop.DBus.Properties",
-                                            "PropertiesChanged",
-                                            new Variant ("(sa{sv}as)",
-                                                        "org.gnome.Shell.ClocksIntegration",
-                                                        builder,
-                                                        invalid_builder));
-            } catch (Error e) {
-                warning ("Shell Integration failed: %s", e.message);
-            }
-        });
-    }
-}
-
 public class Item : Object, ContentItem {
     public GWeather.Location location { get; set; }
 
@@ -470,281 +411,5 @@ public class Item : Object, ContentItem {
     }
 }
 
-[GtkTemplate (ui = "/org/gnome/clocks/ui/worldtile.ui")]
-private class Tile : Gtk.ListBoxRow {
-    public Item location { get; construct set; }
-
-    [GtkChild]
-    private Gtk.Label time_label;
-    [GtkChild]
-    private Gtk.Widget name_label;
-    [GtkChild]
-    private Gtk.Label desc;
-    [GtkChild]
-    private Gtk.Stack delete_stack;
-    [GtkChild]
-    private Gtk.Widget delete_button;
-    [GtkChild]
-    private Gtk.Widget delete_empty;
-
-    internal signal void remove_clock ();
-
-    public Tile (Item location) {
-        Object (location: location);
-
-        location.bind_property ("city-name", name_label, "label", BindingFlags.DEFAULT | 
BindingFlags.SYNC_CREATE);
-        location.tick.connect (update);
-
-        update ();
-    }
-
-    private void update () {
-        var ctx = get_style_context ();
-        ctx.remove_class ("night");
-        ctx.remove_class ("astro");
-        ctx.remove_class ("naut");
-        ctx.remove_class ("civil");
-        ctx.remove_class ("day");
-        ctx.add_class (location.state_class);
-
-        var diff = ((double) location.local_offset / (double) TimeSpan.HOUR);
-        var diff_string = "%.0f".printf (diff.abs ());
-
-        if (diff != Math.round (diff)) {
-            if (diff * 2 != Math.round (diff * 2)) {
-                diff_string = "%.2f".printf (diff.abs ());
-            } else {
-                diff_string = "%.1f".printf (diff.abs ());
-            }
-        }
-
-        // Translators: The time is the same as the local time
-        var message = _("Current timezone");
-
-        if (diff > 0) {
-            // Translators: The (possibly fractical) number hours in the past
-            // (relative to local) the clock/location is
-            message = ngettext ("%s hour earlier",
-                                "%s hours earlier",
-                                ((int) diff).abs ()).printf (diff_string);
-        } else if (diff < 0) {
-            // Translators: The (possibly fractical) number hours in the
-            // future (relative to local) the clock/location is
-            message = ngettext ("%s hour later",
-                                "%s hours later",
-                                ((int) diff).abs ()).printf (diff_string);
-        }
-
-        if (location.day_label != null && location.day_label != "") {
-            desc.label = "%s • %s".printf ((string) location.day_label, message);
-            delete_stack.visible_child = delete_button;
-        } else if (location.automatic) {
-            // Translators: This clock represents the local time
-            desc.label = _("Current location");
-            delete_stack.visible_child = delete_empty;
-        } else {
-            desc.label = "%s".printf (message);
-            delete_stack.visible_child = delete_button;
-        }
-
-        time_label.label = location.time_label;
-    }
-
-    [GtkCallback]
-    private void delete () {
-        remove_clock ();
-    }
-}
-
-[GtkTemplate (ui = "/org/gnome/clocks/ui/worldlocationdialog.ui")]
-private class LocationDialog : Gtk.Dialog {
-    [GtkChild]
-    private GWeather.LocationEntry location_entry;
-    private Face world;
-
-    public LocationDialog (Gtk.Window parent, Face world_face) {
-        Object (transient_for: parent, use_header_bar: 1);
-
-        world = world_face;
-    }
-
-    [GtkCallback]
-    private void icon_released () {
-        if (location_entry.secondary_icon_name == "edit-clear-symbolic") {
-            location_entry.set_text ("");
-        }
-    }
-
-    [GtkCallback]
-    private void location_changed () {
-        GWeather.Location? l = null;
-        GWeather.Timezone? t = null;
-
-        if (location_entry.get_text () != "") {
-            l = location_entry.get_location ();
-
-            if (l != null && !world.location_exists ((GWeather.Location) l)) {
-                t = ((GWeather.Location) l).get_timezone ();
-
-                if (t == null) {
-                    warning ("Timezone not defined for %s. This is a bug in libgweather database",
-                             (string) ((GWeather.Location) l).get_city_name ());
-                }
-            }
-        }
-
-        set_response_sensitive (1, l != null && t != null);
-    }
-
-    public Item? get_location () {
-        var location = location_entry.get_location ();
-        return location != null ? (Item?) new Item ((GWeather.Location) location) : null;
-    }
-}
-
-[GtkTemplate (ui = "/org/gnome/clocks/ui/world.ui")]
-public class Face : Gtk.Stack, Clocks.Clock {
-    public signal void show_standalone (Item location);
-
-    public PanelId panel_id { get; construct set; }
-    public ButtonMode button_mode { get; set; default = NEW; }
-    // Translators: Tooltip for the + button
-    public string? new_label { get; default = _("Add Location"); }
-
-    private ContentStore locations;
-    private GLib.Settings settings;
-    [GtkChild]
-    private Gtk.Widget empty_view;
-    [GtkChild]
-    private Gtk.ScrolledWindow list_view;
-    [GtkChild]
-    private Gtk.ListBox listbox;
-
-    construct {
-        panel_id = WORLD;
-        transition_type = CROSSFADE;
-
-        locations = new ContentStore ();
-        settings = new GLib.Settings ("org.gnome.clocks");
-
-        locations.set_sorting ((item1, item2) => {
-            var offset1 = ((GWeather.Timezone) ((Item) item1).location.get_timezone ()).get_offset ();
-            var offset2 = ((GWeather.Timezone) ((Item) item2).location.get_timezone ()).get_offset ();
-            if (offset1 < offset2)
-                return -1;
-            if (offset1 > offset2)
-                return 1;
-            return 0;
-        });
-
-        listbox.bind_model (locations, (item) => {
-            var tile = new Tile ((Item) item);
-
-            tile.remove_clock.connect (() => locations.delete_item ((Item) item));
-
-            return tile;
-        });
-
-        load ();
-
-        if (settings.get_boolean ("geolocation")) {
-            use_geolocation.begin ((obj, res) => {
-                use_geolocation.end (res);
-            });
-        }
-
-        locations.items_changed.connect ((position, removed, added) => {
-            save ();
-            reset_view ();
-        });
-
-        reset_view ();
-
-        // Start ticking...
-        Utils.WallClock.get_default ().tick.connect (() => {
-            locations.foreach ((l) => {
-                ((Item)l).tick ();
-            });
-            // TODO Only need to queue what changed
-            listbox.queue_draw ();
-        });
-    }
-
-    [GtkCallback]
-    private void item_activated (Gtk.ListBox list, Gtk.ListBoxRow row) {
-        show_standalone (((Tile) row).location);
-    }
-
-    private void load () {
-        locations.deserialize (settings.get_value ("world-clocks"), Item.deserialize);
-    }
-
-    private void save () {
-        settings.set_value ("world-clocks", locations.serialize ());
-    }
-
-    private async void use_geolocation () {
-        Geo.Info geo_info = new Geo.Info ();
-
-        geo_info.location_changed.connect ((found_location) => {
-            var item = (Item?) locations.find ((l) => {
-                return geo_info.is_location_similar (((Item) l).location);
-            });
-
-            if (item != null) {
-                return;
-            }
-
-            var auto_item = new Item (found_location);
-            auto_item.automatic = true;
-            locations.add (auto_item);
-        });
-
-        yield geo_info.seek ();
-    }
-
-    private void add_location_item (Item item) {
-        locations.add (item);
-        save ();
-    }
-
-    public bool location_exists (GWeather.Location location) {
-        var exists = false;
-        var n = locations.get_n_items ();
-        for (int i = 0; i < n; i++) {
-            var l = (Item) locations.get_object (i);
-            if (l.location.equal (location)) {
-                exists = true;
-                break;
-            }
-        }
-
-        return exists;
-    }
-
-    public void add_location (GWeather.Location location) {
-        if (!location_exists (location)) {
-            add_location_item (new Item (location));
-        }
-    }
-
-    public void activate_new () {
-        var dialog = new LocationDialog ((Gtk.Window) get_toplevel (), this);
-
-        dialog.response.connect ((dialog, response) => {
-            if (response == 1) {
-                var location = ((LocationDialog) dialog).get_location ();
-                add_location_item ((Item) location);
-            }
-            dialog.destroy ();
-        });
-        dialog.show ();
-    }
-
-    private void reset_view () {
-        visible_child = locations.get_n_items () == 0 ? empty_view : list_view;
-    }
-}
-
 } // namespace World
 } // namespace Clocks
diff --git a/src/world-location-dialog.vala b/src/world-location-dialog.vala
new file mode 100644
index 0000000..44bdeef
--- /dev/null
+++ b/src/world-location-dialog.vala
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013  Paolo Borelli <pborelli gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+namespace Clocks {
+namespace World {
+
+[GtkTemplate (ui = "/org/gnome/clocks/ui/world-location-dialog.ui")]
+private class LocationDialog : Gtk.Dialog {
+    [GtkChild]
+    private GWeather.LocationEntry location_entry;
+    private Face world;
+
+    public LocationDialog (Gtk.Window parent, Face world_face) {
+        Object (transient_for: parent, use_header_bar: 1);
+
+        world = world_face;
+    }
+
+    [GtkCallback]
+    private void icon_released () {
+        if (location_entry.secondary_icon_name == "edit-clear-symbolic") {
+            location_entry.set_text ("");
+        }
+    }
+
+    [GtkCallback]
+    private void location_changed () {
+        GWeather.Location? l = null;
+        GWeather.Timezone? t = null;
+
+        if (location_entry.get_text () != "") {
+            l = location_entry.get_location ();
+
+            if (l != null && !world.location_exists ((GWeather.Location) l)) {
+                t = ((GWeather.Location) l).get_timezone ();
+
+                if (t == null) {
+                    warning ("Timezone not defined for %s. This is a bug in libgweather database",
+                             (string) ((GWeather.Location) l).get_city_name ());
+                }
+            }
+        }
+
+        set_response_sensitive (1, l != null && t != null);
+    }
+
+    public Item? get_location () {
+        var location = location_entry.get_location ();
+        return location != null ? (Item?) new Item ((GWeather.Location) location) : null;
+    }
+}
+
+} // namespace World
+} // namespace Clocks
diff --git a/src/world-row.vala b/src/world-row.vala
new file mode 100644
index 0000000..a8ceb45
--- /dev/null
+++ b/src/world-row.vala
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013  Paolo Borelli <pborelli gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+namespace Clocks {
+namespace World {
+
+[GtkTemplate (ui = "/org/gnome/clocks/ui/world-row.ui")]
+private class Row : Gtk.ListBoxRow {
+    public Item location { get; construct set; }
+
+    [GtkChild]
+    private Gtk.Label time_label;
+    [GtkChild]
+    private Gtk.Widget name_label;
+    [GtkChild]
+    private Gtk.Label desc;
+    [GtkChild]
+    private Gtk.Stack delete_stack;
+    [GtkChild]
+    private Gtk.Widget delete_button;
+    [GtkChild]
+    private Gtk.Widget delete_empty;
+
+    internal signal void remove_clock ();
+
+    public Row (Item location) {
+        Object (location: location);
+
+        location.bind_property ("city-name", name_label, "label", BindingFlags.DEFAULT | 
BindingFlags.SYNC_CREATE);
+        location.tick.connect (update);
+
+        update ();
+    }
+
+    private void update () {
+        var ctx = get_style_context ();
+        ctx.remove_class ("night");
+        ctx.remove_class ("astro");
+        ctx.remove_class ("naut");
+        ctx.remove_class ("civil");
+        ctx.remove_class ("day");
+        ctx.add_class (location.state_class);
+
+        var diff = ((double) location.local_offset / (double) TimeSpan.HOUR);
+        var diff_string = "%.0f".printf (diff.abs ());
+
+        if (diff != Math.round (diff)) {
+            if (diff * 2 != Math.round (diff * 2)) {
+                diff_string = "%.2f".printf (diff.abs ());
+            } else {
+                diff_string = "%.1f".printf (diff.abs ());
+            }
+        }
+
+        // Translators: The time is the same as the local time
+        var message = _("Current timezone");
+
+        if (diff > 0) {
+            // Translators: The (possibly fractical) number hours in the past
+            // (relative to local) the clock/location is
+            message = ngettext ("%s hour earlier",
+                                "%s hours earlier",
+                                ((int) diff).abs ()).printf (diff_string);
+        } else if (diff < 0) {
+            // Translators: The (possibly fractical) number hours in the
+            // future (relative to local) the clock/location is
+            message = ngettext ("%s hour later",
+                                "%s hours later",
+                                ((int) diff).abs ()).printf (diff_string);
+        }
+
+        if (location.day_label != null && location.day_label != "") {
+            desc.label = "%s • %s".printf ((string) location.day_label, message);
+            delete_stack.visible_child = delete_button;
+        } else if (location.automatic) {
+            // Translators: This clock represents the local time
+            desc.label = _("Current location");
+            delete_stack.visible_child = delete_empty;
+        } else {
+            desc.label = "%s".printf (message);
+            delete_stack.visible_child = delete_button;
+        }
+
+        time_label.label = location.time_label;
+    }
+
+    [GtkCallback]
+    private void delete () {
+        remove_clock ();
+    }
+}
+
+} // namespace World
+} // namespace Clocks
diff --git a/src/world-shell-world-clocks.vala b/src/world-shell-world-clocks.vala
new file mode 100644
index 0000000..bd37003
--- /dev/null
+++ b/src/world-shell-world-clocks.vala
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013  Paolo Borelli <pborelli gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+namespace Clocks {
+namespace World {
+
+// Export world clock locations to GNOME Shell
+[DBus (name = "org.gnome.Shell.ClocksIntegration")]
+public class ShellWorldClocks : Object {
+    [DBus (signature = "av")]
+    public Variant locations {
+        owned get {
+            Variant dict;
+            Variant[] rv = {};
+            var locations = settings.get_value ("world-clocks");
+            var iter = locations.iterator ();
+
+            while (iter.next ("@a{sv}", out dict)) {
+                string key;
+                Variant val;
+                var dict_iter = dict.iterator ();
+                while (dict_iter.next ("{sv}", out key, out val)) {
+                    if (key == "location") {
+                        rv += val;
+                    }
+                }
+            }
+
+            return rv;
+        }
+    }
+
+    private DBusConnection connection;
+    private string object_path;
+
+    private GLib.Settings settings;
+
+    public ShellWorldClocks (DBusConnection connection, string object_path) {
+        this.connection = connection;
+        this.object_path = object_path;
+
+        settings = new GLib.Settings ("org.gnome.clocks");
+        settings.changed["world-clocks"].connect (() => {
+            var builder = new VariantBuilder (VariantType.ARRAY);
+            var invalid_builder = new VariantBuilder (new VariantType ("as"));
+
+            Variant v = locations;
+            builder.add ("{sv}", "Locations", v);
+
+            try {
+                this.connection.emit_signal (null,
+                                            this.object_path,
+                                            "org.freedesktop.DBus.Properties",
+                                            "PropertiesChanged",
+                                            new Variant ("(sa{sv}as)",
+                                                        "org.gnome.Shell.ClocksIntegration",
+                                                        builder,
+                                                        invalid_builder));
+            } catch (Error e) {
+                warning ("Shell Integration failed: %s", e.message);
+            }
+        });
+    }
+}
+
+} // namespace World
+} // namespace Clocks
diff --git a/src/world-standalone.vala b/src/world-standalone.vala
index 5ad78ac..1ff33b6 100644
--- a/src/world-standalone.vala
+++ b/src/world-standalone.vala
@@ -19,7 +19,7 @@
 namespace Clocks {
 namespace World {
 
-[GtkTemplate (ui = "/org/gnome/clocks/ui/worldstandalone.ui")]
+[GtkTemplate (ui = "/org/gnome/clocks/ui/world-standalone.ui")]
 public class Standalone : Gtk.Box {
     public string title { get; set; default = _("Clocks"); }
     public string subtitle { get; set; }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]