[gnome-documents] preview: implement a first iteration of an inline preview



commit 80ff9076cebdd6e05c5e9ad1609b72173ae807d5
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Jul 20 18:02:28 2011 -0400

    preview: implement a first iteration of an inline preview
    
    It's nowhere near the mockups yet, but it's good enough to show the
    concept.

 src/Makefile-js.am  |    1 +
 src/mainToolbar.js  |   46 ++++++++++++++++++++-
 src/mainWindow.js   |  112 +++++++++++++++++++++++++++++++++------------------
 src/preview.js      |   44 ++++++++++++++++++++
 src/trackerModel.js |   14 +++---
 5 files changed, 170 insertions(+), 47 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 777b243..e8a8937 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -7,6 +7,7 @@ dist_js_DATA = \
     main.js \
     mainToolbar.js \
     mainWindow.js \
+    preview.js \
     sidebar.js \
     trackerModel.js \
     utils.js \
diff --git a/src/mainToolbar.js b/src/mainToolbar.js
index 1429e9a..8e0fec5 100644
--- a/src/mainToolbar.js
+++ b/src/mainToolbar.js
@@ -22,7 +22,10 @@
 const Gio = imports.gi.Gio;
 const Gtk = imports.gi.Gtk;
 
+const _ = imports.gettext.gettext;
+
 const Lang = imports.lang;
+const Signals = imports.signals;
 
 function MainToolbar() {
     this._init();
@@ -98,10 +101,51 @@ MainToolbar.prototype = {
 
         this.widget.insert(item, 0);
         this.widget.insert(item2, 1);
+
+        this.widget.show_all();
+    },
+
+    _populateForPreview: function(model, document) {
+        let back = new Gtk.ToolButton({ icon_name: 'go-previous-symbolic' });
+        back.get_style_context().add_class('raised');
+        this.widget.insert(back, 0);
+
+        back.connect('clicked', Lang.bind(this,
+            function() {
+                this.emit('back-clicked');
+            }));
+
+        let label = new Gtk.Label();
+        let labelItem = new Gtk.ToolItem({ child: label });
+        labelItem.set_expand(true);
+        this.widget.insert(labelItem, 1);
+
+        model.connect('page-changed', Lang.bind(this,
+            function() {
+                this._updatePageLabel(label, model, document);
+            }));
+        this._updatePageLabel(label, model, document);
+
+        this.widget.show_all();
+    },
+
+    _updatePageLabel: function(label, model, document) {
+        let curPage, totPages;
+
+        curPage = model.get_page();
+        totPages = document.get_n_pages();
+
+        label.set_text(_("page %d of %d").format(curPage + 1, totPages));
     },
 
     setOverview: function() {
         this._clearToolbar();
         this._populateForOverview();
+    },
+
+    setPreview: function(model, document) {
+        this._clearToolbar();
+        this._populateForPreview(model, document);
     }
-}
+};
+Signals.addSignalMethods(MainToolbar.prototype);
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 195aa17..b4a5c13 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -19,6 +19,7 @@
  *
  */
 
+const EvView = imports.gi.EvinceView;
 const Gd = imports.gi.Gd;
 const GLib = imports.gi.GLib;
 const Gtk = imports.gi.Gtk;
@@ -32,6 +33,7 @@ const Sidebar = imports.sidebar;
 const TrackerModel = imports.trackerModel;
 const IconView = imports.iconView;
 const ListView = imports.listView;
+const Preview = imports.preview;
 
 const _ = imports.gettext.gettext;
 
@@ -65,12 +67,14 @@ MainWindow.prototype = {
         this.window.add(this._grid);
 
         this._searchTimeout = 0;
-        this.toolbar = new MainToolbar.MainToolbar();
-        this.toolbar.setOverview();
-        this.toolbar.searchEntry.connect('changed',
-                                         Lang.bind(this, this._onSearchEntryChanged));
+        this._toolbar = new MainToolbar.MainToolbar();
+        this._toolbar.setOverview();
+        this._toolbar.searchEntry.connect('changed',
+                                          Lang.bind(this, this._onSearchEntryChanged));
+        this._toolbar.connect('back-clicked',
+                              Lang.bind(this, this._onToolbarBackClicked));
 
-        this._grid.add(this.toolbar.widget);
+        this._grid.add(this._toolbar.widget);
 
         this._viewContainer = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL });
         this._grid.add(this._viewContainer);
@@ -79,21 +83,11 @@ MainWindow.prototype = {
         this._sidebar.connect('source-filter-changed', Lang.bind(this, this._onSourceFilterChanged));
         this._viewContainer.add(this._sidebar.widget);
 
-        this._scrolledWin = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER });
+        this._scrolledWin = new Gtk.ScrolledWindow({ hexpand: true,
+                                                     vexpand: true});
         this._viewContainer.add(this._scrolledWin);
 
-        this._loadMore = new Gtk.Button();
-        this._loadMore.connect('clicked', Lang.bind(this, function() {
-            this._model.loadMore();
-        }));
-
-        this._viewBox = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
-        this._viewBox.add(this._loadMore);
-
-        this._initView(this);
-
-        this._scrolledWin.add_with_viewport(this._viewBox);
-
+        this._initView();
         this._grid.show_all();
 
         this._model = new TrackerModel.TrackerModel(Lang.bind(this, this._onModelCreated));
@@ -101,9 +95,9 @@ MainWindow.prototype = {
     },
 
     _destroyView: function() {
-        if (this.view) {
-            this.view.destroy();
-        }
+        let child = this._scrolledWin.get_child();
+        if (child)
+            child.destroy();
     },
 
     _initView: function() {
@@ -111,6 +105,14 @@ MainWindow.prototype = {
 
         this._destroyView();
 
+        this._loadMore = new Gtk.Button();
+        this._loadMore.connect('clicked', Lang.bind(this, function() {
+            this._model.loadMore();
+        }));
+
+        this._viewBox = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL });
+        this._viewBox.add(this._loadMore);
+
         if (isList)
             this.view = new ListView.ListView(this);
         else
