[gnome-documents] all: split filter handling into a separate controller



commit 5d9f54e9453ea4111089fd1239791c58d4ced3e3
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Aug 24 16:10:48 2011 -0400

    all: split filter handling into a separate controller
    
    Keep on decoupling view and model.

 src/Makefile-js.am      |    1 +
 src/application.js      |    2 ++
 src/filterController.js |   45 +++++++++++++++++++++++++++++++++++++++++++++
 src/mainToolbar.js      |   18 +++++++++---------
 src/mainWindow.js       |    6 ++----
 src/trackerModel.js     |   46 ++++++++++++++++++++++++----------------------
 6 files changed, 83 insertions(+), 35 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index ca3b0c3..23585b2 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -2,6 +2,7 @@ jsdir = $(pkgdatadir)/js/
 dist_js_DATA = \
     application.js \
     docFactory.js \
+    filterController.js \
     gDataMiner.js \
     global.js \
     iconView.js \
diff --git a/src/application.js b/src/application.js
index 5e92e15..3c58c90 100644
--- a/src/application.js
+++ b/src/application.js
@@ -30,6 +30,7 @@ const Gtk = imports.gi.Gtk;
 const GLib = imports.gi.GLib;
 const Tracker = imports.gi.Tracker;
 
+const FilterController = imports.filterController;
 const Format = imports.format;
 const Global = imports.global;
 const Main = imports.main;
@@ -105,6 +106,7 @@ Application.prototype = {
         Global.application = this;
         Global.settings = new Gio.Settings({ schema: 'org.gnome.documents' });
         Global.offsetController = new OffsetController.OffsetController();
+        Global.filterController = new FilterController.FilterController();
 
         // connect to tracker
         Tracker.SparqlConnection.get_async(null, Lang.bind(this,
diff --git a/src/filterController.js b/src/filterController.js
new file mode 100644
index 0000000..696515e
--- /dev/null
+++ b/src/filterController.js
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+function FilterController() {
+    this._init();
+};
+
+FilterController.prototype = {
+    _init: function() {
+        this._filter = '';
+    },
+
+    setFilter: function(filter) {
+        if (this._filter == filter)
+            return;
+
+        this._filter = filter;
+        this.emit('filter-changed', this._filter);
+    },
+
+    getFilter: function() {
+        return this._filter;
+    }
+};
+Signals.addSignalMethods(FilterController.prototype);
diff --git a/src/mainToolbar.js b/src/mainToolbar.js
index 4a33331..a916860 100644
--- a/src/mainToolbar.js
+++ b/src/mainToolbar.js
@@ -49,7 +49,7 @@ MainToolbar.prototype = {
         }));
     },
 
