[gnome-documents] all: split offset control into a separate controller



commit aa695fd113f08645160d49eb3277eac65de7e7ae
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Aug 24 15:51:40 2011 -0400

    all: split offset control into a separate controller
    
    This allows avoiding propagating the offset state back and forth between
    the window and the model, so we can split the LoadMore button into a
    separate entity.

 src/Makefile-js.am      |    2 +
 src/application.js      |    2 +
 src/global.js           |    1 +
 src/loadMore.js         |   62 ++++++++++++++++++++++++++++++++++++++++++++
 src/mainWindow.js       |   36 +++-----------------------
 src/offsetController.js |   65 +++++++++++++++++++++++++++++++++++++++++++++++
 src/trackerModel.js     |   26 ++++++++-----------
 7 files changed, 147 insertions(+), 47 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 58a448d..ca3b0c3 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -6,9 +6,11 @@ dist_js_DATA = \
     global.js \
     iconView.js \
     listView.js \
+    loadMore.js \
     main.js \
     mainToolbar.js \
     mainWindow.js \
+    offsetController.js \
     preview.js \
     sidebar.js \
     sources.js \
diff --git a/src/application.js b/src/application.js
index 15f1863..5e92e15 100644
--- a/src/application.js
+++ b/src/application.js
@@ -34,6 +34,7 @@ const Format = imports.format;
 const Global = imports.global;
 const Main = imports.main;
 const MainWindow = imports.mainWindow;
+const OffsetController = imports.offsetController;
 const Path = imports.path;
 const Sources = imports.sources;
 const TrackerModel = imports.trackerModel;