@@ -120,6 +122,10 @@ MainWindow.prototype = {
 
         this._viewBox.attach_next_to(this.view.widget, this._loadMore,
                                      Gtk.PositionType.TOP, 1, 1);
+
+        this._scrolledWin.add_with_viewport(this._viewBox);
+
+        this._viewBox.show();
     },
 
     _refreshViewSettings: function() {
@@ -127,6 +133,21 @@ MainWindow.prototype = {
         this.view.setModel(this._model.model);
     },
 
+    _updateLoadMoreButton: 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();
+    },
+
     _onModelCreated: function() {
         this.view.setModel(this._model.model);
         this._model.populateForOverview();
@@ -137,11 +158,35 @@ MainWindow.prototype = {
     },
 
     _onViewItemActivated: function(view, uri) {
-        try {
-            Gtk.show_uri(null, uri, Gtk.get_current_event_time());
-        } catch (e) {
-            log('Unable to open ' + uri + ': ' + e.toString());
-        }
+        let loader = new Gd.PdfLoader();
+        loader.connect('notify::document', Lang.bind(this, this._onDocumentLoaded));
+        loader.uri = uri;
+    },
+
+    _onDocumentLoaded: function(loader) {
+        let document = loader.document;
+        let model = EvView.DocumentModel.new_with_document(document);
+
+        this._destroyView();
+        this._sidebar.widget.hide();
+
+        this._preview = new Preview.PreviewView(model, document);
+        this._toolbar.setPreview(model, document);
+
+        this._scrolledWin.add(this._preview.widget);
+    },
+
+    _onToolbarBackClicked: function() {
+        if (this._preview)
+            this._preview.destroy();
+
+        this._sidebar.widget.show();
+        this._toolbar.setOverview();
+
+        this._refreshViewSettings();
+        // needs to be called after _refreshViewSettings(), as that
+        // recreates the button
+        this._updateLoadMoreButton(this._model.itemCount, this._model.offset);
     },
 
     _onSearchEntryChanged: function() {
@@ -157,23 +202,12 @@ MainWindow.prototype = {
     _onSearchEntryTimeout: function() {
         this._searchTimeout = 0;
 
-        let text = this.toolbar.searchEntry.get_text();
+        let text = this._toolbar.searchEntry.get_text();
         this._model.setFilter(text);
     },
 
     _onModelCountUpdated: function(model, 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();
+        this._updateLoadMoreButton(itemCount, offset);
     },
 
     _onSourceFilterChanged: function(sidebar, id) {
diff --git a/src/preview.js b/src/preview.js
new file mode 100644
index 0000000..6f68e3d
--- /dev/null
+++ b/src/preview.js
@@ -0,0 +1,44 @@
+/*
+ * 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 EvView = imports.gi.EvinceView;
+const Gtk = imports.gi.Gtk;
+
+const Lang = imports.lang;
+
+function PreviewView(model, document) {
+    this._init(model, document);
+}
+
+PreviewView.prototype = {
+    _init: function(model, document) {
+        this._model = model;
+        this._document = document;
+
+        this.widget = EvView.View.new();
+        this.widget.set_model(this._model);
+        this.widget.show();
+    },
+
+    destroy: function() {
+        this.widget.destroy();
+    }
+};
diff --git a/src/trackerModel.js b/src/trackerModel.js
index 289b5ad..624da59 100644
--- a/src/trackerModel.js
+++ b/src/trackerModel.js
@@ -303,7 +303,7 @@ TrackerModel.prototype = {
         let author = cursor.get_string(TrackerColumns.AUTHOR)[0];
         let mtime = cursor.get_string(TrackerColumns.MTIME)[0];
 
-        this._itemCount = cursor.get_integer(TrackerColumns.TOTAL_COUNT);
+        this.itemCount = cursor.get_integer(TrackerColumns.TOTAL_COUNT);
 
         if (!author)
             author = '';
@@ -364,7 +364,7 @@ TrackerModel.prototype = {
         let identifier = cursor.get_string(TrackerColumns.IDENTIFIER)[0];
         let type = cursor.get_string(TrackerColumns.TYPE)[0];
 
-        this._itemCount = cursor.get_integer(TrackerColumns.TOTAL_COUNT);
+        this.itemCount = cursor.get_integer(TrackerColumns.TOTAL_COUNT);
 
         if (!author)
             author = '';
@@ -416,31 +416,31 @@ TrackerModel.prototype = {
     },
 
     _performCurrentQuery: function() {
-        this._connection.query_async(this._builder.buildQuery(this._offset, this._filter, this._sourceId),
+        this._connection.query_async(this._builder.buildQuery(this.offset, this._filter, this._sourceId),
                                      null, Lang.bind(this, this._onQueryExecuted));
     },
 
     _emitCountUpdated: function() {
-        this.emit('count-updated', this._itemCount, this._offset);
+        this.emit('count-updated', this.itemCount, this.offset);
     },
 
     populateForOverview: function() {
         this._sourceId = 'all';
-        this._offset = 0;
+        this.offset = 0;
         this._filter = '';
 
         this._performCurrentQuery();
     },
 
     loadMore: function() {
-        this._offset += OFFSET_STEP;
+        this.offset += OFFSET_STEP;
         this._performCurrentQuery();
     },
 
     setFilter: function(filter) {
         this.model.clear();
 
-        this._offset = 0;
+        this.offset = 0;
         this._filter = filter;
 
         this._performCurrentQuery();



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