[gnome-documents] all: keep view selection while refreshing the model



commit 6636d9bb42afb7da8d967b5cd2230bd95c9203f1
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Aug 23 16:00:26 2011 -0400

    all: keep view selection while refreshing the model
    
    If the model refreshes from under the view, reapply the selection.

 src/iconView.js     |   25 +++++++++++++++++++++++--
 src/listView.js     |   24 ++++++++++++++++++++++++
 src/mainWindow.js   |    6 +++---
 src/trackerModel.js |   21 +++++++++++++++------
 src/view.js         |   33 +++++++++++++++++++++++++++++----
 5 files changed, 94 insertions(+), 15 deletions(-)
---
diff --git a/src/iconView.js b/src/iconView.js
index a8f22c3..59f445b 100644
--- a/src/iconView.js
+++ b/src/iconView.js
@@ -56,6 +56,27 @@ IconView.prototype = {
         this.widget.show();
     },
 
+    preUpdate: function() {
+        let selection = this.widget.get_selected_items();
+
+        View.View.prototype.preUpdate.call(this, selection);
+    },
+
+    postUpdate: function() {
+        if (!this._selectedURNs)
+            return;
+
+        this._treeModel.foreach(Lang.bind(this,
+            function(model, path, iter) {
+                let urn = this._treeModel.get_value(iter, TrackerModel.ModelColumns.URN);
+
+                if (this._selectedURNs.indexOf(urn) != -1)
+                    this.widget.select_path(path);
+            }));
+
+        View.View.prototype.postUpdate.call(this);
+    },
+
     createRenderers: function() {
         let pixbufRenderer =
             new Gd.FramedPixbufRenderer({ xalign: 0.5,
@@ -81,5 +102,5 @@ IconView.prototype = {
 
     _onItemActivated: function(view, path, column) {
         this.activateItem(path);
-    },
-}
\ No newline at end of file
+    }
+};
diff --git a/src/listView.js b/src/listView.js
index 275d289..8909368 100644
--- a/src/listView.js
+++ b/src/listView.js
@@ -53,6 +53,30 @@ ListView.prototype = {
         this.activateItem(path);
     },
 
+    preUpdate: function() {
+        let treeSelection = this.widget.get_selection();
+        let selection = this.widget.get_selected_rows();
+
+        View.View.prototype.preUpdate.call(this, selection);
+    },
+
+    postUpdate: function() {
+        if (!this._selectedURNs)
+            return;
+
+        let treeSelection = this.widget.get_selection();
+
+        this._treeModel.foreach(Lang.bind(this,
+            function(model, path, iter) {
+                let urn = this._treeModel.get_value(iter, TrackerModel.ModelColumns.URN);
+
+                if (this._selectedURNs.indexOf(urn) != -1)
+                    treeSelection.select_path(path);
+            }));
+
+        View.View.prototype.postUpdate.call(this);
+    },
+
     createRenderers: function() {
         let col = new Gtk.TreeViewColumn();
         this.widget.append_column(col);
diff --git a/src/mainWindow.js b/src/mainWindow.js
index a93aed7..7677828 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -97,7 +97,7 @@ MainWindow.prototype = {
         this._grid.show_all();
 
         this._model = new TrackerModel.TrackerModel(Main.application.connection);
-        this._model.connect('count-updated', Lang.bind(this, this._onModelCountUpdated));
+        this._model.connect('model-update-done', Lang.bind(this, this._onModelUpdateDone));
 
         this._prepareForOverview();
     },
@@ -138,7 +138,7 @@ MainWindow.prototype = {
 
     _refreshViewSettings: function() {
         this._initView();
-        this.view.setModel(this._model.model);
+        this.view.setModel(this._model);
     },
 
     _refreshLoadMoreButton: function(itemCount, offset) {
@@ -252,7 +252,7 @@ MainWindow.prototype = {
         this._model.setFilter(text);
     },
 
-    _onModelCountUpdated: function(model, itemCount, offset) {
+    _onModelUpdateDone: function(model, itemCount, offset) {
         this._refreshLoadMoreButton(itemCount, offset);
     },
 
diff --git a/src/trackerModel.js b/src/trackerModel.js
index 52900e8..f61e183 100644
--- a/src/trackerModel.js
+++ b/src/trackerModel.js
@@ -205,8 +205,8 @@ TrackerModel.prototype = {
                     return;
                 }
 
-                this.model.clear();
-                this._performCurrentQuery();
+                this._emitModelUpdatePending();
+                this._refresh();
             }));
     },
 
@@ -242,7 +242,7 @@ TrackerModel.prototype = {
 
             if (!valid) {
                 // signal the total count update and return
-                this._emitCountUpdated();
+                this._emitModelUpdateDone();
                 return;
             }
         } catch (e) {
@@ -271,8 +271,17 @@ TrackerModel.prototype = {
                                      null, Lang.bind(this, this._onQueryExecuted));
     },
 
-    _emitCountUpdated: function() {
-        this.emit('count-updated', this.itemCount, this.offset);
+    _emitModelUpdateDone: function() {
+        this.emit('model-update-done', this.itemCount, this.offset);
+    },
+
+    _emitModelUpdatePending: function() {
+        this.emit('model-update-pending');
+    },
+
+    _refresh: function() {
+        this.model.clear();
+        this._performCurrentQuery();
     },
 
     populateForOverview: function(resourceUrn, filter) {
@@ -316,7 +325,7 @@ TrackerModel.prototype = {
                 } else {
                     this.offset = 0;
                     this.itemCount = 0;
-                    this._emitCountUpdated();
+                    this._emitModelUpdateDone();
                 }
             }));
     }
diff --git a/src/view.js b/src/view.js
index 613d887..94224b3 100644
--- a/src/view.js
+++ b/src/view.js
@@ -33,6 +33,7 @@ function View(window) {
 
 View.prototype = {
     _init: function(window) {
+        this._selectedURNs = null;
         this.window = window;
     },
 
@@ -42,20 +43,44 @@ View.prototype = {
 
     setModel: function(model) {
         this.model = model;
-        this.widget.set_model(model);
+        this.model.connect('model-update-pending', Lang.bind(this,
+            function() {
+                this.preUpdate();
+            }));
+        this.model.connect('model-update-done', Lang.bind(this,
+            function() {
+                this.postUpdate();
+            }));
+
+        this._treeModel = model.model;
+        this.widget.set_model(this._treeModel);
 
         this.createRenderers();
     },
 
+    preUpdate: function(selection) {
+        this._selectedURNs = selection.map(Lang.bind(this,
+            function(path) {
+                let iter = this._treeModel.get_iter(path)[1];
+                let urn = this._treeModel.get_value(iter, TrackerModel.ModelColumns.URN);
+
+                return urn;
+            }));
+    },
+
+    postUpdate: function() {
+        this._selectedURNs = null;
+    },
+
     // this must be overridden by all implementations
     createRenderers: function() {
         throw new Error('Missing implementation of createRenderers in ' + this);
     },
 
     activateItem: function(path) {
-        let iter = this.model.get_iter(path)[1];
-        let uri = this.model.get_value(iter, TrackerModel.ModelColumns.URI);
-        let resource = this.model.get_value(iter, TrackerModel.ModelColumns.RESOURCE_URN);
+        let iter = this._treeModel.get_iter(path)[1];
+        let uri = this._treeModel.get_value(iter, TrackerModel.ModelColumns.URI);
+        let resource = this._treeModel.get_value(iter, TrackerModel.ModelColumns.RESOURCE_URN);
 
         this.emit('item-activated', uri, resource);
     }



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