@@ -103,6 +104,7 @@ Application.prototype = {
 
         Global.application = this;
         Global.settings = new Gio.Settings({ schema: 'org.gnome.documents' });
+        Global.offsetController = new OffsetController.OffsetController();
 
         // connect to tracker
         Tracker.SparqlConnection.get_async(null, Lang.bind(this,
diff --git a/src/global.js b/src/global.js
index 6387a03..11e1607 100644
--- a/src/global.js
+++ b/src/global.js
@@ -23,3 +23,4 @@ let application = null;
 let sourceManager = null;
 let connection = null;
 let settings = null;
+let offsetController = null;
diff --git a/src/loadMore.js b/src/loadMore.js
new file mode 100644
index 0000000..f0e1c97
--- /dev/null
+++ b/src/loadMore.js
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * Gnome Documents 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.
+ *
+ * Gnome Documents 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 Gnome Documents; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+const Global = imports.global;
+
+const Gtk = imports.gi.Gtk;
+const _ = imports.gettext.gettext;
+
+const Lang = imports.lang;
+
+function LoadMoreButton() {
+    this._init();
+};
+
+LoadMoreButton.prototype = {
+    _init: function() {
+        this._controller = Global.offsetController;
+        this._controller.connect('item-count-changed',
+                                 Lang.bind(this, this._onItemCountChanged));
+
+        this.widget = new Gtk.Button();
+        this.widget.connect('clicked', Lang.bind(this, function() {
+            this._controller.increaseOffset();
+        }));
+
+        this._onItemCountChanged();
+    },
+
+    _onItemCountChanged: function(itemCount) {
+        let remainingDocs = this._controller.getRemainingDocs();
+        let offsetStep = this._controller.getOffsetStep();
+
+        if (remainingDocs <= 0) {
+            this.widget.hide();
+            return;
+        }
+
+        if (remainingDocs > offsetStep)
+            remainingDocs = offsetStep;
+
+        this.widget.label = _("Load %d more documents").format(remainingDocs);
+        this.widget.show();
+    }
+};
\ No newline at end of file
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 641a33f..380cbe8 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -30,6 +30,7 @@ const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Global = imports.global;
+const LoadMore = imports.loadMore;
 const MainToolbar = imports.mainToolbar;
 const Sidebar = imports.sidebar;
 const TrackerModel = imports.trackerModel;
@@ -94,8 +95,6 @@ MainWindow.prototype = {
         this._grid.show_all();
 
         this._model = new TrackerModel.TrackerModel(Global.connection);
-        this._model.connect('model-update-done', Lang.bind(this, this._onModelUpdateDone));
-
         this._prepareForOverview();
     },
 
@@ -110,13 +109,9 @@ MainWindow.prototype = {
 
         this._destroyView();
 
-        this._loadMore = new Gtk.Button();
-        this._loadMore.connect('clicked', Lang.bind(this, function() {
-            this._model.loadMore();
-        }));
-
+        this._loadMore = new LoadMore.LoadMoreButton();
         this._viewBox = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
-        this._viewBox.add(this._loadMore);
+        this._viewBox.add(this._loadMore.widget);
 
         if (isList)
             this.view = new ListView.ListView(this);
@@ -125,7 +120,7 @@ MainWindow.prototype = {
 
         this.view.connect('item-activated', Lang.bind(this, this._onViewItemActivated));
 
-        this._viewBox.attach_next_to(this.view.widget, this._loadMore,
+        this._viewBox.attach_next_to(this.view.widget, this._loadMore.widget,
                                      Gtk.PositionType.TOP, 1, 1);
 
         this._scrolledWin.add_with_viewport(this._viewBox);
@@ -138,21 +133,6 @@ MainWindow.prototype = {
         this.view.setModel(this._model);
     },
 
-    _refreshLoadMoreButton: function(itemCount, offset) {
-        let remainingDocs = itemCount - (offset + TrackerModel.OFFSET_STEP);
-
-        if (remainingDocs <= 0) {
-            this._loadMore.hide();
-            return;
-        }
-
-        if (remainingDocs > TrackerModel.OFFSET_STEP)
-            remainingDocs = TrackerModel.OFFSET_STEP;
-
-        this._loadMore.label = _("Load %d more documents").format(remainingDocs);
-        this._loadMore.show();
-    },
-
     _prepareForPreview: function(model, document) {
         this._destroyView();
         this._sidebar.widget.hide();
@@ -176,10 +156,6 @@ MainWindow.prototype = {
 
         this._refreshViewSettings();
 
-        // needs to be called after _refreshViewSettings(), as that
-        // recreates the button
-        this._refreshLoadMoreButton(this._model.itemCount, this._model.offset);
-
         this._sidebar.widget.show();
         this._toolbar.setOverview(this._lastFilter);
         this._model.populateForOverview(this._lastFilter);
@@ -247,9 +223,5 @@ MainWindow.prototype = {
     _onToolbarSearchChanged: function(toolbar, text) {
         this._lastFilter = text;
         this._model.setFilter(text);
-    },
-
-    _onModelUpdateDone: function(model, itemCount, offset) {
-        this._refreshLoadMoreButton(itemCount, offset);
     }
 };
diff --git a/src/offsetController.js b/src/offsetController.js
new file mode 100644
index 0000000..b6fa2a8
--- /dev/null
+++ b/src/offsetController.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * Gnome Documents 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.
+ *
+ * Gnome Documents 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 Gnome Documents; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Cosimo Cecchi <cosimoc redhat com>
+ *
+ */
+
+const Signals = imports.signals;
+
+const _OFFSET_STEP = 50;
+
+function OffsetController() {
+    this._init();
+};
+
+OffsetController.prototype = {
+    _init: function() {
+        this._offset = 0;
+        this._itemCount = 0;
+    },
+
+    // to be called by the view
+    increaseOffset: function() {
+        this._offset += _OFFSET_STEP;
+        this.emit('offset-changed', this._offset);
+    },
+
+    // to be called by the model
+    setItemCount: function(itemCount) {
+        this._itemCount = itemCount;
+        this.emit('item-count-changed', this._itemCount);
+    },
+
+    // to be called by the model
+    resetOffset: function() {
+        this._offset = 0;
+    },
+
+    getRemainingDocs: function() {
+        return (this._itemCount - (this._offset + _OFFSET_STEP));
+    },
+
+    getOffsetStep: function() {
+        return _OFFSET_STEP;
+    },
+
+    getOffset: function() {
+        return this._offset;
+    }
+};
+Signals.addSignalMethods(OffsetController.prototype);
\ No newline at end of file
diff --git a/src/trackerModel.js b/src/trackerModel.js
index 56d92fc..06f5cf0 100644
--- a/src/trackerModel.js
+++ b/src/trackerModel.js
@@ -46,7 +46,6 @@ const ModelColumns = {
     N_COLUMNS: 7
 };
 
-const OFFSET_STEP = 50;
 const MINER_REFRESH_TIMEOUT = 60; /* seconds */
 
 const TrackerColumns = {
@@ -161,7 +160,7 @@ QueryBuilder.prototype = {
         return sparql;
     },
 
-    buildQuery: function(offset, searchString, filterId) {
+    buildQuery: function(searchString, filterId) {
         let sparql =
             ('SELECT DISTINCT ?urn ' + // urn
              'nie:url(?urn) ' + // uri
@@ -179,7 +178,8 @@ QueryBuilder.prototype = {
              this._buildFilterString('?urn', searchString, filterId) +
              ' } ' +
              'ORDER BY DESC (?mtime)' +
-             'LIMIT %d OFFSET %d').format(OFFSET_STEP, offset);
+             'LIMIT %d OFFSET %d').format(Global.offsetController.getOffsetStep(),
+                                          Global.offsetController.getOffset());
 
         return sparql;
     }
@@ -205,6 +205,10 @@ TrackerModel.prototype = {
         this._sourceManager = Global.sourceManager;
         this._sourceManager.connect('active-source-changed',
                                     Lang.bind(this, this._refreshAccountFilter));
+
+        this._offsetController = Global.offsetController;
+        this._offsetController.connect('offset-changed',
+                                       Lang.bind(this, this._performCurrentQuery));
     },
 
     _onSettingsChanged: function() {
@@ -234,7 +238,7 @@ TrackerModel.prototype = {
     },
 
     _addRowFromCursor: function(cursor) {
-        this.itemCount = cursor.get_integer(TrackerColumns.TOTAL_COUNT);
+        this._offsetController.setItemCount(cursor.get_integer(TrackerColumns.TOTAL_COUNT));
 
         let newDoc = this._factory.newDocument(cursor);
         let iter = this.model.append();
@@ -285,12 +289,12 @@ TrackerModel.prototype = {
     },
 
     _performCurrentQuery: function() {
-        this._connection.query_async(this._builder.buildQuery(this.offset, this._filter, this._resourceUrn),
+        this._connection.query_async(this._builder.buildQuery(this._filter, this._resourceUrn),
                                      null, Lang.bind(this, this._onQueryExecuted));
     },
 
     _emitModelUpdateDone: function() {
-        this.emit('model-update-done', this.itemCount, this.offset);
+        this.emit('model-update-done');
     },
 
     _emitModelUpdatePending: function() {
@@ -303,21 +307,13 @@ TrackerModel.prototype = {
     },
 
     populateForOverview: function(filter) {
-        this.offset = 0;
         this._filter = filter;
-
         this._refreshAccountFilter(this._sourceManager.getActiveSourceId());
     },
 
-    loadMore: function() {
-        this.offset += OFFSET_STEP;
-        this._performCurrentQuery();
-    },
-
     setFilter: function(filter) {
-        this.offset = 0;
         this._filter = filter;
-
+        this._offsetController.resetOffset();
         this._refresh();
     },
 



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