[gnome-documents/wip/rishi/split-view: 6/11] embed, view: Move the no-results page into the ViewContainer



commit 0d68c884e9bc5d248cbf3382c2927b5f754be427
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Oct 17 15:25:30 2014 +0200

    embed, view: Move the no-results page into the ViewContainer
    
    With multiple views, it is simpler to give each view its own no-results
    page, so that they can individually react to the presence or absence
    of items.
    
    Instead of listening to TrackerChangeMonitor, we use the
    OffsetController and we reset the item count as new items are added to
    ViewModel. This is useful because each view will have its own separate
    OffsetController and ViewModel to filter the global item set, while
    TrackerChangeMonitor has no such filtering and gets bombarded with
    every change in the tracker database.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=686461

 src/embed.js |  121 -----------------------------------------------------
 src/view.js  |  131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 129 insertions(+), 123 deletions(-)
---
diff --git a/src/embed.js b/src/embed.js
index f3588de..8d95ea7 100644
--- a/src/embed.js
+++ b/src/embed.js
@@ -118,91 +118,6 @@ const ErrorBox = new Lang.Class({
     }
 });
 
-const EmptyResultsBox = new Lang.Class({
-    Name: 'EmptyResultsBox',
-
-    _init: function() {
-        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
-                                     column_spacing: 12,
-                                     hexpand: true,
-                                     vexpand: true,
-                                     halign: Gtk.Align.CENTER,
-                                     valign: Gtk.Align.CENTER });
-        this.widget.get_style_context().add_class('dim-label');
-
-        this._image = new Gtk.Image({ pixel_size: 64,
-                                      icon_name: 'emblem-documents-symbolic' });
-        this.widget.add(this._image);
-
-        this._labelsGrid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
-                                          row_spacing: 12 });
-        this.widget.add(this._labelsGrid);
-
-        let titleLabel = new Gtk.Label({ label: '<b><span size="large">' +
-                                         (Application.application.isBooks ?
-                                          _("No Books Found") :
-                                          _("No Documents Found")) +
-                                         '</span></b>',
-                                         use_markup: true,
-                                         halign: Gtk.Align.START,
-                                         vexpand: true });
-        this._labelsGrid.add(titleLabel);
-
-        if (Application.sourceManager.hasOnlineSources() ||
-            Application.application.isBooks) {
-            titleLabel.valign = Gtk.Align.CENTER;
-        } else {
-            titleLabel.valign = Gtk.Align.START;
-            this._addSystemSettingsLabel();
-        }
-
-        this.widget.show_all();
-    },
-
-    _addSystemSettingsLabel: function() {
-        let detailsStr =
-            // Translators: %s here is "Settings", which is in a separate string due to
-            // markup, and should be translated only in the context of this sentence
-            _("You can add your online accounts in %s").format(
-            " <a href=\"system-settings\">" +
-            // Translators: this should be translated in the context of the
-            // "You can add your online accounts in Settings" sentence above
-            _("Settings") +
-            "</a>");
-        let details = new Gtk.Label({ label: detailsStr,
-                                      use_markup: true,
-                                      halign: Gtk.Align.START,
-                                      xalign: 0,
-                                      max_width_chars: 24,
-                                      wrap: true });
-        this._labelsGrid.add(details);
-
-        details.connect('activate-link', Lang.bind(this,
-            function(label, uri) {
-                if (uri != 'system-settings')
-                    return false;
-
-                try {
-                    let app = Gio.AppInfo.create_from_commandline(
-                        'gnome-control-center online-accounts', null, 0);
-
-                    let screen = this.widget.get_screen();
-                    let display = screen ? screen.get_display() : Gdk.Display.get_default();
-                    let ctx = display.get_app_launch_context();
-
-                    if (screen)
-                        ctx.set_screen(screen);
-
-                    app.launch([], ctx);
-                } catch(e) {
-                    log('Unable to launch gnome-control-center: ' + e.message);
-                }
-
-                return true;
-            }));
-    }
-});
-
 const Embed = new Lang.Class({
     Name: 'Embed',
 
@@ -249,9 +164,6 @@ const Embed = new Lang.Class({
         this._errorBox = new ErrorBox();
         this._stack.add_named(this._errorBox.widget, 'error');
 
-        this._noResults = new EmptyResultsBox();
-        this._stack.add_named(this._noResults.widget, 'no-results');
-
         Application.modeController.connect('window-mode-changed',
                                            Lang.bind(this, this._onWindowModeChanged));
 
@@ -262,9 +174,6 @@ const Embed = new Lang.Class({
         Application.trackerController.connect('query-error',
                                               Lang.bind(this, this._onQueryError));
 
-        Application.offsetController.connect('item-count-changed',
-                                             Lang.bind(this, this._onItemCountChanged));
-
         Application.documentManager.connect('active-changed',
                                             Lang.bind(this, this._onActiveItemChanged));
         Application.documentManager.connect('load-started',
@@ -308,36 +217,6 @@ const Embed = new Lang.Class({
         }
     },
 
-    _hideNoResultsPage: function() {
-        if (this._noResultsChangeId != 0) {
-            Application.changeMonitor.disconnect(this._noResultsChangeId);
-            this._noResultsChangeId = 0;
-        }
-
-        this._stack.set_visible_child_name('view');
-    },
-
-    _onItemCountChanged: function() {
-        let windowMode = Application.modeController.getWindowMode();
-        if (windowMode != WindowMode.WindowMode.OVERVIEW)
-            return;
-
-        let itemCount = Application.offsetController.getItemCount();
-
-        if (itemCount == 0) {
-            // also listen to changes-pending while in this mode
-            this._noResultsChangeId =
-                Application.changeMonitor.connect('changes-pending', Lang.bind(this,
-                    function() {
-                        this._hideNoResultsPage();
-                    }));
-
-            this._stack.set_visible_child_name('no-results');
-        } else {
-            this._hideNoResultsPage();
-        }
-    },
-
     _onQueryError: function(manager, message, exception) {
         this._setError(message, exception.message);
     },
diff --git a/src/view.js b/src/view.js
index c18dfe3..b20f732 100644
--- a/src/view.js
+++ b/src/view.js
@@ -37,6 +37,8 @@ const TrackerUtils = imports.trackerUtils;
 const WindowMode = imports.windowMode;
 const Utils = imports.utils;
 
+const _RESET_COUNT_TIMEOUT = 500; // msecs
+
 const ViewModel = new Lang.Class({
     Name: 'ViewModel',
 
@@ -53,6 +55,8 @@ const ViewModel = new Lang.Class({
         this.model.set_sort_column_id(Gd.MainColumns.MTIME,
                                       Gtk.SortType.DESCENDING);
 
+        this._resetCountId = 0;
+
         Application.documentManager.connect('item-added',
             Lang.bind(this, this._onItemAdded));
         Application.documentManager.connect('item-removed',
@@ -77,6 +81,11 @@ const ViewModel = new Lang.Class({
     },
 
     _onItemAdded: function(source, doc) {
+        // Update the count so that OffsetController has the correct
+        // values. Otherwise things like loading more items and "No
+        // Results" page will not work correctly.
+        this._resetCount();
+
         let iter = this.model.append();
         this.model.set(iter,
             [ 0, 1, 2, 3, 4, 5 ],
@@ -102,6 +111,11 @@ const ViewModel = new Lang.Class({
     },
 
     _onItemRemoved: function(source, doc) {
+        // Update the count so that OffsetController has the correct
+        // values. Otherwise things like loading more items and "No
+        // Results" page will not work correctly.
+        this._resetCount();
+
         this.model.foreach(Lang.bind(this,
             function(model, path, iter) {
                 let id = model.get_value(iter, Gd.MainColumns.ID);
@@ -113,6 +127,102 @@ const ViewModel = new Lang.Class({
 
                 return false;
             }));
+    },
+
+    _resetCount: function() {
+        if (this._resetCountId == 0) {
+            this._resetCountId = Mainloop.timeout_add(_RESET_COUNT_TIMEOUT, Lang.bind(this,
+                function() {
+                    this._resetCountId = 0;
+                    Application.offsetController.resetItemCount();
+                    return false;
+                }));
+        }
+    }
+});
+
+const EmptyResultsBox = new Lang.Class({
+    Name: 'EmptyResultsBox',
+
+    _init: function() {
+        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
+                                     column_spacing: 12,
+                                     hexpand: true,
+                                     vexpand: true,
+                                     halign: Gtk.Align.CENTER,
+                                     valign: Gtk.Align.CENTER });
+        this.widget.get_style_context().add_class('dim-label');
+
+        this._image = new Gtk.Image({ pixel_size: 64,
+                                      icon_name: 'emblem-documents-symbolic' });
+        this.widget.add(this._image);
+
+        this._labelsGrid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
+                                          row_spacing: 12 });
+        this.widget.add(this._labelsGrid);
+
+        let titleLabel = new Gtk.Label({ label: '<b><span size="large">' +
+                                         (Application.application.isBooks ?
+                                          _("No Books Found") :
+                                          _("No Documents Found")) +
+                                         '</span></b>',
+                                         use_markup: true,
+                                         halign: Gtk.Align.START,
+                                         vexpand: true });
+        this._labelsGrid.add(titleLabel);
+
+        if (Application.sourceManager.hasOnlineSources() ||
+            Application.application.isBooks) {
+            titleLabel.valign = Gtk.Align.CENTER;
+        } else {
+            titleLabel.valign = Gtk.Align.START;
+            this._addSystemSettingsLabel();
+        }
+
+        this.widget.show_all();
+    },
+
+    _addSystemSettingsLabel: function() {
+        let detailsStr =
+            // Translators: %s here is "Settings", which is in a separate string due to
+            // markup, and should be translated only in the context of this sentence
+            _("You can add your online accounts in %s").format(
+            " <a href=\"system-settings\">" +
+            // Translators: this should be translated in the context of the
+            // "You can add your online accounts in Settings" sentence above
+            _("Settings") +
+            "</a>");
+        let details = new Gtk.Label({ label: detailsStr,
+                                      use_markup: true,
+                                      halign: Gtk.Align.START,
+                                      xalign: 0,
+                                      max_width_chars: 24,
+                                      wrap: true });
+        this._labelsGrid.add(details);
+
+        details.connect('activate-link', Lang.bind(this,
+            function(label, uri) {
+                if (uri != 'system-settings')
+                    return false;
+
+                try {
+                    let app = Gio.AppInfo.create_from_commandline(
+                        'gnome-control-center online-accounts', null, 0);
+
+                    let screen = this.widget.get_screen();
+                    let display = screen ? screen.get_display() : Gdk.Display.get_default();
+                    let ctx = display.get_app_launch_context();
+
+                    if (screen)
+                        ctx.set_screen(screen);
+
+                    app.launch([], ctx);
+                } catch(e) {
+                    log('Unable to launch gnome-control-center: ' + e.message);
+                }
+
+                return true;
+            }));
     }
 });
 
@@ -124,11 +234,20 @@ const ViewContainer = new Lang.Class({
 
         this._model = new ViewModel();
 
-        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+        this.widget = new Gtk.Stack({ homogeneous: true,
+                                      transition_type: Gtk.StackTransitionType.CROSSFADE });
+
+        let grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+        this.widget.add_named(grid, 'view');
+
+        this._noResults = new EmptyResultsBox();
+        this.widget.add_named(this._noResults.widget, 'no-results');
+
         this.view = new Gd.MainView({ shadow_type: Gtk.ShadowType.NONE });
-        this.widget.add(this.view);
+        grid.add(this.view);
 
         this.widget.show_all();
+        this.widget.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
 
         this.view.connect('item-activated',
                             Lang.bind(this, this._onItemActivated));
@@ -163,6 +282,14 @@ const ViewContainer = new Lang.Class({
                 this.view.unselect_all();
             }));
 
+        Application.offsetController.connect('item-count-changed', Lang.bind(this,
+            function(controller, count) {
+                if (count == 0)
+                    this.widget.set_visible_child_name('no-results');
+                else
+                    this.widget.set_visible_child_name('view');
+            }));
+
         this._queryId = Application.trackerController.connect('query-status-changed',
             Lang.bind(this, this._onQueryStatusChanged));
         // ensure the tracker controller is started


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