[gnome-clocks] Factor out a common ListModel



commit 7f26d63b13656a8119fa79a3cae6d041a8aa0f99
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Feb 7 16:55:11 2016 +0100

    Factor out a common ListModel

 src/alarm.vala   |   71 +++++++++++++------------------------------
 src/widgets.vala |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/world.vala   |   69 +++++++++++++++----------------------------
 3 files changed, 133 insertions(+), 94 deletions(-)
---
diff --git a/src/alarm.vala b/src/alarm.vala
index c039dc1..0674ab8 100644
--- a/src/alarm.vala
+++ b/src/alarm.vala
@@ -254,7 +254,7 @@ private class Item : Object, ContentItem {
         builder.close ();
     }
 
-    public static Item? deserialize (GLib.Variant alarm_variant) {
+    public static ContentItem? deserialize (GLib.Variant alarm_variant) {
         string? name = null;
         string? id = null;
         bool active = true;
@@ -523,7 +523,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
     public HeaderBar header_bar { get; construct set; }
     public PanelId panel_id { get; construct set; }
 
-    private ListStore alarms;
+    private ContentStore alarms;
     private GLib.Settings settings;
     private Gtk.Button new_button;
     [GtkChild]
@@ -538,23 +538,27 @@ public class Face : Gtk.Stack, Clocks.Clock {
                 header_bar: header_bar,
                 panel_id: PanelId.ALARM);
 
-        alarms = new ListStore (typeof (Item));
+        alarms = new ContentStore ();
         settings = new GLib.Settings ("org.gnome.clocks");
 
         var app = GLib.Application.get_default();
         var action = app.lookup_action ("stop-alarm");
         ((GLib.SimpleAction)action).activate.connect ((action, param) => {
-            var item = find_item (param.get_string());
-            if (item != null) {
-                item.stop();
+            var a = (Item)alarms.find ((a) => {
+                return ((Item)a).id == param.get_string();
+            });
+            if (a != null) {
+                a.stop();
             }
         });
 
         action = app.lookup_action ("snooze-alarm");
         ((GLib.SimpleAction)action).activate.connect ((action, param) => {
-            var item = find_item (param.get_string());
-            if (item != null) {
-                item.snooze();
+            var a = (Item)alarms.find ((a) => {
+                return ((Item)a).id == param.get_string();
+            });
+            if (a != null) {
+                a.snooze();
             }
         });
 
@@ -573,10 +577,8 @@ public class Face : Gtk.Stack, Clocks.Clock {
 
         // Start ticking...
         Utils.WallClock.get_default ().tick.connect (() => {
-            var n = alarms.get_n_items ();
-            for (int i = 0; i < n; i++) {
-                var a = alarms.get_object (i) as Item;
-                // a.tick() returns true if the state changed
+            alarms.foreach ((i) => {
+                var a = (Item)i;
                 if (a.tick()) {
                     if (a.state == Item.State.RINGING) {
                         show_ringing_panel (a);
@@ -585,7 +587,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
                         ringing_panel.update ();
                     }
                 }
-            }
+            });
         });
     }
 
@@ -603,16 +605,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
 
     [GtkCallback]
     private void delete_selected () {
-        Object[] not_selected = {};
-        var n = alarms.get_n_items ();
-        for (int i = 0; i < n; i++) {
-            var o = alarms.get_object (i);
-            if (!((Item)o).selected) {
-                not_selected += o;
-            }
-        }
-        // remove everything and readd the ones not selected
-        alarms.splice(0, n, not_selected);
+        alarms.delete_selected ();
         save ();
     }
 
@@ -635,35 +628,15 @@ public class Face : Gtk.Stack, Clocks.Clock {
         }
     }
 
-    private Item? find_item (string id) {
-        var n = alarms.get_n_items ();
-        for (int i = 0; i < n; i++) {
-            var item = alarms.get_object (i) as Item;
-            if (item.id == id) {
-                return item;
-            }
-        }
-        return null;
-    }
-
     private void load () {
-        foreach (var a in settings.get_value ("alarms")) {
-            Item? alarm = Item.deserialize (a);
-            if (alarm != null) {
-                alarms.append (alarm);
-                content_view.add_item (alarm);
-            }
-        }
+        alarms.deserialize (settings.get_value ("alarms"), Item.deserialize);
+        alarms.foreach ((item) => {
+            content_view.add_item (item);
+        });
     }
 
     private void save () {
-        var builder = new GLib.VariantBuilder (new VariantType ("aa{sv}"));
-        var n = alarms.get_n_items ();
-        for (int i = 0; i < n; i++) {
-            var a = alarms.get_object (i) as Item;
-            a.serialize (builder);
-        }
-        settings.set_value ("alarms", builder.end ());
+        settings.set_value ("alarms", alarms.serialize ());
     }
 
     private void edit (Item alarm) {
diff --git a/src/widgets.vala b/src/widgets.vala
index 1072251..8cec1cd 100644
--- a/src/widgets.vala
+++ b/src/widgets.vala
@@ -264,6 +264,93 @@ public interface ContentItem : GLib.Object {
                                                out string subtext,
                                                out Gdk.Pixbuf? pixbuf,
                                                out string css_class);
+
+    public abstract void serialize (GLib.VariantBuilder builder);
+}
+
+public class ContentStore : GLib.Object, GLib.ListModel {
+    private ListStore store;
+
+    public ContentStore () {
+        store = new ListStore (typeof (ContentItem));
+        store.items_changed.connect ((position, removed, added) => {
+            items_changed (position, removed, added);
+        });
+    }
+
+    public Type get_item_type () {
+        return store.get_item_type ();
+    }
+
+    public uint get_n_items () {
+        return store.get_n_items ();
+    }
+
+    public Object? get_item (uint position) {
+        return store.get_item (position);
+    }
+
+    public void append (ContentItem *item) {
+        store.append (item);
+    }
+
+    public delegate void ForeachFunc(ContentItem item);
+
+    public void foreach(ForeachFunc func) {
+        var n = store.get_n_items ();
+        for (int i = 0; i < n; i++) {
+            func(store.get_object (i) as ContentItem);
+        }
+    }
+
+    public delegate bool FindFunc(ContentItem item);
+
+    public ContentItem? find(FindFunc func) {
+        var n = store.get_n_items ();
+        for (int i = 0; i < n; i++) {
+            var item = store.get_object (i) as ContentItem;
+            if (func (item)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public void delete_selected () {
+        Object[] not_selected = {};
+        var n = store.get_n_items ();
+        for (int i = 0; i < n; i++) {
+            var o = store.get_object (i);
+            if (!((ContentItem)o).selected) {
+                not_selected += o;
+            }
+        }
+
+        // remove everything and readd the ones not selected
+        store.splice(0, n, not_selected);
+    }
+
+    public Variant serialize () {
+        var builder = new GLib.VariantBuilder (new VariantType ("aa{sv}"));
+        var n = store.get_n_items ();
+        for (int i = 0; i < n; i++) {
+            var item = store.get_object (i) as ContentItem;
+            item.serialize (builder);
+        }
+        return builder.end ();
+    }
+
+    public delegate ContentItem? DeserializeItemFunc(Variant v);
+
+    public void deserialize (Variant variant, DeserializeItemFunc deserialize_item) {
+        foreach (var v in variant) {
+            ContentItem? i = deserialize_item (v);
+            if (i != null) {
+                store.append (i);
+            }
+        }
+    }
+
 }
 
 private class IconView : Gtk.IconView {
diff --git a/src/world.vala b/src/world.vala
index 3bfb7ef..c4d42f5 100644
--- a/src/world.vala
+++ b/src/world.vala
@@ -158,12 +158,14 @@ public class Item : Object, ContentItem {
     }
 
     public void serialize (GLib.VariantBuilder builder) {
-        builder.open (new GLib.VariantType ("a{sv}"));
-        builder.add ("{sv}", "location", location.serialize ());
-        builder.close ();
+        if (!automatic) {
+            builder.open (new GLib.VariantType ("a{sv}"));
+            builder.add ("{sv}", "location", location.serialize ());
+            builder.close ();
+        }
     }
 
-    public static Item deserialize (GLib.Variant location_variant) {
+    public static ContentItem? deserialize (GLib.Variant location_variant) {
         GWeather.Location? location = null;
 
         var world = GWeather.Location.get_world ();
@@ -230,7 +232,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
     public HeaderBar header_bar { get; construct set; }
     public PanelId panel_id { get; construct set; }
 
-    private ListStore locations;
+    private ContentStore locations;
     private GLib.Settings settings;
     private Gtk.Button new_button;
     private Gtk.Button back_button;
@@ -258,7 +260,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
                 panel_id: PanelId.WORLD,
                 transition_type: Gtk.StackTransitionType.CROSSFADE);
 
-        locations = new ListStore (typeof (Item));
+        locations = new ContentStore ();
         settings = new GLib.Settings ("org.gnome.clocks");
 
         day_pixbuf = Utils.load_image ("day.png");
@@ -305,11 +307,9 @@ public class Face : Gtk.Stack, Clocks.Clock {
 
         // Start ticking...
         Utils.WallClock.get_default ().tick.connect (() => {
-            var n = locations.get_n_items ();
-            for (int i = 0; i < n; i++) {
-                var l = locations.get_object (i) as Item;
-                l.tick();
-            }
+            locations.foreach ((l) => {
+                ((Item)l).tick();
+            });
             content_view.queue_draw ();
             update_standalone ();
         });
@@ -322,16 +322,7 @@ public class Face : Gtk.Stack, Clocks.Clock {
 
     [GtkCallback]
     private void delete_selected () {
-        Object[] not_selected = {};
-        var n = locations.get_n_items ();
-        for (int i = 0; i < n; i++) {
-            var o = locations.get_object (i);
-            if (!((Item)o).selected) {
-                not_selected += o;
-            }
-        }
-        // remove everything and readd the ones not selected
-        locations.splice(0, n, not_selected);
+        locations.delete_selected ();
         save ();
     }
 
@@ -365,41 +356,29 @@ public class Face : Gtk.Stack, Clocks.Clock {
     }
 
     private void load () {
-        foreach (var l in settings.get_value ("world-clocks")) {
-            Item? location = Item.deserialize (l);
-            if (location != null) {
-                locations.append (location);
-                content_view.add_item (location);
-            }
-        }
+        locations.deserialize (settings.get_value ("world-clocks"), Item.deserialize);
+        locations.foreach ((item) => {
+            content_view.add_item (item);
+        });
     }
 
     private void save () {
-        var builder = new GLib.VariantBuilder (new VariantType ("aa{sv}"));
-        var n = locations.get_n_items ();
-        for (int i = 0; i < n; i++) {
-            var l = locations.get_object (i) as Item;
-            if (!l.automatic) {
-                l.serialize (builder);
-            }
-        }
-        settings.set_value ("world-clocks", builder.end ());
+        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 n = locations.get_n_items ();
-            for (int i = 0; i < n; i++) {
-                var l = locations.get_object (i) as Item;
-                if (geo_info.is_location_similar (l.location)) {
-                    return;
-                }
-            }
+            var item = (Item)locations.find ((l) => {
+                return geo_info.is_location_similar (((Item)l).location);
+            });
 
-            var item = new Item (found_location);
+            if (item != null) {
+                return;
+            }
 
+            item = new Item (found_location);
             item.automatic = true;
             item.selectable = false;
             item.title_icon = "find-location-symbolic";


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