[gnome-documents/wip/gepub] Refactor preview code into a base class



commit 16a8a8328a8ffb919e7ec6b8629585b59cb60e91
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Sun Jun 19 17:38:24 2016 -0700

    Refactor preview code into a base class
    
    Similarly to what we did for the navigation controls, also refactor a
    base class for the preview view.

 src/embed.js      |    2 +-
 src/epubview.js   |   42 +++------------
 src/evinceview.js |  147 ++++++++++++++++++++++++++---------------------------
 src/lokview.js    |  108 +++++++++++++++++----------------------
 src/preview.js    |   57 ++++++++++++++++++++
 5 files changed, 185 insertions(+), 171 deletions(-)
---
diff --git a/src/embed.js b/src/embed.js
index 9703c18..fb5efed 100644
--- a/src/embed.js
+++ b/src/embed.js
@@ -380,8 +380,8 @@ const Embed = new Lang.Class({
                 else
                     docModel.set_sizing_mode(EvView.SizingMode.AUTOMATIC);
                 docModel.set_page_layout(EvView.PageLayout.AUTOMATIC);
-                this._toolbar.setModel(docModel);
                 this._previewEv.setModel(docModel);
+                this._toolbar.setModel(docModel);
                 this._previewEv.grab_focus();
             }
             this._stack.set_visible_child_name('preview-ev');
diff --git a/src/epubview.js b/src/epubview.js
index 3abfc93..c4502b8 100644
--- a/src/epubview.js
+++ b/src/epubview.js
@@ -29,7 +29,6 @@ const _ = imports.gettext.gettext;
 
 const Application = imports.application;
 const Documents = imports.documents;
-const ErrorBox = imports.errorBox;
 const MainToolbar = imports.mainToolbar;
 const Preview = imports.preview;
 const Searchbar = imports.searchbar;
@@ -44,19 +43,10 @@ function isEpub(mimeType) {
 
 const EPUBView = new Lang.Class({
     Name: 'EPUBView',
-    Extends: Gtk.Stack,
+    Extends: Preview.Preview,
 
     _init: function(overlay) {
-        this.parent({ homogeneous: true,
-                      transition_type: Gtk.StackTransitionType.CROSSFADE });
-
-        this._overlay = overlay;
-
-        this._errorBox = new ErrorBox.ErrorBox();
-        this.add_named(this._errorBox, 'error');
-
-        this._createView();
-        this.show_all();
+        this.parent(overlay);
 
         Application.documentManager.connect('load-started',
                                             Lang.bind(this, this._onLoadStarted));
@@ -71,6 +61,10 @@ const EPUBView = new Lang.Class({
         findNext.connect('activate',  Lang.bind(this, this._findNext));
     },
 
+    createView: function() {
+        return new Gepub.Widget();
+    },
+
     _findNext: function() {
         let fc = this.view.get_find_controller();
         fc.search_next();
@@ -84,7 +78,7 @@ const EPUBView = new Lang.Class({
     _onWindowModeChanged: function() {
         let windowMode = Application.modeController.getWindowMode();
         if (windowMode != WindowMode.WindowMode.PREVIEW_EPUB)
-            this._navControls.hide();
+            this.navControls.hide();
     },
 
     _onLoadStarted: function(manager, doc) {
@@ -103,30 +97,12 @@ const EPUBView = new Lang.Class({
         if (doc.viewType != Documents.ViewType.EPUB)
             return;
 
-        this._setError(message, exception.message);
+        this.setError(message, exception.message);
     },
 
     reset: function () {
-        if (!this.view)
-            return;
-
         this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
-        this._navControls.show();
-    },
-
-    _createView: function() {
-        this.view = new Gepub.Widget();
-
-        this.add_named(this.view, 'view');
-        this.view.show();
-
-        this._navControls = new Preview.PreviewNavControls(this, this._overlay);
-        this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
-    },
-
-    _setError: function(primary, secondary) {
-        this._errorBox.update(primary, secondary);
-        this.set_visible_child_name('error');
+        this.navControls.show();
     },
 
     goPrev: function() {
diff --git a/src/evinceview.js b/src/evinceview.js
index bbc8b07..6df1cfe 100644
--- a/src/evinceview.js
+++ b/src/evinceview.js
@@ -31,7 +31,6 @@ const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
 const Application = imports.application;
-const ErrorBox = imports.errorBox;
 const MainToolbar = imports.mainToolbar;
 const Places = imports.places;
 const Preview = imports.preview;
@@ -45,7 +44,7 @@ const _FULLSCREEN_TOOLBAR_TIMEOUT = 2; // seconds
 
 const EvinceView = new Lang.Class({
     Name: 'EvinceView',
-    Extends: Gtk.Stack,
+    Extends: Preview.Preview,
 
     _init: function(overlay) {
         this._model = null;
@@ -56,37 +55,19 @@ const EvinceView = new Lang.Class({
         this._hasSelection = false;
         this._viewSelectionChanged = false;
         this._fsToolbar = null;
-        this._overlay = overlay;
         this._lastSearch = '';
 
+        this.parent(overlay);
+
         Application.modeController.connect('fullscreen-changed', Lang.bind(this,
             this._onFullscreenChanged));
         Application.modeController.connect('window-mode-changed', Lang.bind(this,
             this._onWindowModeChanged));
 
-        this.parent({ homogeneous: true,
-                      transition_type: Gtk.StackTransitionType.CROSSFADE });
-
-        this._errorBox = new ErrorBox.ErrorBox();
-        this.add_named(this._errorBox, 'error');
-
-        this._sw = new Gtk.ScrolledWindow({ hexpand: true,
-                                            vexpand: true });
-        this._sw.get_style_context().add_class('documents-scrolledwin');
-        this._sw.get_hscrollbar().connect('button-press-event', Lang.bind(this, this._onScrollbarClick));
-        this._sw.get_vscrollbar().connect('button-press-event', Lang.bind(this, this._onScrollbarClick));
-        this._sw.get_hadjustment().connect('value-changed', Lang.bind(this, this._onAdjustmentChanged));
-        this._sw.get_vadjustment().connect('value-changed', Lang.bind(this, this._onAdjustmentChanged));
-        this.add_named(this._sw, 'view');
-
-        this._createView();
-
         // create context menu
         let model = this._getEvinceViewContextMenu();
         this._previewContextMenu = Gtk.Menu.new_from_model(model);
-        this._previewContextMenu.attach_to_widget(this._sw, null);
-
-        this.show_all();
+        this._previewContextMenu.attach_to_widget(this.view, null);
 
         this._bookmarkPage = Application.application.lookup_action('bookmark-page');
         this._bookmarkPage.enabled = false;
@@ -99,7 +80,7 @@ const EvinceView = new Lang.Class({
                 if (!this._model)
                     return;
                 this._model.set_sizing_mode(EvView.SizingMode.FREE);
-                this.view.zoom_in();
+                this._evView.zoom_in();
             }));
 
         this._zoomOut = Application.application.lookup_action('zoom-out');
@@ -108,23 +89,23 @@ const EvinceView = new Lang.Class({
                 if (!this._model)
                     return;
                 this._model.set_sizing_mode(EvView.SizingMode.FREE);
-                this.view.zoom_out();
+                this._evView.zoom_out();
             }));
 
         let findPrev = Application.application.lookup_action('find-prev');
         let findPrevId = findPrev.connect('activate', Lang.bind(this,
             function() {
-                this.view.find_previous();
+                this._evView.find_previous();
             }));
         let findNext = Application.application.lookup_action('find-next');
         let findNextId = findNext.connect('activate', Lang.bind(this,
             function() {
-                this.view.find_next();
+                this._evView.find_next();
             }));
         this._copy = Application.application.lookup_action('copy');
         let copyId = this._copy.connect('activate', Lang.bind(this,
             function() {
-                this.view.copy();
+                this._evView.copy();
             }));
 
         let rotLeft = Application.application.lookup_action('rotate-left');
@@ -172,6 +153,39 @@ const EvinceView = new Lang.Class({
             }));
     },
 
+    createNavControls: function() {
+        return new EvinceViewNavControls(this, this.overlay);
+    },
+
+    createView: function() {
+        let sw = new Gtk.ScrolledWindow({ hexpand: true,
+                                          vexpand: true });
+        sw.get_style_context().add_class('documents-scrolledwin');
+        sw.get_hscrollbar().connect('button-press-event', Lang.bind(this, this._onScrollbarClick));
+        sw.get_vscrollbar().connect('button-press-event', Lang.bind(this, this._onScrollbarClick));
+        sw.get_hadjustment().connect('value-changed', Lang.bind(this, this._onAdjustmentChanged));
+        sw.get_vadjustment().connect('value-changed', Lang.bind(this, this._onAdjustmentChanged));
+
+        this._evView = EvView.View.new();
+        sw.add(this._evView);
+        this._evView.show();
+
+        this._evView.connect('notify::can-zoom-in', Lang.bind(this,
+            this._onCanZoomInChanged));
+        this._evView.connect('notify::can-zoom-out', Lang.bind(this,
+            this._onCanZoomOutChanged));
+        this._evView.connect('button-press-event', Lang.bind(this,
+            this._onButtonPressEvent));
+        this._evView.connect('button-release-event', Lang.bind(this,
+            this._onButtonReleaseEvent));
+        this._evView.connect('selection-changed', Lang.bind(this,
+            this._onViewSelectionChanged));
+        this._evView.connect('external-link', Lang.bind(this,
+            this._handleExternalLink));
+
+        return sw;
+    },
+
     _onLoadStarted: function(manager, doc) {
         if (doc.viewType != Documents.ViewType.EV)
             return;
@@ -185,7 +199,7 @@ const EvinceView = new Lang.Class({
             return;
         this._controlsVisible = true;
         this._syncControlsVisible();
-        this._setError(message, exception.message);
+        this.setError(message, exception.message);
     },
 
     _onActionStateChanged: function(source, actionName, state) {
@@ -224,11 +238,6 @@ const EvinceView = new Lang.Class({
         this._bookmarkPage.change_state(GLib.Variant.new('b', hasBookmark));
     },
 
-    _setError: function(primary, secondary) {
-        this._errorBox.update(primary, secondary);
-        this.set_visible_child_name('error');
-    },
-
     _showPlaces: function() {
         let dialog = new Places.PlacesDialog(this._model, this._bookmarks);
         dialog.connect('response', Lang.bind(this,
@@ -272,7 +281,7 @@ const EvinceView = new Lang.Class({
     },
 
     _onViewSelectionChanged: function() {
-        let hasSelection = this.view.get_has_selection();
+        let hasSelection = this._evView.get_has_selection();
         this._copy.enabled = hasSelection;
 
         if (!hasSelection &&
@@ -344,33 +353,11 @@ const EvinceView = new Lang.Class({
     },
 
     _onCanZoomInChanged: function() {
-        this._zoomIn.enabled = this.view.can_zoom_in;
+        this._zoomIn.enabled = this._evView.can_zoom_in;
     },
 
     _onCanZoomOutChanged: function() {
-        this._zoomOut.enabled = this.view.can_zoom_out;
-    },
-
-    _createView: function() {
-        this.view = EvView.View.new();
-        this._sw.add(this.view);
-        this.view.show();
-
-        this.view.connect('notify::can-zoom-in', Lang.bind(this,
-            this._onCanZoomInChanged));
-        this.view.connect('notify::can-zoom-out', Lang.bind(this,
-            this._onCanZoomOutChanged));
-        this.view.connect('button-press-event', Lang.bind(this,
-            this._onButtonPressEvent));
-        this.view.connect('button-release-event', Lang.bind(this,
-            this._onButtonReleaseEvent));
-        this.view.connect('selection-changed', Lang.bind(this,
-            this._onViewSelectionChanged));
-        this.view.connect('external-link', Lang.bind(this,
-            this._handleExternalLink));
-
-        this._navControls = new EvinceViewNavControls(this, this._overlay);
-        this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
+        this._zoomOut.enabled = this._evView.can_zoom_out;
     },
 
     _getEvinceViewContextMenu: function() {
@@ -394,7 +381,7 @@ const EvinceView = new Lang.Class({
         if (windowMode != WindowMode.WindowMode.PREVIEW_EV) {
             this.controlsVisible = false;
             this._hidePresentation();
-            this._navControls.hide();
+            this.navControls.hide();
         }
     },
 
@@ -405,7 +392,7 @@ const EvinceView = new Lang.Class({
             // create fullscreen toolbar (hidden by default)
             this._fsToolbar = new EvinceViewFullscreenToolbar(this);
             this._fsToolbar.setModel(this._model);
-            this._overlay.add_overlay(this._fsToolbar);
+            this.overlay.add_overlay(this._fsToolbar);
 
             this._fsToolbar.connectJS('show-controls', Lang.bind(this,
                 function() {
@@ -505,7 +492,7 @@ const EvinceView = new Lang.Class({
     },
 
     activateResult: function() {
-        this.view.find_next();
+        this._evView.find_next();
     },
 
     startSearch: function(str) {
@@ -521,7 +508,7 @@ const EvinceView = new Lang.Class({
         this._lastSearch = str;
 
         if (!str) {
-            this.view.queue_draw();
+            this._evView.queue_draw();
             return;
         }
 
@@ -536,22 +523,28 @@ const EvinceView = new Lang.Class({
     _onSearchJobUpdated: function(job, page) {
         // FIXME: ev_job_find_get_results() returns a GList **
         // and thus is not introspectable
-        GdPrivate.ev_view_find_changed(this.view, job, page);
+        GdPrivate.ev_view_find_changed(this._evView, job, page);
         this.emitJS('search-changed', job.has_results());
     },
 
     reset: function() {
         this.setModel(null);
         this.view.destroy();
-        this._navControls.destroy();
-        this._createView();
+        this.navControls.destroy();
+
+        this.view = this.createView();
+        this.add_named(this.view, 'view');
+        this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
+
+        this.navControls = this.createNavControls();
+        this.show_all();
     },
 
     setModel: function(model) {
         if (this._model == model)
             return;
 
-        if (this.view) {
+        if (this._evView) {
             this.controlsVisible = false;
             this._lastSearch = '';
         }
@@ -559,9 +552,9 @@ const EvinceView = new Lang.Class({
         this._model = model;
 
         if (this._model) {
-            this.view.set_model(this._model);
-            this._navControls.setModel(model);
-            this._navControls.show();
+            this._evView.set_model(this._model);
+            this.navControls.setModel(model);
+            this.navControls.show();
             if (this._togglePresentation)
                 this._togglePresentation.enabled = true;
 
@@ -607,11 +600,11 @@ const EvinceView = new Lang.Class({
     },
 
     goPrev: function() {
-        this.view.previous_page();
+        this._evView.previous_page();
     },
 
     goNext: function() {
-        this.view.next_page();
+        this._evView.next_page();
     },
 
     get hasPages() {
@@ -624,6 +617,10 @@ const EvinceView = new Lang.Class({
 
     get numPages() {
         return this._model ? this._model.document.get_n_pages() : 0;
+    },
+
+    get evView() {
+        return this._evView;
     }
 });
 Utils.addJSSignalMethods(EvinceView.prototype);
@@ -840,7 +837,7 @@ const EvinceViewSearchbar = new Lang.Class({
     },
 
     entryChanged: function() {
-        this._previewView.view.find_search_changed();
+        this._previewView.evView.find_search_changed();
         this._previewView.startSearch(this._searchEntry.get_text());
     },
 
@@ -852,12 +849,12 @@ const EvinceViewSearchbar = new Lang.Class({
             this._searchEntry.select_region(0, -1);
         }
 
-        this._previewView.view.find_set_highlight_search(true);
+        this._previewView.evView.find_set_highlight_search(true);
         this._previewView.startSearch(this._searchEntry.get_text());
     },
 
     conceal: function() {
-        this._previewView.view.find_set_highlight_search(false);
+        this._previewView.evView.find_set_highlight_search(false);
 
         this.searchChangeBlocked = true;
         this.parent();
diff --git a/src/lokview.js b/src/lokview.js
index 85a4119..117519c 100644
--- a/src/lokview.js
+++ b/src/lokview.js
@@ -34,7 +34,6 @@ const Lang = imports.lang;
 const Signals = imports.signals;
 
 const Application = imports.application;
-const ErrorBox = imports.errorBox;
 const MainToolbar = imports.mainToolbar;
 const Preview = imports.preview;
 const Documents = imports.documents;
@@ -95,36 +94,22 @@ function isOpenDocumentFormat(mimeType) {
 
 const LOKView = new Lang.Class({
     Name: 'LOKView',
-    Extends: Gtk.Stack,
+    Extends: Preview.Preview,
 
     _init: function(overlay) {
-        this.parent({ homogeneous: true,
-                      transition_type: Gtk.StackTransitionType.CROSSFADE });
+        this.parent(overlay);
 
         this._uri = null;
-        this._overlay = overlay;
-        this.get_style_context().add_class('documents-scrolledwin');
-
-        this._errorBox = new ErrorBox.ErrorBox();
-        this.add_named(this._errorBox, 'error');
-
-        this._sw = new Gtk.ScrolledWindow({hexpand: true,
-                                           vexpand: true});
 
         this._progressBar = new Gtk.ProgressBar({ halign: Gtk.Align.FILL,
                                                   valign: Gtk.Align.START });
         this._progressBar.get_style_context().add_class('osd');
-        this._overlay.add_overlay(this._progressBar);
-
-        this.add_named(this._sw, 'view');
-        this._createView();
+        this.overlay.add_overlay(this._progressBar);
 
         // create context menu
         let model = this._getPreviewContextMenu();
         this._previewContextMenu = Gtk.Menu.new_from_model(model);
-        this._previewContextMenu.attach_to_widget(this._sw, null);
-
-        this.show_all();
+        this._previewContextMenu.attach_to_widget(this.view, null);
 
         this._zoomIn = Application.application.lookup_action('zoom-in');
         let zoomInId = this._zoomIn.connect('activate', Lang.bind(this,
@@ -132,8 +117,8 @@ const LOKView = new Lang.Class({
                 // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97301
                 if (!this._doc)
                     return;
-                let zoomLevel = this.view.get_zoom() * ZOOM_IN_FACTOR;
-                this.view.set_zoom(zoomLevel);
+                let zoomLevel = this._lokview.get_zoom() * ZOOM_IN_FACTOR;
+                this._lokview.set_zoom(zoomLevel);
             }));
 
         this._zoomOut = Application.application.lookup_action('zoom-out');
@@ -142,8 +127,8 @@ const LOKView = new Lang.Class({
                 // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97301
                 if (!this._doc)
                     return;
-                let zoomLevel = this.view.get_zoom() * ZOOM_OUT_FACTOR;
-                this.view.set_zoom(zoomLevel);
+                let zoomLevel = this._lokview.get_zoom() * ZOOM_OUT_FACTOR;
+                this._lokview.set_zoom(zoomLevel);
             }));
 
         this._copy = Application.application.lookup_action('copy');
@@ -162,16 +147,36 @@ const LOKView = new Lang.Class({
            }));
     },
 
+    createView: function() {
+        let sw = new Gtk.ScrolledWindow({ hexpand: true,
+                                          vexpand: true });
+        sw.get_style_context().add_class('documents-scrolledwin');
+
+        if (isAvailable()) {
+            this._lokview = LOKDocView.View.new(null, null, null);
+            sw.add(this._lokview);
+
+            this._lokview.show();
+            this._lokview.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
+            this._lokview.connect('load-changed', Lang.bind(this, this._onProgressChanged));
+            this._lokview.connect('text-selection', Lang.bind(this, this._onTextSelection));
+            this._lokview.connect('notify::can-zoom-in', Lang.bind(this, this._onCanZoomInChanged));
+            this._lokview.connect('notify::can-zoom-out', Lang.bind(this, this._onCanZoomOutChanged));
+        }
+
+        return sw;
+    },
+
     _onCanZoomInChanged: function() {
-        this._zoomIn.enabled = this.view.can_zoom_in;
+        this._zoomIn.enabled = this._lokview.can_zoom_in;
     },
 
     _onCanZoomOutChanged: function() {
-        this._zoomOut.enabled = this.view.can_zoom_out;
+        this._zoomOut.enabled = this._lokview.can_zoom_out;
     },
 
     _onCopyActivated: function() {
-        let [selectedText, mimeType] = this.view.copy_selection('text/plain;charset=utf-8');
+        let [selectedText, mimeType] = this._lokview.copy_selection('text/plain;charset=utf-8');
         let display = Gdk.Display.get_default();
         let clipboard = Gtk.Clipboard.get_default(display);
 
@@ -185,7 +190,7 @@ const LOKView = new Lang.Class({
             return;
         this._doc = doc;
         this._copy.enabled = false;
-        this.view.open_document(doc.uri, "{}", null, Lang.bind(this, this.open_document_cb));
+        this._lokview.open_document(doc.uri, "{}", null, Lang.bind(this, this.open_document_cb));
         this._progressBar.show();
     },
 
@@ -193,43 +198,27 @@ const LOKView = new Lang.Class({
         if (doc.viewType != Documents.ViewType.LOK)
             return;
         //FIXME we should hide controls
-        this._setError(message, exception.message);
+        this.setError(message, exception.message);
     },
 
     open_document_cb: function(res, doc) {
         // TODO: Call _finish and check failure
         this._progressBar.hide();
         this.set_visible_child_name('view');
-        this.view.set_edit(false);
+        this._lokview.set_edit(false);
     },
 
     reset: function () {
-        if (!this.view)
+        if (!this._lokview)
             return;
 
         // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97235
         if (this._doc)
-            this.view.reset_view();
+            this._lokview.reset_view();
         this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
         this._copy.enabled = false;
     },
 
-    _createView: function() {
-        if (isAvailable()) {
-            this.view = LOKDocView.View.new(null, null, null);
-            this._sw.add(this.view);
-            this.view.show();
-            this.view.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
-            this.view.connect('load-changed', Lang.bind(this, this._onProgressChanged));
-            this.view.connect('text-selection', Lang.bind(this, this._onTextSelection));
-            this.view.connect('notify::can-zoom-in', Lang.bind(this, this._onCanZoomInChanged));
-            this.view.connect('notify::can-zoom-out', Lang.bind(this, this._onCanZoomOutChanged));
-        }
-
-        this._navControls = new Preview.PreviewNavControls(this, this._overlay);
-        this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
-    },
-
     _getPreviewContextMenu: function() {
         let builder = new Gtk.Builder();
         builder.add_from_resource('/org/gnome/Documents/ui/preview-context-menu.ui');
@@ -249,37 +238,32 @@ const LOKView = new Lang.Class({
    },
 
     _onProgressChanged: function() {
-        this._progressBar.fraction = this.view.load_progress;
+        this._progressBar.fraction = this._lokview.load_progress;
     },
 
     _onTextSelection: function(hasSelection) {
         this._copy.enabled = hasSelection;
     },
 
-    _setError: function(primary, secondary) {
-        this._errorBox.update(primary, secondary);
-        this.set_visible_child_name('error');
-    },
-
     goPrev: function() {
-        let currentPart = this.view.get_part();
+        let currentPart = this._lokview.get_part();
         currentPart -= 1;
         if (currentPart < 0)
             return;
-        this.view.set_part(currentPart);
+        this._lokview.set_part(currentPart);
         // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97236
-        this.view.reset_view();
+        this._lokview.reset_view();
     },
 
     goNext: function() {
-        let totalParts  = this.view.get_parts();
-        let currentPart = this.view.get_part();
+        let totalParts  = this._lokview.get_parts();
+        let currentPart = this._lokview.get_part();
         currentPart += 1;
         if (currentPart > totalParts)
             return;
-        this.view.set_part(currentPart);
+        this._lokview.set_part(currentPart);
         // FIXME: https://bugs.documentfoundation.org/show_bug.cgi?id=97236
-        this.view.reset_view();
+        this._lokview.reset_view();
     },
 
     get hasPages() {
@@ -287,11 +271,11 @@ const LOKView = new Lang.Class({
     },
 
     get page() {
-        return this.view.get_part();
+        return this._lokview.get_part();
     },
 
     get numPages() {
-        return this.view.get_parts();
+        return this._lokview.get_parts();
     }
 });
 Signals.addSignalMethods(LOKView.prototype);
diff --git a/src/preview.js b/src/preview.js
index 3fd5553..c9b7d53 100644
--- a/src/preview.js
+++ b/src/preview.js
@@ -6,6 +6,63 @@ const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 const Tweener = imports.tweener.tweener;
 
+const ErrorBox = imports.errorBox;
+
+const Preview = new Lang.Class({
+    Name: 'Preview',
+    Extends: Gtk.Stack,
+
+    _init: function(overlay) {
+        this.overlay = overlay;
+
+        this.parent({ homogeneous: true,
+                      transition_type: Gtk.StackTransitionType.CROSSFADE });
+
+        this._errorBox = new ErrorBox.ErrorBox();
+        this.add_named(this._errorBox, 'error');
+
+        this.view = this.createView();
+        this.add_named(this.view, 'view');
+        this.set_visible_child_full('view', Gtk.StackTransitionType.NONE);
+
+        this.navControls = this.createNavControls();
+        this.show_all();
+    },
+
+    createNavControls: function() {
+        return new PreviewNavControls(this, this.overlay);
+    },
+
+    createView: function() {
+        throw(new Error('Not implemented'));
+    },
+
+    setError: function(primary, secondary) {
+        this._errorBox.update(primary, secondary);
+        this.set_visible_child_name('error');
+    },
+
+    goPrev: function() {
+        throw (new Error('Not implemented'));
+    },
+
+    goNext: function() {
+        throw (new Error('Not implemented'));
+    },
+
+    get hasPages() {
+        return false;
+    },
+
+    get page() {
+        return 0;
+    },
+
+    get numPages() {
+        return 0;
+    }
+});
+
 const _AUTO_HIDE_TIMEOUT = 2;
 const PREVIEW_NAVBAR_MARGIN = 30;
 


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