[gnome-documents] all: handle load errors in the main window



commit faa04e5e0d6f07c3f3f77d831fd7b5367f656c46
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Mon Aug 29 16:50:01 2011 -0400

    all: handle load errors in the main window
    
    Show an "error view" when something goes wrong loading the preview.
    A similar treatment will be applied to exceptions coming up from the
    tracker controller.

 src/Makefile-js.am |    2 +
 src/application.js |    2 +
 src/documents.js   |   55 ++++++++++++++++++++++----------------------
 src/error.js       |   42 ++++++++++++++++++++++++++++++++++
 src/errorBox.js    |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/global.js      |    1 +
 src/mainWindow.js  |   19 +++++++++++++--
 7 files changed, 155 insertions(+), 30 deletions(-)
---
diff --git a/src/Makefile-js.am b/src/Makefile-js.am
index 7768ad1..008038f 100644
--- a/src/Makefile-js.am
+++ b/src/Makefile-js.am
@@ -4,6 +4,8 @@ dist_js_DATA = \
     categories.js \
     changeMonitor.js \
     documents.js \
+    error.js \
+    errorBox.js \
     filterController.js \
     gDataMiner.js \
     global.js \
diff --git a/src/application.js b/src/application.js
index a81e729..0eb50dd 100644
--- a/src/application.js
+++ b/src/application.js
@@ -33,6 +33,7 @@ const Tracker = imports.gi.Tracker;
 const Categories = imports.categories;
 const ChangeMonitor = imports.changeMonitor;
 const Documents = imports.documents;
+const Error = imports.error;
 const FilterController = imports.filterController;
 const Format = imports.format;
 const Global = imports.global;