-    _populateForOverview: function(filter) {
+    _populateForOverview: function() {
         let iconView = new Gtk.ToggleButton({ child: new Gtk.Image({ icon_name: 'view-grid-symbolic',
                                                                      pixel_size: 16 }) });
         iconView.get_style_context().add_class('linked');
@@ -101,11 +101,12 @@ MainToolbar.prototype = {
                 this._searchEntryTimeout = 0;
             }
 
-            this._searchEntryTimeout = Mainloop.timeout_add(_SEARCH_ENTRY_TIMEOUT, Lang.bind(this, function() {
-                this._searchEntryTimeout = 0;
+            this._searchEntryTimeout = Mainloop.timeout_add(_SEARCH_ENTRY_TIMEOUT, Lang.bind(this,
+                function() {
+                    this._searchEntryTimeout = 0;
 
-                let currentText = this._searchEntry.get_text();
-                this.emit('search-text-changed', currentText);
+                    let currentText = this._searchEntry.get_text();
+                    Global.filterController.setFilter(currentText);
             }));
         }));
 
@@ -118,8 +119,7 @@ MainToolbar.prototype = {
 
         this.widget.show_all();
 
-        if (filter)
-            this._searchEntry.set_text(filter);
+        this._searchEntry.set_text(Global.filterController.getFilter());
     },
 
     _populateForPreview: function(model, document) {
@@ -164,9 +164,9 @@ MainToolbar.prototype = {
         label.set_text(_("page %d of %d").format(curPage + 1, totPages));
     },
 
-    setOverview: function(filter) {
+    setOverview: function() {
         this._clearToolbar();
-        this._populateForOverview(filter);
+        this._populateForOverview();
     },
 
     setPreview: function(model, document) {
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 380cbe8..b627d94 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -81,8 +81,6 @@ MainWindow.prototype = {
         this._grid.add(this._viewContainer);
 
         this._toolbar = new MainToolbar.MainToolbar();
-        this._toolbar.connect('search-text-changed',
-                              Lang.bind(this, this._onToolbarSearchChanged));
         this._toolbar.connect('back-clicked',
                               Lang.bind(this, this._onToolbarBackClicked));
         this._viewContainer.add(this._toolbar.widget);
@@ -157,8 +155,8 @@ MainWindow.prototype = {
         this._refreshViewSettings();
 
         this._sidebar.widget.show();
-        this._toolbar.setOverview(this._lastFilter);
-        this._model.populateForOverview(this._lastFilter);
+        this._toolbar.setOverview();
+        this._model.populateForOverview();
     },
 
     _onDeleteEvent: function() {
diff --git a/src/trackerModel.js b/src/trackerModel.js
index 9ec4e92..8117886 100644
--- a/src/trackerModel.js
+++ b/src/trackerModel.js
@@ -68,17 +68,17 @@ QueryBuilder.prototype = {
     _init: function() {
     },
 
-    _buildFilterSearch: function(subject, searchString) {
+    _buildFilterSearch: function(subject) {
         let filter =
             ('fn:contains ' +
              '(fn:lower-case (tracker:coalesce(nie:title(%s), nfo:fileName(%s))), ' +
              '"%s") ' +
-             '&& ').format(subject, subject, searchString);
+             '&& ').format(subject, subject, Global.filterController.getFilter());
 
         return filter;
     },
 
-    _buildFilterLocal: function(subject, searchString) {
+    _buildFilterLocal: function(subject) {
         let path;
         let desktopURI;
         let documentsURI;
@@ -96,7 +96,7 @@ QueryBuilder.prototype = {
             documentsURI = '';
 
         let filter =
-            this._buildFilterSearch(subject, searchString) +
+            this._buildFilterSearch(subject) +
             ('((fn:starts-with (nie:url(%s), "%s")) || ' +
              '(fn:starts-with (nie:url(%s), "%s")))').format(subject, desktopURI,
                                                              subject, documentsURI);
@@ -104,36 +104,36 @@ QueryBuilder.prototype = {
         return filter;
     },
 
-    _buildFilterNotLocal: function(subject, searchString) {
+    _buildFilterNotLocal: function(subject) {
         let filter =
-            this._buildFilterSearch(subject, searchString) +
+            this._buildFilterSearch(subject) +
             ('(fn:contains(rdf:type(%s), \"RemoteDataObject\"))').format(subject);
 
         return filter;
     },
 
-    _buildFilterResource: function(subject, searchString, resourceUrn) {
+    _buildFilterResource: function(subject, resourceUrn) {
         let filter =
-            this._buildFilterSearch(subject, searchString) +
+            this._buildFilterSearch(subject) +
             ('(nie:dataSource(%s) = "<%s>")').format(subject, resourceUrn);
 
         return filter;
     },
 
-    _buildFilterString: function(subject, searchString) {
+    _buildFilterString: function(subject) {
         let filterId = Global.sourceManager.getActiveSourceUrn();
         let sparql = 'FILTER ((';
 
         if (filterId == 'local' || filterId == 'all')
-            sparql += this._buildFilterLocal(subject, searchString);
+            sparql += this._buildFilterLocal(subject);
 
         if (filterId == 'all')
             sparql += ') || (';
 
         if (filterId != 'local' && filterId != 'all')
-            sparql += this._buildFilterResource(subject, searchString, filterId);
+            sparql += this._buildFilterResource(subject, filterId);
         else if (filterId == 'all')
-            sparql += this._buildFilterNotLocal(subject, searchString);
+            sparql += this._buildFilterNotLocal(subject);
 
         sparql += ')) ';
 
@@ -151,24 +151,24 @@ QueryBuilder.prototype = {
         return sparql;
     },
 
-    _buildTotalCounter: function(searchString) {
+    _buildTotalCounter: function() {
         let sparql =
             '(SELECT DISTINCT COUNT(?doc) WHERE { ' +
             this._buildTypeFilter('?doc') +
-            this._buildFilterString('?doc', searchString) +
+            this._buildFilterString('?doc') +
             '}) ';
 
         return sparql;
     },
 
-    buildQuery: function(searchString) {
+    buildQuery: function() {
         let sparql =
             ('SELECT DISTINCT ?urn ' + // urn
              'nie:url(?urn) ' + // uri
              'tracker:coalesce(nie:title(?urn), nfo:fileName(?urn)) ' + // title
              'tracker:coalesce(nco:fullname(?creator), nco:fullname(?publisher)) ' + // author
              'tracker:coalesce(nfo:fileLastModified(?urn), nie:contentLastModified(?urn)) AS ?mtime ' + // mtime
-             this._buildTotalCounter(searchString) +
+             this._buildTotalCounter() +
              'nao:identifier(?urn) ' +
              'rdf:type(?urn) ' +
              'nie:dataSource(?urn) ' +
@@ -176,7 +176,7 @@ QueryBuilder.prototype = {
              this._buildTypeFilter('?urn') +
              'OPTIONAL { ?urn nco:creator ?creator . } ' +
              'OPTIONAL { ?urn nco:publisher ?publisher . } ' +
-             this._buildFilterString('?urn', searchString) +
+             this._buildFilterString('?urn') +
              ' } ' +
              'ORDER BY DESC (?mtime)' +
              'LIMIT %d OFFSET %d').format(Global.offsetController.getOffsetStep(),
@@ -210,6 +210,10 @@ TrackerModel.prototype = {
         this._offsetController = Global.offsetController;
         this._offsetController.connect('offset-changed',
                                        Lang.bind(this, this._performCurrentQuery));
+
+        this._filterController = Global.filterController;
+        this._filterController.connect('filter-changed',
+                                       Lang.bind(this, this._onFilterChanged));
     },
 
     _refreshMinerNow: function() {
@@ -286,7 +290,7 @@ TrackerModel.prototype = {
     },
 
     _performCurrentQuery: function() {
-        this._connection.query_async(this._builder.buildQuery(this._filter),
+        this._connection.query_async(this._builder.buildQuery(),
                                      null, Lang.bind(this, this._onQueryExecuted));
     },
 
@@ -303,13 +307,11 @@ TrackerModel.prototype = {
         this._performCurrentQuery();
     },
 
-    populateForOverview: function(filter) {
-        this._filter = filter;
+    populateForOverview: function() {
         this._refresh();
     },
 
-    setFilter: function(filter) {
-        this._filter = filter;
+    _onFilterChanged: function() {
         this._offsetController.resetOffset();
         this._refresh();
     }



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