[gnome-weather] Fix history handling



commit 0c4156db6219e05523569352e9679c8e07a47a52
Author: Giovanni Campagna <scampa giovanni gmail com>
Date:   Mon Feb 9 22:23:36 2015 -0800

    Fix history handling
    
    We need to store the last 5 locations in the order the were
    accessed by the user, and move the last location to the front
    of the list when it is click. We also need to update the
    store on disk when a change happens.
    
    As far as the current location is concerned, the design is
    that we store on disk if clicked explicitly, otherwise we
    forget it.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741837

 src/app/main.js     |    1 +
 src/app/window.js   |    6 +-
 src/app/world.js    |   13 +++++-
 src/shared/world.js |  105 +++++++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 105 insertions(+), 20 deletions(-)
---
diff --git a/src/app/main.js b/src/app/main.js
index 9d360b8..fe85976 100644
--- a/src/app/main.js
+++ b/src/app/main.js
@@ -145,6 +145,7 @@ const Application = new Lang.Class({
 
     vfunc_shutdown: function() {
         GWeather.Info.store_cache();
+        this.model.saveSettingsNow();
 
         this.parent();
     }
diff --git a/src/app/window.js b/src/app/window.js
index 19b82d7..062f696 100644
--- a/src/app/window.js
+++ b/src/app/window.js
@@ -160,12 +160,12 @@ const MainWindow = new Lang.Class({
         this._cityView.info = info;
         this._cityView.disconnectClock();
 
-        let isCurrentLocation = false;
+        let isCurrentTimezone = false;
         let currentLocation = this.application.currentLocationController.currentLocation;
         if (currentLocation) {
-            isCurrentLocation = currentLocation.get_timezone().get_tzid() == 
info.location.get_timezone().get_tzid();
+            isCurrentTimezone = currentLocation.get_timezone().get_tzid() == 
info.location.get_timezone().get_tzid();
         }
-        if (isCurrentLocation) {
+        if (isCurrentTimezone) {
             this._cityView.infoPage.timeGrid.hide();
         } else {
             this._cityView.connectClock();
diff --git a/src/app/world.js b/src/app/world.js
index 32edaff..99d0fab 100644
--- a/src/app/world.js
+++ b/src/app/world.js
@@ -86,7 +86,7 @@ const WorldContentView = new Lang.Class({
 
         this._listbox.connect('row-activated', Lang.bind(this, function(listbox, row) {
             this.hide();
-            this.model.showInfo(row._info);
+            this.model.showInfo(row._info, row._isCurrentLocation);
         }));
 
         this.model.connect('current-location-changed', Lang.bind(this, function(model, location) {
@@ -180,6 +180,7 @@ const WorldContentView = new Lang.Class({
         let row = new Gtk.ListBoxRow({ visible: true });
         row.add(grid);
         row._info = info;
+        row._isCurrentLocation = isCurrentLocation;
 
         if (isCurrentLocation) {
             if (model.addedCurrentLocation) {
@@ -194,7 +195,10 @@ const WorldContentView = new Lang.Class({
                 this._listbox.insert(row, 0);
         }
 
-        info.connect('updated', Lang.bind(this, function(info) {
+        if (info._updatedId)
+            return;
+
+        info._updatedId = info.connect('updated', Lang.bind(this, function(info) {
             tempLabel.label = info.get_temp_summary();
             image.icon_name = info.get_symbolic_icon_name();
         }));
@@ -209,5 +213,10 @@ const WorldContentView = new Lang.Class({
                 break;
             }
         }
+
+        if (info._updatedId) {
+            info.disconnect(info._updatedId);
+            info._updatedId = 0;
+        }
     },
 });
diff --git a/src/shared/world.js b/src/shared/world.js
index 114079d..4153668 100644
--- a/src/shared/world.js
+++ b/src/shared/world.js
@@ -77,7 +77,17 @@ const WorldModel = new Lang.Class({
         this.emit('current-location-changed', location);
     },
 
-    showInfo: function(info) {
+    showInfo: function(info, isCurrentLocation) {
+        if (info != null &&
+            this._infoList[0] != info &&
+            this._infoList.length > 1) {
+            this._moveLocationToFront(info, isCurrentLocation);
+        }
+
+        this._showInfoInternal(info);
+    },
+
+    _showInfoInternal: function(info) {
         this.currentlyLoadedInfo = info;
         this.emit('show-info', info);
         if (info != null)
@@ -86,9 +96,9 @@ const WorldModel = new Lang.Class({
 
     showRecent: function(listbox) {
         if (this._infoList.length > 0)
-            this.showInfo(this._infoList[0]);
+            this.showInfo(this._infoList[0], false);
         else
-            this.showInfo(null);
+            this.showInfo(null, false);
     },
 
     load: function () {
@@ -99,12 +109,16 @@ const WorldModel = new Lang.Class({
             this._settings.set_value('locations', new GLib.Variant('av', locations));
         }
 
-        for (let i = 0; i < locations.length; i++) {
+        let info = null;
+        for (let i = locations.length - 1; i >= 0; i--) {
             let variant = locations[i];
             let location = this._world.deserialize(variant);
 
-            this._addLocationInternal(location, false);
+            info = this._addLocationInternal(location, false);
         }
+
+        if (info)
+            this._showAddedLocation(info, false);
     },
 
     _updateLoadingCount: function(delta) {
@@ -140,33 +154,92 @@ const WorldModel = new Lang.Class({
             for (let info of this._infoList) {
                 let location = info.location;
                 if (location.equal(newLocation)) {
-                    this.showInfo(info);
+                    this.showInfo(info, false);
                     return;
                 }
             }
+        }
 
-            let locations = this._settings.get_value('locations').deep_unpack();
-            locations.push(newLocation.serialize());
-            this._settings.set_value('locations', new GLib.Variant('av', locations));
+        let info = this._addLocationInternal(newLocation, isCurrentLocation);
+        this._showAddedLocation(info, isCurrentLocation);
+
+        if (!isCurrentLocation)
+            this._queueSaveSettings();
+    },
+
+    _queueSaveSettings: function() {
+        if (this._queueSaveSettingsId)
+            return;
+
+        let id = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 10,
+                                          Lang.bind(this, function() {
+                                              this._queueSaveSettingsId = 0;
+                                              this._saveSettingsInternal();
+                                              return false;
+                                          }));
+        this._queueSaveSettingsId = id;
+    },
+
+    _saveSettingsInternal: function() {
+        let locations = [];
+
+        for (let i = 0; i < this._infoList.length; i++) {
+            if (!this._infoList[i]._isCurrentLocation)
+                locations.push(this._infoList[i].location.serialize());
         }
 
-        this._addLocationInternal(newLocation, isCurrentLocation);
+        this._settings.set_value('locations', new GLib.Variant('av', locations));
     },
 
-    _removeLocationInternal: function(oldInfo) {
-        if (oldInfo._loadingId) {
+    saveSettingsNow: function() {
+        if (!this._queueSaveSettingsId)
+            return;
+
+        GLib.source_remove(this._queueSaveSettingsId);
+        this._queueSaveSettingsId = 0;
+
+        this._saveSettingsInternal();
+    },
+
+    _moveLocationToFront: function(info, isCurrentLocation) {
+        this._removeLocationInternal(info, true);
+        this._addInfoInternal(info, isCurrentLocation);
+
+        // mark info as a manually chosen location so that we
+        // save it
+        info._isCurrentLocation = false;
+
+        this._queueSaveSettings();
+    },
+
+    _removeLocationInternal: function(oldInfo, skipDisconnect) {
+        if (oldInfo._loadingId && !skipDisconnect) {
             oldInfo.disconnect(oldInfo._loadingId);
             oldInfo._loadingId = 0;
             this._updateLoadingCount(-1);
         }
 
+        for (let i = 0; i < this._infoList.length; i++) {
+            if (this._infoList[i] == oldInfo) {
+                this._infoList.splice(i, 1);
+                break;
+            }
+        }
+
         this.emit('location-removed', oldInfo);
     },
 
     _addLocationInternal: function(newLocation, isCurrentLocation) {
         let info = new GWeather.Info({ location: newLocation,
                                        enabled_providers: this._providers });
-        this._infoList.push(info);
+        this._addInfoInternal(info, isCurrentLocation);
+
+        return info;
+    },
+
+    _addInfoInternal: function(info, isCurrentLocation) {
+        info._isCurrentLocation = isCurrentLocation;
+        this._infoList.unshift(info);
         this.updateInfo(info);
 
         this.emit('location-added', info, isCurrentLocation);
@@ -175,14 +248,16 @@ const WorldModel = new Lang.Class({
             let oldInfo = this._infoList.pop();
             this._removeLocationInternal(oldInfo);
         }
+    },
 
+    _showAddedLocation: function(info, isCurrentLocation) {
         if (isCurrentLocation) {
             if(!this.addedCurrentLocation)
-                this.showInfo(info);
+                this._showInfoInternal(info);
 
             this.addedCurrentLocation = true;
         } else {
-            this.showInfo(info);
+            this._showInfoInternal(info);
         }
     }
 });


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