@@ -119,6 +120,7 @@ Application.prototype = {
         Global.offsetController = new OffsetController.OffsetController();
         Global.filterController = new FilterController.FilterController();
         Global.categoryManager = new Categories.CategoryManager();
+        Global.errorHandler = new Error.ErrorHandler();
 
         // connect to tracker
         Tracker.SparqlConnection.get_async(null, Lang.bind(this,
diff --git a/src/documents.js b/src/documents.js
index 259ba3b..ff446f9 100644
--- a/src/documents.js
+++ b/src/documents.js
@@ -269,17 +269,13 @@ LocalDocument.prototype = {
     loadPreview: function(cancellable, callback) {
         Gd.pdf_loader_load_uri_async(this.uri, cancellable, Lang.bind(this,
             function(source, res) {
-                let document = null;
-
                 try {
-                    document = Gd.pdf_loader_load_uri_finish(res);
+                    let document = Gd.pdf_loader_load_uri_finish(res);
+                    callback(document);
                 } catch (e) {
-                    log('Unable to load the uri ' + this.uri + ' for preview: ' + e.toString());
+                    Global.errorHandler.addLoadError(this, e);
                 }
-
-                callback(document);
             }));
-
     }
 };
 
@@ -318,34 +314,36 @@ GoogleDocument.prototype = {
              cancellable, Lang.bind(this,
                  function(object, res) {
                      let entry = null;
+                     let exception = null;
+
                      try {
                          entry = object.query_single_entry_finish(res);
                      } catch (e) {
-                         log('Unable to query the GData entry: ' + e.toString());
+                         exception = e;
                      }
-                     callback(entry, service);
+
+                     callback(entry, service, exception);
                  }));
     },
 
     loadPreview: function(cancellable, callback) {
         this._createGDataEntry(cancellable, Lang.bind(this,
-            function(entry, service) {
-                if (!entry)
-                    callback(null);
-
-                Gd.pdf_loader_load_entry_async
-                    (entry, service, cancellable, Lang.bind(this,
-                        function(source, res) {
-                            let document = null;
-
-                            try {
-                                document = Gd.pdf_loader_load_entry_finish(res);
-                            } catch (e) {
-                                log('Unable to load the GData entry: ' + e.toString());
-                            }
+            function(entry, service, exception) {
+                if (exception) {
+                    Global.errorHandler.addLoadError(this, exception);
+                    return;
+                }
 
+            Gd.pdf_loader_load_entry_async
+                (entry, service, cancellable, Lang.bind(this,
+                    function(source, res) {
+                        try {
+                            let document = Gd.pdf_loader_load_entry_finish(res);
                             callback(document);
-                        }));
+                        } catch (e) {
+                            Global.errorHandler.addLoadError(this, e);
+                        }
+                    }));
             }));
     },
 
@@ -357,10 +355,13 @@ GoogleDocument.prototype = {
 
     setFavorite: function(favorite) {
         DocCommon.prototype.setFavorite.call(this, favorite);
+
         this._createGDataEntry(null, Lang.bind(this,
-            function(entry, service) {
-                if (!entry)
+            function(entry, service, exception) {
+                if (!entry) {
+                    log('Unable to call setFavorite on ' + this.title + ': ' + exception.toString());
                     return;
+                }
 
                 let starred = null;
                 let categories = entry.get_categories();
@@ -386,7 +387,7 @@ GoogleDocument.prototype = {
                              try {
                                  service.update_entry_finish(res);
                              } catch (e) {
-                                 log('Unable to update the entry ' + e.toString());
+                                 log('Unable to call setFavorite on ' + this.title + ': ' + e.toString());
                              }
                          }));
             }));
diff --git a/src/error.js b/src/error.js
new file mode 100644
index 0000000..d7ca594
--- /dev/null
+++ b/src/error.js
@@ -0,0 +1,42 @@
+/*
+ * 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 Lang = imports.lang;
+const Signals = imports.signals;
+
+const _ = imports.gettext.gettext;
+
+function ErrorHandler() {
+    this._init();
+}
+
+ErrorHandler.prototype = {
+    _init: function() {
+    },
+
+    addLoadError: function(doc, exception) {
+        let message = _("Unable to load \"%s\" for preview").format(doc.title);
+        log('Error caught: ' + message + ' - ' + exception.toString());
+
+        this.emit('load-error', message, exception);
+    }
+};
+Signals.addSignalMethods(ErrorHandler.prototype);
diff --git a/src/errorBox.js b/src/errorBox.js
new file mode 100644
index 0000000..bfcbcfe
--- /dev/null
+++ b/src/errorBox.js
@@ -0,0 +1,64 @@
+/*
+ * 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 GLib = imports.gi.GLib;
+const Gtk = imports.gi.Gtk;
+const _ = imports.gettext.gettext;
+
+const _ICON_SIZE = 128;
+
+function ErrorBox(primary, secondary) {
+    this._init(primary, secondary);
+}
+
+ErrorBox.prototype = {
+    _init: function(primary, secondary) {
+        this.widget = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL,
+                                     column_spacing: 12,
+                                     hexpand: true,
+                                     vexpand: true,
+                                     halign: Gtk.Align.CENTER,
+                                     valign: Gtk.Align.CENTER });
+
+        this._image = new Gtk.Image({ pixel_size: _ICON_SIZE,
+                                      icon_name: 'dialog-error',
+                                      halign: Gtk.Align.CENTER,
+                                      valign: Gtk.Align.CENTER });
+
+        this.widget.add(this._image);
+
+        this._primaryLabel =
+            new Gtk.Label({ label: '<big><b>' + GLib.markup_escape_text(primary, -1) + '</b></big>',
+                            use_markup: true,
+                            halign: Gtk.Align.CENTER,
+                            valign: Gtk.Align.CENTER });
+        this.widget.add(this._primaryLabel);
+
+        this._secondaryLabel =
+            new Gtk.Label({ label: GLib.markup_escape_text(secondary, -1),
+                            use_markup: true,
+                            halign: Gtk.Align.CENTER,
+                            valign: Gtk.Align.CENTER });
+        this.widget.add(this._secondaryLabel);
+
+        this.widget.show_all();
+    }
+};
diff --git a/src/global.js b/src/global.js
index a5a2c03..90eea45 100644
--- a/src/global.js
+++ b/src/global.js
@@ -23,6 +23,7 @@ let application = null;
 let categoryManager = null;
 let connection = null;
 let documentManager = null;
+let errorHandler = null;
 let offsetController = null;
 let queryBuilder = null;
 let selectionController = null;
diff --git a/src/mainWindow.js b/src/mainWindow.js
index e4efe8e..bd464de 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -29,6 +29,7 @@ const Gtk = imports.gi.Gtk;
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 
+const ErrorBox = imports.errorBox;
 const Global = imports.global;
 const LoadMore = imports.loadMore;
 const MainToolbar = imports.mainToolbar;
@@ -69,6 +70,8 @@ MainWindow.prototype = {
 
         Global.settings.connect('changed::list-view',
                                 Lang.bind(this, this._refreshViewSettings));
+        Global.errorHandler.connect('load-error',
+                                    Lang.bind(this, this._onLoadError));
 
         this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL });
         this.window.add(this._grid);
@@ -196,6 +199,19 @@ MainWindow.prototype = {
         doc.loadPreview(this._loaderCancellable, Lang.bind(this, this._onDocumentLoaded));
     },
 
+    _onLoadError: function(manager, message, exception) {
+        if (this._loaderTimeout != 0) {
+            Mainloop.source_remove(this._loaderTimeout);
+            this._loaderTimeout = 0;
+        }
+
+        this._loaderCancellable = null;
+        this._prepareForPreview();
+
+        let errorBox = new ErrorBox.ErrorBox(message, exception.toString());
+        this._scrolledWin.add_with_viewport(errorBox.widget);
+    },
+
     _onPdfLoaderTimeout: function() {
         this._loaderTimeout = 0;
 
@@ -208,9 +224,6 @@ MainWindow.prototype = {
     },
 
     _onDocumentLoaded: function(document) {
-        if (!document)
-            return;
-
         this._loaderCancellable = null;
         let model = EvView.DocumentModel.new_with_document(document);
 



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