Blame SOURCES/gnome-documents-skydrive-printing-and-lok-fixes.patch

4f50f5
From 4ba7db7a91de431134c23bd2b43ca4e5e63e2bac Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Wed, 29 Mar 2017 16:04:08 +0200
4f50f5
Subject: [PATCH 01/16] documents: Simplify calculation of thumbnail paths for
4f50f5
 GoogleDocuments
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=780718
4f50f5
---
4f50f5
 src/documents.js | 9 ++++-----
4f50f5
 1 file changed, 4 insertions(+), 5 deletions(-)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 50cfbdafc7ee..2071882218b2 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -30,6 +30,7 @@ const GdPrivate = imports.gi.GdPrivate;
4f50f5
 const Gdk = imports.gi.Gdk;
4f50f5
 const GData = imports.gi.GData;
4f50f5
 const GLib = imports.gi.GLib;
4f50f5
+const GnomeDesktop = imports.gi.GnomeDesktop;
4f50f5
 const Gtk = imports.gi.Gtk;
4f50f5
 const Zpj = imports.gi.Zpj;
4f50f5
 const _ = imports.gettext.gettext;
4f50f5
@@ -916,12 +917,10 @@ const GoogleDocument = new Lang.Class({
4f50f5
                                                              authorization_domain: authorizationDomain,
4f50f5
                                                              download_uri: uri });
4f50f5
 
4f50f5
-                let checksum = new GLib.Checksum(GLib.ChecksumType.MD5);
4f50f5
-                checksum.update(this.uri, -1);
4f50f5
-                let dirPath = GLib.build_filenamev([GLib.get_user_cache_dir(), "thumbnails", "normal"]);
4f50f5
+                let path = GnomeDesktop.desktop_thumbnail_path_for_uri (this.uri,
4f50f5
+                                                                        GnomeDesktop.DesktopThumbnailSize.NORMAL);
4f50f5
+                let dirPath = GLib.path_get_dirname(path);
4f50f5
                 GLib.mkdir_with_parents(dirPath, 448);
4f50f5
-                let basename = checksum.get_string() + '.png';
4f50f5
-                let path = GLib.build_filenamev([dirPath, basename])
4f50f5
 
4f50f5
                 let downloadFile = Gio.File.new_for_path(path);
4f50f5
                 downloadFile.replace_async
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 7597a3e77b5c0192fc848f5fc7f65bb5b662ed20 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 30 Mar 2017 16:54:15 +0200
4f50f5
Subject: [PATCH 02/16] documents: Track nfo:fileName for later use
4f50f5
4f50f5
Now that we can open ODFs and OOXMLs in LOKDocView, we don't need to
4f50f5
convert all remote documents to PDF. For example, we can open office
4f50f5
documents stored from OneDrive without any format conversion. The
4f50f5
nfo:fileName can be used to determine the extension of the cached file.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=774937
4f50f5
---
4f50f5
 src/documents.js | 7 ++++---
4f50f5
 1 file changed, 4 insertions(+), 3 deletions(-)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 2071882218b2..6ecc255c9407 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -229,6 +229,7 @@ const DocCommon = new Lang.Class({
4f50f5
     _init: function(cursor) {
4f50f5
         this.id = null;
4f50f5
         this.uri = null;
4f50f5
+        this.filename = null;
4f50f5
         this.name = null;
4f50f5
         this.author = null;
4f50f5
         this.mtime = null;
4f50f5
@@ -306,12 +307,12 @@ const DocCommon = new Lang.Class({
4f50f5
             this.uri = '';
4f50f5
 
4f50f5
         let title = cursor.get_string(Query.QueryColumns.TITLE)[0];
4f50f5
-        let filename = cursor.get_string(Query.QueryColumns.FILENAME)[0];
4f50f5
+        this.filename = cursor.get_string(Query.QueryColumns.FILENAME)[0];
4f50f5
 
4f50f5
         if (title && title != '')
4f50f5
             this.name = title;
4f50f5
-        else if (filename)
4f50f5
-            this.name = GdPrivate.filename_strip_extension(filename);
4f50f5
+        else if (this.filename)
4f50f5
+            this.name = GdPrivate.filename_strip_extension(this.filename);
4f50f5
         else
4f50f5
             this.name = '';
4f50f5
 
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 291a12b177411b960c91413a51f05493daf98bd1 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 30 Mar 2017 17:25:44 +0200
4f50f5
Subject: [PATCH 03/16] documents: Add property to denote the URI to be loaded
4f50f5
 by the preview
4f50f5
4f50f5
We want to open ODFs and OOXMLs from OneDrive using LOKDocView, not
4f50f5
EvView. Therefore, the logic to convert a remote document into
4f50f5
something that can be loaded by the different preview widgets can no
4f50f5
longer be hidden inside GdPdfLoader. LOKDocView needs to know the URI
4f50f5
it can load without hitting the network.
4f50f5
4f50f5
For local and ownCloud this is the same as the actual URI because they
4f50f5
are natively handled by GIO. The property is not defined for Google
4f50f5
because it is still handled entirely by GdPdfLoader.
4f50f5
4f50f5
This changes the caching for SkydriveDocuments. The old scheme was:
4f50f5
  ~/.cache/gnome-documents/gnome-documents-<g_str_hash(id)>.pdf
4f50f5
The new structure is:
4f50f5
  ~/.cache/gnome-documents/skydrive/<SHA1(id)>.<original-extension>
4f50f5
4f50f5
The new scheme namespaces each document type and uses a hash function
4f50f5
that can be easily replicated by other tools for debugging. This is a
4f50f5
good time to change this because we are about to invalidate existing
4f50f5
caches by not using the ".pdf" extension for all SkydriveDocuments.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=774937
4f50f5
---
4f50f5
 src/documents.js | 24 +++++++++++++++++++++++-
4f50f5
 src/epubview.js  |  2 +-
4f50f5
 src/lokview.js   |  2 +-
4f50f5
 3 files changed, 25 insertions(+), 3 deletions(-)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 6ecc255c9407..c50d50078f2f 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -229,6 +229,7 @@ const DocCommon = new Lang.Class({
4f50f5
     _init: function(cursor) {
4f50f5
         this.id = null;
4f50f5
         this.uri = null;
4f50f5
+        this.uriToLoad = null;
4f50f5
         this.filename = null;
4f50f5
         this.name = null;
4f50f5
         this.author = null;
4f50f5
@@ -618,7 +619,7 @@ const DocCommon = new Lang.Class({
4f50f5
             return;
4f50f5
         }
4f50f5
 
4f50f5
-        GdPrivate.pdf_loader_load_uri_async(this.uri, passwd, cancellable, Lang.bind(this,
4f50f5
+        GdPrivate.pdf_loader_load_uri_async(this.uriToLoad, passwd, cancellable, Lang.bind(this,
4f50f5
             function(source, res) {
4f50f5
                 try {
4f50f5
                     let docModel = GdPrivate.pdf_loader_load_uri_finish(res);
4f50f5
@@ -749,6 +750,7 @@ const LocalDocument = new Lang.Class({
4f50f5
 
4f50f5
     populateFromCursor: function(cursor) {
4f50f5
         this.parent(cursor);
4f50f5
+        this.uriToLoad = this.uri;
4f50f5
 
4f50f5
         if (!Application.application.gettingStartedLocation)
4f50f5
             return;
4f50f5
@@ -1013,6 +1015,11 @@ const OwncloudDocument = new Lang.Class({
4f50f5
             this.defaultAppName = this.defaultApp.get_name();
4f50f5
     },
4f50f5
 
4f50f5
+    populateFromCursor: function(cursor) {
4f50f5
+        this.parent(cursor);
4f50f5
+        this.uriToLoad = this.uri;
4f50f5
+    },
4f50f5
+
4f50f5
     createThumbnail: function(callback) {
4f50f5
         GdPrivate.queue_thumbnail_job_for_file_async(this._file, Lang.bind(this,
4f50f5
             function(object, res) {
4f50f5
@@ -1071,6 +1078,21 @@ const SkydriveDocument = new Lang.Class({
4f50f5
         this.sourceName = _("OneDrive");
4f50f5
     },
4f50f5
 
4f50f5
+    populateFromCursor: function(cursor) {
4f50f5
+        this.parent(cursor);
4f50f5
+
4f50f5
+        let localDir = GLib.build_filenamev([GLib.get_user_cache_dir(), "gnome-documents", "skydrive"]);
4f50f5
+
4f50f5
+        let identifierHash = GLib.compute_checksum_for_string(GLib.ChecksumType.SHA1, this.identifier, -1);
4f50f5
+        let filenameStripped = GdPrivate.filename_strip_extension(this.filename);
4f50f5
+        let extension = this.filename.substring(filenameStripped.length);
4f50f5
+        let localFilename = identifierHash + extension;
4f50f5
+
4f50f5
+        let localPath = GLib.build_filenamev([localDir, localFilename]);
4f50f5
+        let localFile = Gio.File.new_for_path(localPath);
4f50f5
+        this.uriToLoad = localFile.get_uri();
4f50f5
+    },
4f50f5
+
4f50f5
     _createZpjEntry: function(cancellable, callback) {
4f50f5
         let source = Application.sourceManager.getItemById(this.resourceUrn);
4f50f5
 
4f50f5
diff --git a/src/epubview.js b/src/epubview.js
4f50f5
index 923b0aa265ab..12f392225d6f 100644
4f50f5
--- a/src/epubview.js
4f50f5
+++ b/src/epubview.js
4f50f5
@@ -65,7 +65,7 @@ const EPUBView = new Lang.Class({
4f50f5
     onLoadFinished: function(manager, doc) {
4f50f5
         this.parent(manager, doc);
4f50f5
 
4f50f5
-        let f = Gio.File.new_for_uri(doc.uri);
4f50f5
+        let f = Gio.File.new_for_uri(doc.uriToLoad);
4f50f5
         this._epubdoc = new Gepub.Doc({ path: f.get_path() });
4f50f5
         this._epubdoc.init(null);
4f50f5
 
4f50f5
diff --git a/src/lokview.js b/src/lokview.js
4f50f5
index 092adc5a0471..988db963d5d9 100644
4f50f5
--- a/src/lokview.js
4f50f5
+++ b/src/lokview.js
4f50f5
@@ -148,7 +148,7 @@ const LOKView = new Lang.Class({
4f50f5
         if (!isAvailable())
4f50f5
             return;
4f50f5
         this._doc = doc;
4f50f5
-        this._lokview.open_document(doc.uri, '{}', null, Lang.bind(this, this._onDocumentOpened));
4f50f5
+        this._lokview.open_document(doc.uriToLoad, '{}', null, Lang.bind(this, this._onDocumentOpened));
4f50f5
         this._progressBar.show();
4f50f5
     },
4f50f5
 
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 0ea69b0519a4e374feabc1923c82e1e0c71d5914 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 30 Mar 2017 18:18:16 +0200
4f50f5
Subject: [PATCH 04/16] documents: Let everybody provide their own download
4f50f5
 implementation
4f50f5
4f50f5
This is meant to reduce our reliance on GdPdfLoader for loading remote
4f50f5
documents. We can open ODFs and OOXMLs in LOKDocView, so we don't need
4f50f5
to convert everything to PDFs. In the future, remote sub-classes will
4f50f5
provider their own implementation to download a document, and this will
4f50f5
help unify the loading across the various sub-classes.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=774937
4f50f5
---
4f50f5
 src/documents.js | 42 ++++++++++++++++++++++++++++++++++++++++++
4f50f5
 1 file changed, 42 insertions(+)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index c50d50078f2f..9028e9b5084f 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -360,6 +360,48 @@ const DocCommon = new Lang.Class({
4f50f5
         }
4f50f5
     },
4f50f5
 
4f50f5
+    download: function(useCache, cancellable, callback) {
4f50f5
+        let localFile = Gio.File.new_for_uri(this.uriToLoad);
4f50f5
+        let localPath = localFile.get_path();
4f50f5
+        let localDir = GLib.path_get_dirname(localPath);
4f50f5
+        GLib.mkdir_with_parents(localDir, 448);
4f50f5
+
4f50f5
+        if (!useCache) {
4f50f5
+            this.downloadImpl(localFile, cancellable, callback);
4f50f5
+            return;
4f50f5
+        }
4f50f5
+
4f50f5
+        localFile.query_info_async(Gio.FILE_ATTRIBUTE_TIME_MODIFIED,
4f50f5
+                                   Gio.FileQueryInfoFlags.NONE,
4f50f5
+                                   GLib.PRIORITY_DEFAULT,
4f50f5
+                                   cancellable,
4f50f5
+                                   Lang.bind(this,
4f50f5
+            function(object, res) {
4f50f5
+                let info;
4f50f5
+
4f50f5
+                try {
4f50f5
+                    info = object.query_info_finish(res);
4f50f5
+                } catch (e) {
4f50f5
+                    this.downloadImpl(localFile, cancellable, callback);
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                let cacheMtime = info.get_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_MODIFIED);
4f50f5
+                cacheMtime /= 1000000;
4f50f5
+
4f50f5
+                if (this.mtime <= cacheMtime) {
4f50f5
+                    callback(true, null);
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                this.downloadImpl(localFile, cancellable, callback);
4f50f5
+            }));
4f50f5
+    },
4f50f5
+
4f50f5
+    downloadImpl: function(localFile, cancellable, callback) {
4f50f5
+        throw(new Error('DocCommon implementations must override downloadImpl'));
4f50f5
+    },
4f50f5
+
4f50f5
     load: function() {
4f50f5
         log('Error: DocCommon implementations must override load');
4f50f5
     },
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 630fc1a93bbd3a93ee242231a6a1129aef924127 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 30 Mar 2017 18:23:27 +0200
4f50f5
Subject: [PATCH 05/16] documents: Implement the downloadImpl vfunc for
4f50f5
 SkydriveDocument
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=774937
4f50f5
---
4f50f5
 src/documents.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4f50f5
 1 file changed, 56 insertions(+)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 9028e9b5084f..781019091754 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -1161,6 +1161,62 @@ const SkydriveDocument = new Lang.Class({
4f50f5
                  }));
4f50f5
     },
4f50f5
 
4f50f5
+    downloadImpl: function(localFile, cancellable, callback) {
4f50f5
+        this._createZpjEntry(cancellable, Lang.bind(this,
4f50f5
+            function(entry, service, error) {
4f50f5
+                if (error) {
4f50f5
+                    callback(false, error);
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                service.download_file_to_stream_async(entry, cancellable, Lang.bind(this,
4f50f5
+                    function(object, res) {
4f50f5
+                        let inputStream;
4f50f5
+
4f50f5
+                        try {
4f50f5
+                            inputStream = object.download_file_to_stream_finish(res);
4f50f5
+                        } catch (e) {
4f50f5
+                            callback(false, e);
4f50f5
+                            return;
4f50f5
+                        }
4f50f5
+
4f50f5
+                        localFile.replace_async(null,
4f50f5
+                                                false,
4f50f5
+                                                Gio.FileCreateFlags.PRIVATE,
4f50f5
+                                                GLib.PRIORITY_DEFAULT,
4f50f5
+                                                cancellable,
4f50f5
+                                                Lang.bind(this,
4f50f5
+                            function(object, res) {
4f50f5
+                                let outputStream;
4f50f5
+
4f50f5
+                                try {
4f50f5
+                                    outputStream = object.replace_finish(res);
4f50f5
+                                } catch (e) {
4f50f5
+                                    callback(false, e);
4f50f5
+                                    return;
4f50f5
+                                }
4f50f5
+
4f50f5
+                                outputStream.splice_async(inputStream,
4f50f5
+                                                          Gio.OutputStreamSpliceFlags.CLOSE_SOURCE |
4f50f5
+                                                          Gio.OutputStreamSpliceFlags.CLOSE_TARGET,
4f50f5
+                                                          GLib.PRIORITY_DEFAULT,
4f50f5
+                                                          cancellable,
4f50f5
+                                                          Lang.bind(this,
4f50f5
+                                    function(object, res) {
4f50f5
+                                        try {
4f50f5
+                                            object.splice_finish(res);
4f50f5
+                                        } catch (e) {
4f50f5
+                                            callback(false, e);
4f50f5
+                                            return;
4f50f5
+                                        }
4f50f5
+
4f50f5
+                                        callback(false, null);
4f50f5
+                                    }));
4f50f5
+                            }));
4f50f5
+                    }));
4f50f5
+            }));
4f50f5
+    },
4f50f5
+
4f50f5
     load: function(passwd, cancellable, callback) {
4f50f5
         this._createZpjEntry(cancellable, Lang.bind(this,
4f50f5
             function(entry, service, exception) {
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From c21f27f63ec2cf31c254896ad8343689b9cc9499 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 30 Mar 2017 18:31:18 +0200
4f50f5
Subject: [PATCH 06/16] documents, pdf-loader: Fix previewing of ODFs and
4f50f5
 OOXMLs on OneDrive
4f50f5
4f50f5
OneDrive documents were being converted to PDFs via GdPdfLoader, but
4f50f5
LOKDocView was being used instead of EvView to render them. LOKDocView
4f50f5
uses the document's URI property, and in this case it is not a valid
4f50f5
URI that it can use. As a result the preview would fail and sometimes
4f50f5
crash the application.
4f50f5
4f50f5
Solve all that by removing the PDF conversion, and passing the correct
4f50f5
URI to LOKDocView.
4f50f5
4f50f5
This effectively reverts 0bfb23786dc84d390c4bd6bde5f20987874e1e9b
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=774937
4f50f5
---
4f50f5
 configure.ac            |   4 +-
4f50f5
 src/documents.js        |  50 ++++++------
4f50f5
 src/lib/gd-pdf-loader.c | 205 +-----------------------------------------------
4f50f5
 src/lib/gd-pdf-loader.h |   9 ---
4f50f5
 4 files changed, 29 insertions(+), 239 deletions(-)
4f50f5
4f50f5
diff --git a/configure.ac b/configure.ac
4f50f5
index 78cda4f799d5..8098515028d1 100644
4f50f5
--- a/configure.ac
4f50f5
+++ b/configure.ac
4f50f5
@@ -57,7 +57,6 @@ GOBJECT_INTROSPECTION_MIN_VERSION=1.31.6
4f50f5
 GDATA_MIN_VERSION=0.13.3
4f50f5
 GOA_MIN_VERSION=3.2.0
4f50f5
 TRACKER_MIN_VERSION=0.17.3
4f50f5
-ZAPOJIT_MIN_VERSION=0.0.2
4f50f5
 SOUP_MIN_VERSION=2.41.3
4f50f5
 
4f50f5
 AC_ARG_ENABLE(documentation,
4f50f5
@@ -85,8 +84,7 @@ PKG_CHECK_MODULES(DOCUMENTS,
4f50f5
                   tracker-control-1.0 >= $TRACKER_MIN_VERSION
4f50f5
                   tracker-sparql-1.0 >= $TRACKER_MIN_VERSION
4f50f5
                   goa-1.0 >= $GOA_MIN_VERSION
4f50f5
-                  libgdata >= $GDATA_MIN_VERSION
4f50f5
-                  zapojit-0.0 >= $ZAPOJIT_MIN_VERSION)
4f50f5
+                  libgdata >= $GDATA_MIN_VERSION)
4f50f5
 
4f50f5
 # Although GTK+ 3.10 includes hi-dpi functionality, it does not require a cairo with
4f50f5
 # cairo_surface_set_device_scale(), which we also need if we're to support hi-dpi,
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 781019091754..ca48e53db25d 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -1218,34 +1218,36 @@ const SkydriveDocument = new Lang.Class({
4f50f5
     },
4f50f5
 
4f50f5
     load: function(passwd, cancellable, callback) {
4f50f5
-        this._createZpjEntry(cancellable, Lang.bind(this,
4f50f5
-            function(entry, service, exception) {
4f50f5
-                if (exception) {
4f50f5
-                    // try loading from the most recent cache, if any
4f50f5
-                    GdPrivate.pdf_loader_load_uri_async(this.identifier, passwd, cancellable, Lang.bind(this,
4f50f5
-                        function(source, res) {
4f50f5
-                            try {
4f50f5
-                                let docModel = GdPrivate.pdf_loader_load_uri_finish(res);
4f50f5
-                                callback(this, docModel, null);
4f50f5
-                            } catch (e) {
4f50f5
-                                // report the outmost error only
4f50f5
-                                callback(this, null, exception);
4f50f5
-                            }
4f50f5
-                        }));
4f50f5
-
4f50f5
+        this.download(true, cancellable, Lang.bind(this,
4f50f5
+            function(fromCache, error) {
4f50f5
+                if (error) {
4f50f5
+                    callback(this, null, error);
4f50f5
                     return;
4f50f5
                 }
4f50f5
 
4f50f5
-                GdPrivate.pdf_loader_load_zpj_entry_async
4f50f5
-                    (entry, service, cancellable, Lang.bind(this,
4f50f5
-                        function(source, res) {
4f50f5
-                            try {
4f50f5
-                                let docModel = GdPrivate.pdf_loader_load_zpj_entry_finish(res);
4f50f5
-                                callback(this, docModel, null);
4f50f5
-                            } catch (e) {
4f50f5
-                                callback(this, null, e);
4f50f5
+                this.loadLocal(passwd, cancellable, Lang.bind(this,
4f50f5
+                    function(doc, docModel, error) {
4f50f5
+                        if (error) {
4f50f5
+                            if (fromCache &&
4f50f5
+                                !error.matches(EvDocument.DocumentError, EvDocument.DocumentError.ENCRYPTED)) {
4f50f5
+                                this.download(false, cancellable, Lang.bind(this,
4f50f5
+                                    function(fromCache, error) {
4f50f5
+                                        if (error) {
4f50f5
+                                            callback(this, null, error);
4f50f5
+                                            return;
4f50f5
+                                        }
4f50f5
+
4f50f5
+                                        this.loadLocal(passwd, cancellable, callback);
4f50f5
+                                    }));
4f50f5
+                            } else {
4f50f5
+                                callback(this, null, error);
4f50f5
                             }
4f50f5
-                        }));
4f50f5
+
4f50f5
+                            return;
4f50f5
+                        }
4f50f5
+
4f50f5
+                        callback(this, docModel, null);
4f50f5
+                    }));
4f50f5
             }));
4f50f5
     },
4f50f5
 
4f50f5
diff --git a/src/lib/gd-pdf-loader.c b/src/lib/gd-pdf-loader.c
4f50f5
index 7a8890e75891..202f6cc0a65f 100644
4f50f5
--- a/src/lib/gd-pdf-loader.c
4f50f5
+++ b/src/lib/gd-pdf-loader.c
4f50f5
@@ -51,9 +51,6 @@ typedef struct {
4f50f5
   GDataService *gdata_service;
4f50f5
   gchar *resource_id;
4f50f5
 
4f50f5
-  ZpjSkydriveEntry *zpj_entry;
4f50f5
-  ZpjSkydrive *zpj_service;
4f50f5
-
4f50f5
   guint64 pdf_cache_mtime;
4f50f5
   guint64 original_file_mtime;
4f50f5
 
4f50f5
@@ -64,7 +61,6 @@ typedef struct {
4f50f5
 static void pdf_load_job_from_openoffice (PdfLoadJob *job);
4f50f5
 static void pdf_load_job_gdata_refresh_cache (PdfLoadJob *job);
4f50f5
 static void pdf_load_job_openoffice_refresh_cache (PdfLoadJob *job);
4f50f5
-static void pdf_load_job_zpj_refresh_cache (PdfLoadJob *job);
4f50f5
 
4f50f5
 /* --------------------------- utils -------------------------------- */
4f50f5
 
4f50f5
@@ -134,8 +130,6 @@ pdf_load_job_free (PdfLoadJob *job)
4f50f5
   g_clear_object (&job->download_file);
4f50f5
   g_clear_object (&job->gdata_service);
4f50f5
   g_clear_object (&job->gdata_entry);
4f50f5
-  g_clear_object (&job->zpj_service);
4f50f5
-  g_clear_object (&job->zpj_entry);
4f50f5
 
4f50f5
   g_free (job->uri);
4f50f5
   g_free (job->passwd);
4f50f5
@@ -160,7 +154,6 @@ static PdfLoadJob *
4f50f5
 pdf_load_job_new (GSimpleAsyncResult *result,
4f50f5
                   const gchar *uri,
4f50f5
                   GDataEntry *gdata_entry,
4f50f5
-                  ZpjSkydriveEntry *zpj_entry,
4f50f5
                   const gchar *passwd,
4f50f5
                   GCancellable *cancellable)
4f50f5
 {
4f50f5
@@ -178,8 +171,6 @@ pdf_load_job_new (GSimpleAsyncResult *result,
4f50f5
     retval->passwd = g_strdup (passwd);
4f50f5
   if (gdata_entry != NULL)
4f50f5
     retval->gdata_entry = g_object_ref (gdata_entry);
4f50f5
-  if (zpj_entry != NULL)
4f50f5
-    retval->zpj_entry = g_object_ref (zpj_entry);
4f50f5
   if (cancellable != NULL)
4f50f5
     retval->cancellable = g_object_ref (cancellable);
4f50f5
 
4f50f5
@@ -216,8 +207,6 @@ pdf_load_job_force_refresh_cache (PdfLoadJob *job)
4f50f5
 
4f50f5
   if (job->gdata_entry != NULL)
4f50f5
     pdf_load_job_gdata_refresh_cache (job);
4f50f5
-  if (job->zpj_entry != NULL)
4f50f5
-    pdf_load_job_zpj_refresh_cache (job);
4f50f5
   else
4f50f5
     pdf_load_job_openoffice_refresh_cache (job);
4f50f5
 }
4f50f5
@@ -429,61 +418,6 @@ pdf_load_job_gdata_refresh_cache (PdfLoadJob *job)
4f50f5
 }
4f50f5
 
4f50f5
 static void
4f50f5
-zpj_download_stream_ready (GObject *source,
4f50f5
-                       GAsyncResult *res,
4f50f5
-                       gpointer user_data)
4f50f5
-{
4f50f5
-  GError *error = NULL;
4f50f5
-  PdfLoadJob *job = (PdfLoadJob *) user_data;
4f50f5
-  const gchar *name;
4f50f5
-  const gchar *extension;
4f50f5
-
4f50f5
-  job->stream = zpj_skydrive_download_file_to_stream_finish (ZPJ_SKYDRIVE (source), res, &error);
4f50f5
-  if (error != NULL) {
4f50f5
-    pdf_load_job_complete_error (job, error);
4f50f5
-    return;
4f50f5
-  }
4f50f5
-
4f50f5
-  name = zpj_skydrive_entry_get_name (job->zpj_entry);
4f50f5
-  extension = gd_filename_get_extension_offset (name);
4f50f5
-
4f50f5
-  /* If it is not a PDF, we need to convert it afterwards.
4f50f5
-   * http://msdn.microsoft.com/en-us/library/live/hh826545#fileformats
4f50f5
-   */
4f50f5
-  if (g_strcmp0 (extension, ".pdf") != 0)
4f50f5
-    {
4f50f5
-      GFileIOStream *iostream;
4f50f5
-
4f50f5
-      job->download_file = g_file_new_tmp (NULL, &iostream, &error);
4f50f5
-      if (error != NULL) {
4f50f5
-        pdf_load_job_complete_error (job, error);
4f50f5
-        return;
4f50f5
-      }
4f50f5
-
4f50f5
-      /* We don't need the iostream. */
4f50f5
-      g_io_stream_close (G_IO_STREAM (iostream), NULL, NULL);
4f50f5
-    }
4f50f5
-  else
4f50f5
-    job->download_file = g_file_new_for_path (job->pdf_path);
4f50f5
-
4f50f5
-  g_file_replace_async (job->download_file, NULL, FALSE,
4f50f5
-                        G_FILE_CREATE_PRIVATE,
4f50f5
-                        G_PRIORITY_DEFAULT,
4f50f5
-                        job->cancellable, file_replace_ready_cb,
4f50f5
-                        job);
4f50f5
-}
4f50f5
-
4f50f5
-static void
4f50f5
-pdf_load_job_zpj_refresh_cache (PdfLoadJob *job)
4f50f5
-{
4f50f5
-  zpj_skydrive_download_file_to_stream_async (job->zpj_service,
4f50f5
-                                              ZPJ_SKYDRIVE_FILE (job->zpj_entry),
4f50f5
-                                              job->cancellable,
4f50f5
-                                              zpj_download_stream_ready,
4f50f5
-                                              job);
4f50f5
-}
4f50f5
-
4f50f5
-static void
4f50f5
 gdata_cache_query_info_ready_cb (GObject *source,
4f50f5
                                  GAsyncResult *res,
4f50f5
                                  gpointer user_data)
4f50f5
@@ -518,40 +452,6 @@ gdata_cache_query_info_ready_cb (GObject *source,
4f50f5
 }
4f50f5
 
4f50f5
 static void
4f50f5
-zpj_cache_query_info_ready_cb (GObject *source,
4f50f5
-                               GAsyncResult *res,
4f50f5
-                               gpointer user_data)
4f50f5
-{
4f50f5
-  PdfLoadJob *job = user_data;
4f50f5
-  GError *error = NULL;
4f50f5
-  GFileInfo *info;
4f50f5
-  guint64 cache_mtime;
4f50f5
-
4f50f5
-  info = g_file_query_info_finish (G_FILE (source), res, &error);
4f50f5
-
4f50f5
-  if (error != NULL) {
4f50f5
-    /* create/invalidate cache */
4f50f5
-    pdf_load_job_zpj_refresh_cache (job);
4f50f5
-    g_error_free (error);
4f50f5
-
4f50f5
-    return;
4f50f5
-  }
4f50f5
-
4f50f5
-  job->pdf_cache_mtime = cache_mtime =
4f50f5
-    g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
4f50f5
-  g_object_unref (info);
4f50f5
-
4f50f5
-  if (job->original_file_mtime != cache_mtime) {
4f50f5
-    pdf_load_job_zpj_refresh_cache (job);
4f50f5
-  } else {
4f50f5
-    job->from_old_cache = TRUE;
4f50f5
-
4f50f5
-    /* load the cached file */
4f50f5
-    pdf_load_job_from_pdf (job);
4f50f5
-  }
4f50f5
-}
4f50f5
-
4f50f5
-static void
4f50f5
 pdf_load_job_from_google_documents (PdfLoadJob *job)
4f50f5
 {
4f50f5
   gchar *tmp_name;
4f50f5
@@ -583,39 +483,6 @@ pdf_load_job_from_google_documents (PdfLoadJob *job)
4f50f5
 }
4f50f5
 
4f50f5
 static void
4f50f5
-pdf_load_job_from_skydrive (PdfLoadJob *job)
4f50f5
-{
4f50f5
-  gchar *tmp_name;
4f50f5
-  gchar *tmp_path, *pdf_path;
4f50f5
-  GDateTime *updated_time;
4f50f5
-  GFile *pdf_file;
4f50f5
-
4f50f5
-  updated_time = zpj_skydrive_entry_get_updated_time (job->zpj_entry);
4f50f5
-  job->original_file_mtime = (guint64) g_date_time_to_unix (updated_time);
4f50f5
-
4f50f5
-  tmp_name = g_strdup_printf ("gnome-documents-%u.pdf",
4f50f5
-                              g_str_hash (zpj_skydrive_entry_get_id (job->zpj_entry)));
4f50f5
-  tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL);
4f50f5
-  job->pdf_path = pdf_path =
4f50f5
-    g_build_filename (tmp_path, tmp_name, NULL);
4f50f5
-  g_mkdir_with_parents (tmp_path, 0700);
4f50f5
-
4f50f5
-  pdf_file = g_file_new_for_path (pdf_path);
4f50f5
-
4f50f5
-  g_file_query_info_async (pdf_file,
4f50f5
-                           G_FILE_ATTRIBUTE_TIME_MODIFIED,
4f50f5
-                           G_FILE_QUERY_INFO_NONE,
4f50f5
-                           G_PRIORITY_DEFAULT,
4f50f5
-                           job->cancellable,
4f50f5
-                           zpj_cache_query_info_ready_cb,
4f50f5
-                           job);
4f50f5
-
4f50f5
-  g_free (tmp_name);
4f50f5
-  g_free (tmp_path);
4f50f5
-  g_object_unref (pdf_file);
4f50f5
-}
4f50f5
-
4f50f5
-static void
4f50f5
 pdf_load_job_from_gdata_cache (PdfLoadJob *job)
4f50f5
 {
4f50f5
   gchar *tmp_name;
4f50f5
@@ -633,23 +500,6 @@ pdf_load_job_from_gdata_cache (PdfLoadJob *job)
4f50f5
 }
4f50f5
 
4f50f5
 static void
4f50f5
-pdf_load_job_from_zpj_cache (PdfLoadJob *job)
4f50f5
-{
4f50f5
-  gchar *tmp_name;
4f50f5
-  gchar *tmp_path;
4f50f5
-
4f50f5
-  tmp_name = g_strdup_printf ("gnome-documents-%u.pdf",
4f50f5
-                              g_str_hash (job->resource_id));
4f50f5
-  tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL);
4f50f5
-  job->pdf_path = g_build_filename (tmp_path, tmp_name, NULL);
4f50f5
-
4f50f5
-  pdf_load_job_from_pdf (job);
4f50f5
-
4f50f5
-  g_free (tmp_path);
4f50f5
-  g_free (tmp_name);
4f50f5
-}
4f50f5
-
4f50f5
-static void
4f50f5
 unoconv_cancelled_cb (GCancellable *cancellable,
4f50f5
                       gpointer user_data)
4f50f5
 {
4f50f5
@@ -1134,7 +984,6 @@ pdf_load_job_from_uri (PdfLoadJob *job)
4f50f5
 {
4f50f5
   GFile *file;
4f50f5
   const gchar *gdata_prefix = "google:drive:";
4f50f5
-  const gchar *zpj_prefix = "windows-live:skydrive:";
4f50f5
 
4f50f5
   if (g_str_has_prefix (job->uri, gdata_prefix)) {
4f50f5
     job->resource_id = g_strdup (job->uri + strlen (gdata_prefix));
4f50f5
@@ -1142,12 +991,6 @@ pdf_load_job_from_uri (PdfLoadJob *job)
4f50f5
     return;
4f50f5
   }
4f50f5
 
4f50f5
-  if (g_str_has_prefix (job->uri, zpj_prefix)) {
4f50f5
-    job->resource_id = g_strdup (job->uri + strlen (zpj_prefix));
4f50f5
-    pdf_load_job_from_zpj_cache (job);
4f50f5
-    return;
4f50f5
-  }
4f50f5
-
4f50f5
   file = g_file_new_for_uri (job->uri);
4f50f5
   if (!g_file_is_native (file))
4f50f5
     pdf_load_job_from_remote_file (job);
4f50f5
@@ -1162,8 +1005,6 @@ pdf_load_job_start (PdfLoadJob *job)
4f50f5
 {
4f50f5
   if (job->gdata_entry != NULL)
4f50f5
     pdf_load_job_from_google_documents (job);
4f50f5
-  else if (job->zpj_entry != NULL)
4f50f5
-    pdf_load_job_from_skydrive (job);
4f50f5
   else
4f50f5
     pdf_load_job_from_uri (job);
4f50f5
 }
4f50f5
@@ -1189,7 +1030,7 @@ gd_pdf_loader_load_uri_async (const gchar *uri,
4f50f5
   result = g_simple_async_result_new (NULL, callback, user_data,
4f50f5
                                       gd_pdf_loader_load_uri_async);
4f50f5
 
4f50f5
-  job = pdf_load_job_new (result, uri, NULL, NULL, passwd, cancellable);
4f50f5
+  job = pdf_load_job_new (result, uri, NULL, passwd, cancellable);
4f50f5
 
4f50f5
   pdf_load_job_start (job);
4f50f5
 
4f50f5
@@ -1230,7 +1071,7 @@ gd_pdf_loader_load_gdata_entry_async (GDataEntry *entry,
4f50f5
   result = g_simple_async_result_new (NULL, callback, user_data,
4f50f5
                                       gd_pdf_loader_load_gdata_entry_async);
4f50f5
 
4f50f5
-  job = pdf_load_job_new (result, NULL, entry, NULL, NULL, cancellable);
4f50f5
+  job = pdf_load_job_new (result, NULL, entry, NULL, cancellable);
4f50f5
   job->gdata_service = g_object_ref (service);
4f50f5
 
4f50f5
   pdf_load_job_start (job);
4f50f5
@@ -1257,45 +1098,3 @@ gd_pdf_loader_load_gdata_entry_finish (GAsyncResult *res,
4f50f5
   retval = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
4f50f5
   return retval;
4f50f5
 }
4f50f5
-
4f50f5
-
4f50f5
-void
4f50f5
-gd_pdf_loader_load_zpj_entry_async (ZpjSkydriveEntry *entry,
4f50f5
-                                    ZpjSkydrive *service,
4f50f5
-                                    GCancellable *cancellable,
4f50f5
-                                    GAsyncReadyCallback callback,
4f50f5
-                                    gpointer user_data)
4f50f5
-{
4f50f5
-  PdfLoadJob *job;
4f50f5
-  GSimpleAsyncResult *result;
4f50f5
-
4f50f5
-  result = g_simple_async_result_new (NULL, callback, user_data,
4f50f5
-                                      gd_pdf_loader_load_zpj_entry_async);
4f50f5
-
4f50f5
-  job = pdf_load_job_new (result, NULL, NULL, entry, NULL, cancellable);
4f50f5
-  job->zpj_service = g_object_ref (service);
4f50f5
-
4f50f5
-  pdf_load_job_start (job);
4f50f5
-
4f50f5
-  g_object_unref (result);
4f50f5
-}
4f50f5
-
4f50f5
-/**
4f50f5
- * gd_pdf_loader_load_zpj_entry_finish:
4f50f5
- * @res:
4f50f5
- * @error: (allow-none) (out):
4f50f5
- *
4f50f5
- * Returns: (transfer full):
4f50f5
- */
4f50f5
-EvDocumentModel *
4f50f5
-gd_pdf_loader_load_zpj_entry_finish (GAsyncResult *res,
4f50f5
-                                     GError **error)
4f50f5
-{
4f50f5
-  EvDocumentModel *retval;
4f50f5
-
4f50f5
-  if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
4f50f5
-    return NULL;
4f50f5
-
4f50f5
-  retval = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
4f50f5
-  return retval;
4f50f5
-}
4f50f5
diff --git a/src/lib/gd-pdf-loader.h b/src/lib/gd-pdf-loader.h
4f50f5
index 9e5ffb737eee..70ded295dad3 100644
4f50f5
--- a/src/lib/gd-pdf-loader.h
4f50f5
+++ b/src/lib/gd-pdf-loader.h
4f50f5
@@ -28,7 +28,6 @@
4f50f5
 
4f50f5
 #define GOA_API_IS_SUBJECT_TO_CHANGE
4f50f5
 #include <gdata/gdata.h>
4f50f5
-#include <zpj/zpj.h>
4f50f5
 
4f50f5
 G_BEGIN_DECLS
4f50f5
 
4f50f5
@@ -48,14 +47,6 @@ void gd_pdf_loader_load_gdata_entry_async (GDataEntry *entry,
4f50f5
 EvDocumentModel *gd_pdf_loader_load_gdata_entry_finish (GAsyncResult *res,
4f50f5
                                                         GError **error);
4f50f5
 
4f50f5
-void gd_pdf_loader_load_zpj_entry_async (ZpjSkydriveEntry *entry,
4f50f5
-                                         ZpjSkydrive *service,
4f50f5
-                                         GCancellable *cancellable,
4f50f5
-                                         GAsyncReadyCallback callback,
4f50f5
-                                         gpointer user_data);
4f50f5
-EvDocumentModel *gd_pdf_loader_load_zpj_entry_finish (GAsyncResult *res,
4f50f5
-                                                      GError **error);
4f50f5
-
4f50f5
 G_END_DECLS
4f50f5
 
4f50f5
 #endif /* __GD_PDF_LOADER_H__ */
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From b80863a8d5666c9bd246a09bf770a8ea58367637 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 20 Apr 2017 11:51:47 +0200
4f50f5
Subject: [PATCH 07/16] documents: Fix the retrieval of the cache's
4f50f5
 modification time
4f50f5
4f50f5
Gio.FILE_ATTRIBUTE_TIME_MODIFIED returns a value in seconds, not
4f50f5
microseconds.
4f50f5
4f50f5
Fallout from 4133adf06a0ff473e6234f8ab3eb88c47589e627
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=774937
4f50f5
---
4f50f5
 src/documents.js | 2 --
4f50f5
 1 file changed, 2 deletions(-)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index ca48e53db25d..4db7d07029b4 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -387,8 +387,6 @@ const DocCommon = new Lang.Class({
4f50f5
                 }
4f50f5
 
4f50f5
                 let cacheMtime = info.get_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_MODIFIED);
4f50f5
-                cacheMtime /= 1000000;
4f50f5
-
4f50f5
                 if (this.mtime <= cacheMtime) {
4f50f5
                     callback(true, null);
4f50f5
                     return;
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From dd1343e7869882d632d75307b396de0c3fde4447 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Tue, 18 Apr 2017 19:01:26 +0200
4f50f5
Subject: [PATCH 08/16] Optionally load the document when determining if it can
4f50f5
 be printed
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=781533
4f50f5
---
4f50f5
 src/documents.js  | 99 ++++++++++++++++++++++++++++++++++++-------------------
4f50f5
 src/evinceview.js |  8 ++++-
4f50f5
 2 files changed, 72 insertions(+), 35 deletions(-)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 4db7d07029b4..fb0eee962548 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -36,6 +36,7 @@ const Zpj = imports.gi.Zpj;
4f50f5
 const _ = imports.gettext.gettext;
4f50f5
 
4f50f5
 const Lang = imports.lang;
4f50f5
+const Mainloop = imports.mainloop;
4f50f5
 const Signals = imports.signals;
4f50f5
 
4f50f5
 const Application = imports.application;
4f50f5
@@ -416,11 +417,37 @@ const DocCommon = new Lang.Class({
4f50f5
         log('Error: DocCommon implementations must override canTrash');
4f50f5
     },
4f50f5
 
4f50f5
-    canPrint: function(docModel) {
4f50f5
-        if (!docModel)
4f50f5
-            return false;
4f50f5
+    canPrint: function(docModel, cancellable, callback) {
4f50f5
+        if (docModel) {
4f50f5
+            Mainloop.idle_add(Lang.bind(this,
4f50f5
+                function() {
4f50f5
+                    this._canPrint(docModel, callback);
4f50f5
+                    return GLib.SOURCE_REMOVE;
4f50f5
+                }));
4f50f5
+
4f50f5
+            return;
4f50f5
+        }
4f50f5
+
4f50f5
+        this.load(null, cancellable, Lang.bind(this,
4f50f5
+            function(doc, docModel, error) {
4f50f5
+                if (error) {
4f50f5
+                    callback(this, false);
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                this._canPrint(docModel, callback);
4f50f5
+            }));
4f50f5
+    },
4f50f5
+
4f50f5
+    _canPrint: function(docModel, callback) {
4f50f5
+        if (!docModel) {
4f50f5
+            callback(this, false);
4f50f5
+            return;
4f50f5
+        }
4f50f5
 
4f50f5
-        return EvView.PrintOperation.exists_for_document(docModel.get_document());
4f50f5
+        let evDoc = docModel.get_document();
4f50f5
+        let supported = EvView.PrintOperation.exists_for_document(evDoc);
4f50f5
+        callback(this, supported);
4f50f5
     },
4f50f5
 
4f50f5
     trash: function() {
4f50f5
@@ -694,41 +721,45 @@ const DocCommon = new Lang.Class({
4f50f5
                     return;
4f50f5
                 }
4f50f5
 
4f50f5
-                if (!this.canPrint(docModel))
4f50f5
-                    return;
4f50f5
+                this.canPrint(docModel, null, Lang.bind(this,
4f50f5
+                    function(doc, supported) {
4f50f5
+                        if (!supported)
4f50f5
+                            return;
4f50f5
 
4f50f5
-                let printOp = EvView.PrintOperation.new(docModel.get_document());
4f50f5
+                        let printOp = EvView.PrintOperation.new(docModel.get_document());
4f50f5
 
4f50f5
-                printOp.connect('begin-print', Lang.bind(this,
4f50f5
-                    function() {
4f50f5
-                        Application.selectionController.setSelectionMode(false);
4f50f5
-                    }));
4f50f5
 
4f50f5
-                printOp.connect('done', Lang.bind(this,
4f50f5
-                    function(op, res) {
4f50f5
-                        if (res == Gtk.PrintOperationResult.ERROR) {
4f50f5
-                            try {
4f50f5
-                                printOp.get_error();
4f50f5
-                            } catch (e) {
4f50f5
-                                let errorDialog = new Gtk.MessageDialog ({ transient_for: toplevel,
4f50f5
-                                                                           modal: true,
4f50f5
-                                                                           destroy_with_parent: true,
4f50f5
-                                                                           buttons: Gtk.ButtonsType.OK,
4f50f5
-                                                                           message_type: Gtk.MessageType.ERROR,
4f50f5
-                                                                           text: _("Failed to print document"),
4f50f5
-                                                                           secondary_text: e.message });
4f50f5
-                                errorDialog.connect ('response', Lang.bind(this,
4f50f5
-                                    function() {
4f50f5
-                                        errorDialog.destroy();
4f50f5
-                                    }));
4f50f5
-                                errorDialog.show();
4f50f5
-                            }
4f50f5
-                        }
4f50f5
-                    }));
4f50f5
+                        printOp.connect('begin-print', Lang.bind(this,
4f50f5
+                            function() {
4f50f5
+                                Application.selectionController.setSelectionMode(false);
4f50f5
+                            }));
4f50f5
 
4f50f5
-                let printNotification = new Notifications.PrintNotification(printOp, doc);
4f50f5
+                        printOp.connect('done', Lang.bind(this,
4f50f5
+                            function(op, res) {
4f50f5
+                                if (res == Gtk.PrintOperationResult.ERROR) {
4f50f5
+                                    try {
4f50f5
+                                        printOp.get_error();
4f50f5
+                                    } catch (e) {
4f50f5
+                                        let errorDialog = new Gtk.MessageDialog ({ transient_for: toplevel,
4f50f5
+                                                                                   modal: true,
4f50f5
+                                                                                   destroy_with_parent: true,
4f50f5
+                                                                                   buttons: Gtk.ButtonsType.OK,
4f50f5
+                                                                                   message_type: Gtk.MessageType.ERROR,
4f50f5
+                                                                                   text: _("Failed to print document"),
4f50f5
+                                                                                   secondary_text: e.message });
4f50f5
+                                        errorDialog.connect ('response', Lang.bind(this,
4f50f5
+                                            function() {
4f50f5
+                                                errorDialog.destroy();
4f50f5
+                                            }));
4f50f5
+                                        errorDialog.show();
4f50f5
+                                    }
4f50f5
+                                }
4f50f5
+                            }));
4f50f5
+
4f50f5
+                        let printNotification = new Notifications.PrintNotification(printOp, doc);
4f50f5
 
4f50f5
-                printOp.run(toplevel);
4f50f5
+                        printOp.run(toplevel);
4f50f5
+                    }));
4f50f5
             }));
4f50f5
     },
4f50f5
 
4f50f5
diff --git a/src/evinceview.js b/src/evinceview.js
4f50f5
index d4ea883e76b4..3e0070bb785c 100644
4f50f5
--- a/src/evinceview.js
4f50f5
+++ b/src/evinceview.js
4f50f5
@@ -264,7 +264,13 @@ const EvinceView = new Lang.Class({
4f50f5
 
4f50f5
         this.getAction('copy').enabled = false;
4f50f5
         this.getAction('edit-current').enabled = doc.canEdit();
4f50f5
-        this.getAction('print-current').enabled = doc.canPrint(docModel);
4f50f5
+
4f50f5
+        this.getAction('print-current').enabled = false;
4f50f5
+        doc.canPrint(docModel, null, Lang.bind(this,
4f50f5
+            function(doc, supported) {
4f50f5
+                this.getAction('print-current').enabled = supported;
4f50f5
+            }));
4f50f5
+
4f50f5
         let presentCurrent = this.getAction('present-current');
4f50f5
         if (presentCurrent)
4f50f5
             presentCurrent.enabled = true;
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From c37a9a62610ba301f09d2e53a4004dcbf12dadec Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 20 Apr 2017 14:40:40 +0200
4f50f5
Subject: [PATCH 09/16] documents: Check whether it is a collection in canPrint
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=781533
4f50f5
---
4f50f5
 src/documents.js | 10 ++++++++++
4f50f5
 1 file changed, 10 insertions(+)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index fb0eee962548..3bed18c36a49 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -418,6 +418,16 @@ const DocCommon = new Lang.Class({
4f50f5
     },
4f50f5
 
4f50f5
     canPrint: function(docModel, cancellable, callback) {
4f50f5
+        if (this.collection) {
4f50f5
+            Mainloop.idle_add(Lang.bind(this,
4f50f5
+                function() {
4f50f5
+                    callback(this, false);
4f50f5
+                    return GLib.SOURCE_REMOVE;
4f50f5
+                }));
4f50f5
+
4f50f5
+            return;
4f50f5
+        }
4f50f5
+
4f50f5
         if (docModel) {
4f50f5
             Mainloop.idle_add(Lang.bind(this,
4f50f5
                 function() {
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 7d63e3fc760aef6ec56868a16e930af8977f0973 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 20 Apr 2017 14:59:12 +0200
4f50f5
Subject: [PATCH 10/16] selections: Enable printing only for documents handled
4f50f5
 by EvView
4f50f5
4f50f5
Now that we don't convert everything to PDFs, we might not be able to
4f50f5
print everything that's not a collection. eg., we can't print EPUBs,
4f50f5
ODFs and OOXMLs. Therefore it is not enough to only check for
4f50f5
collections.
4f50f5
4f50f5
Instead, let's use canPrint which encapsulates all the conditions that
4f50f5
need to be met for printing.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=781533
4f50f5
---
4f50f5
 src/selections.js | 15 ++++++++++-----
4f50f5
 1 file changed, 10 insertions(+), 5 deletions(-)
4f50f5
4f50f5
diff --git a/src/selections.js b/src/selections.js
4f50f5
index b864c8f8a634..ecfd3ec694c7 100644
4f50f5
--- a/src/selections.js
4f50f5
+++ b/src/selections.js
4f50f5
@@ -946,7 +946,7 @@ const SelectionToolbar = new Lang.Class({
4f50f5
         let hasSelection = (selection.length > 0);
4f50f5
 
4f50f5
         let showTrash = hasSelection;
4f50f5
-        let showPrint = hasSelection;
4f50f5
+        let showPrint = false;
4f50f5
         let showProperties = hasSelection;
4f50f5
         let showOpen = hasSelection;
4f50f5
         let showShare = hasSelection;
4f50f5
@@ -967,16 +967,21 @@ const SelectionToolbar = new Lang.Class({
4f50f5
                     showShare = false;
4f50f5
 
4f50f5
                 showTrash &= doc.canTrash();
4f50f5
-                showPrint &= !doc.collection;
4f50f5
             }));
4f50f5
 
4f50f5
         showOpen = (apps.length > 0);
4f50f5
 
4f50f5
-        if (selection.length > 1) {
4f50f5
-            showPrint = false;
4f50f5
-            showProperties = false;
4f50f5
+        if (selection.length == 1) {
4f50f5
+            let doc = Application.documentManager.getItemById(selection[0]);
4f50f5
+            doc.canPrint(null, null, Lang.bind(this,
4f50f5
+                function(doc, supported) {
4f50f5
+                    this._toolbarPrint.set_sensitive(supported);
4f50f5
+                }));
4f50f5
         }
4f50f5
 
4f50f5
+        if (selection.length > 1)
4f50f5
+            showProperties = false;
4f50f5
+
4f50f5
         let openLabel = null;
4f50f5
         if (apps.length == 1) {
4f50f5
             // Translators: this is the Open action in a context menu
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From aa507bc55aef99815308fe7865f016d40ed6f76d Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Mon, 27 Mar 2017 16:08:57 +0200
4f50f5
Subject: [PATCH 11/16] documents: Thumbnail SkydriveDocuments once they are
4f50f5
 loaded
4f50f5
MIME-Version: 1.0
4f50f5
Content-Type: text/plain; charset=UTF-8
4f50f5
Content-Transfer-Encoding: 8bit
4f50f5
4f50f5
Historically, unlike GoogleDocuments, we were unable to fetch
4f50f5
server-side thumbnails for SkydriveDocuments due to limitations of
4f50f5
OneDrive's REST API. Newer versions of the REST API do support it [1],
4f50f5
but it is not implemented in libzapojit.
4f50f5
4f50f5
Some ways to work around these limitations:
4f50f5
  - Create the thumbnail from the EvDocument when it is loaded for
4f50f5
    previewing
4f50f5
  - Use a cached copy of the document as source for the thumbnail
4f50f5
4f50f5
Even if we can fetch thumbnails from the server in future, these would
4f50f5
still be nice optimizations to have — reduces network consumption and
4f50f5
offers a cheap way to jump ahead in the thumbnailing queue.
4f50f5
4f50f5
[1] https://dev.onedrive.com/items/thumbnails.htm
4f50f5
---
4f50f5
 src/documents.js | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4f50f5
 1 file changed, 109 insertions(+), 2 deletions(-)
4f50f5
4f50f5
diff --git a/src/documents.js b/src/documents.js
4f50f5
index 3bed18c36a49..27518b2251d1 100644
4f50f5
--- a/src/documents.js
4f50f5
+++ b/src/documents.js
4f50f5
@@ -1150,7 +1150,7 @@ const SkydriveDocument = new Lang.Class({
4f50f5
     Extends: DocCommon,
4f50f5
 
4f50f5
     _init: function(cursor) {
4f50f5
-        this._failedThumbnailing = true;
4f50f5
+        this._failedThumbnailing = false;
4f50f5
 
4f50f5
         this.parent(cursor);
4f50f5
 
4f50f5
@@ -1174,6 +1174,54 @@ const SkydriveDocument = new Lang.Class({
4f50f5
         this.uriToLoad = localFile.get_uri();
4f50f5
     },
4f50f5
 
4f50f5
+    _createThumbnailFromEvDocument: function(evDoc, cancellable, callback) {
4f50f5
+        let thumbnailPath = GnomeDesktop.desktop_thumbnail_path_for_uri (this.uri,
4f50f5
+                                                                         GnomeDesktop.DesktopThumbnailSize.LARGE);
4f50f5
+        let thumbnailFile = Gio.File.new_for_path(thumbnailPath);
4f50f5
+
4f50f5
+        let thumbnailDir = GLib.path_get_dirname(thumbnailPath);
4f50f5
+        GLib.mkdir_with_parents(thumbnailDir, 448);
4f50f5
+
4f50f5
+        thumbnailFile.replace_async(null,
4f50f5
+                                    false,
4f50f5
+                                    Gio.FileCreateFlags.PRIVATE,
4f50f5
+                                    GLib.PRIORITY_DEFAULT,
4f50f5
+                                    cancellable,
4f50f5
+                                    Lang.bind(this,
4f50f5
+            function(source, res) {
4f50f5
+                let outputStream;
4f50f5
+
4f50f5
+                try {
4f50f5
+                    outputStream = thumbnailFile.replace_finish(res);
4f50f5
+                } catch (e) {
4f50f5
+                    callback(e);
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                let [width, height] = evDoc.get_page_size(0);
4f50f5
+                let maxDimension = Math.max(width, height);
4f50f5
+                let scale = Application.application.getScaleFactor();
4f50f5
+                let size = 128 * scale;
4f50f5
+                let zoom = size / maxDimension;
4f50f5
+
4f50f5
+                let page = evDoc.get_page(0);
4f50f5
+
4f50f5
+                let rc = EvDocument.RenderContext.new(page, 0, zoom);
4f50f5
+                let pixbuf = evDoc.get_thumbnail(rc);
4f50f5
+                pixbuf.save_to_streamv_async(outputStream, "png", [], [], cancellable, Lang.bind(this,
4f50f5
+                    function(source, res) {
4f50f5
+                        try {
4f50f5
+                            GdkPixbuf.Pixbuf.save_to_stream_finish(res);
4f50f5
+                        } catch (e) {
4f50f5
+                            callback(e);
4f50f5
+                            return;
4f50f5
+                        }
4f50f5
+
4f50f5
+                        callback(null);
4f50f5
+                    }));
4f50f5
+            }));
4f50f5
+    },
4f50f5
+
4f50f5
     _createZpjEntry: function(cancellable, callback) {
4f50f5
         let source = Application.sourceManager.getItemById(this.resourceUrn);
4f50f5
 
4f50f5
@@ -1276,7 +1324,16 @@ const SkydriveDocument = new Lang.Class({
4f50f5
                                             return;
4f50f5
                                         }
4f50f5
 
4f50f5
-                                        this.loadLocal(passwd, cancellable, callback);
4f50f5
+                                        this.loadLocal(passwd, cancellable, Lang.bind(this,
4f50f5
+                                            function(doc, docModel, error) {
4f50f5
+                                                if (error) {
4f50f5
+                                                    callback(this, null, error);
4f50f5
+                                                    return;
4f50f5
+                                                }
4f50f5
+
4f50f5
+                                                callback(this, docModel, null);
4f50f5
+                                                this._postLoad(docModel);
4f50f5
+                                            }));
4f50f5
                                     }));
4f50f5
                             } else {
4f50f5
                                 callback(this, null, error);
4f50f5
@@ -1286,6 +1343,56 @@ const SkydriveDocument = new Lang.Class({
4f50f5
                         }
4f50f5
 
4f50f5
                         callback(this, docModel, null);
4f50f5
+                        this._postLoad(docModel);
4f50f5
+                    }));
4f50f5
+            }));
4f50f5
+    },
4f50f5
+
4f50f5
+    _postLoad: function(docModel) {
4f50f5
+        if (this._thumbPath)
4f50f5
+            return;
4f50f5
+
4f50f5
+        if (!docModel)
4f50f5
+            return;
4f50f5
+
4f50f5
+        this._createThumbnailFromEvDocument(docModel.document, null, Lang.bind(this,
4f50f5
+            function(error) {
4f50f5
+                if (error) {
4f50f5
+                    logError(error, 'Unable to create thumbnail from EvDocument');
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                this._failedThumbnailing = false;
4f50f5
+                this.refreshIcon();
4f50f5
+            }));
4f50f5
+    },
4f50f5
+
4f50f5
+    createThumbnail: function(callback) {
4f50f5
+        // try loading from the most recent cache, if any
4f50f5
+        this.loadLocal(null, null, Lang.bind(this,
4f50f5
+            function(doc, docModel, error) {
4f50f5
+                if (error) {
4f50f5
+                    if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) &&
4f50f5
+                        !error.matches(EvDocument.DocumentError, EvDocument.DocumentError.ENCRYPTED)) {
4f50f5
+                        logError(error, 'Unable to load document from the cache');
4f50f5
+                        callback(false);
4f50f5
+                        return;
4f50f5
+                    }
4f50f5
+                }
4f50f5
+
4f50f5
+                if (!docModel) {
4f50f5
+                    callback(false);
4f50f5
+                    return;
4f50f5
+                }
4f50f5
+
4f50f5
+                this._createThumbnailFromEvDocument(docModel.document, null, Lang.bind(this,
4f50f5
+                    function(error) {
4f50f5
+                        if (error) {
4f50f5
+                            logError(error, 'Unable to create thumbnail from EvDocument');
4f50f5
+                            return;
4f50f5
+                        }
4f50f5
+
4f50f5
+                        callback(true);
4f50f5
                     }));
4f50f5
             }));
4f50f5
     },
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 3bd516524432f9decb0a15ab209a9957b7ae7488 Mon Sep 17 00:00:00 2001
4f50f5
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
4f50f5
Date: Mon, 8 May 2017 16:44:32 +0100
4f50f5
Subject: [PATCH 12/16] lokview: Fix crash on repeated open of presentations
4f50f5
4f50f5
Ensure prompt destruction of the LOKDocView widget when the view is
4f50f5
destroyed. This gives LOK a chance to shutdown at the right time.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=782508
4f50f5
---
4f50f5
 src/lokview.js | 12 ++++++++++--
4f50f5
 1 file changed, 10 insertions(+), 2 deletions(-)
4f50f5
4f50f5
diff --git a/src/lokview.js b/src/lokview.js
4f50f5
index 988db963d5d9..238832ed4502 100644
4f50f5
--- a/src/lokview.js
4f50f5
+++ b/src/lokview.js
4f50f5
@@ -137,11 +137,19 @@ const LOKView = new Lang.Class({
4f50f5
             this._lokview.connect('text-selection', Lang.bind(this, this._onTextSelection));
4f50f5
             this._lokview.connect('notify::can-zoom-in', Lang.bind(this, this._onCanZoomInChanged));
4f50f5
             this._lokview.connect('notify::can-zoom-out', Lang.bind(this, this._onCanZoomOutChanged));
4f50f5
+            this.connect('destroy', Lang.bind(this, this._destroyView));
4f50f5
         }
4f50f5
 
4f50f5
         return sw;
4f50f5
     },
4f50f5
 
4f50f5
+    _destroyView: function() {
4f50f5
+	if (this._lokview) {
4f50f5
+	    this._lokview.destroy();
4f50f5
+	    this._lokview = null;
4f50f5
+	}
4f50f5
+    },
4f50f5
+
4f50f5
     onLoadFinished: function(manager, doc) {
4f50f5
         this.parent(manager, doc);
4f50f5
 
4f50f5
@@ -237,10 +245,10 @@ const LOKView = new Lang.Class({
4f50f5
     },
4f50f5
 
4f50f5
     get page() {
4f50f5
-        return this._lokview.get_part();
4f50f5
+        return this._lokview ? this._lokview.get_part() : 0;
4f50f5
     },
4f50f5
 
4f50f5
     get numPages() {
4f50f5
-        return this._lokview.get_parts();
4f50f5
+        return this._lokview ? this._lokview.get_parts() : 0;
4f50f5
     }
4f50f5
 });
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 238a4d4c95b78eff9d1a764f184936ddc58db73d Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 8 Jun 2017 16:10:57 +0200
4f50f5
Subject: [PATCH 13/16] application: Avoid CRITICALs if a primary instance is
4f50f5
 already present
4f50f5
4f50f5
The dbus_unregister method can be invoked more than once. Trying to
4f50f5
unexport an already unexported GDBusInterfaceSkeleton led to:
4f50f5
  GLib-GIO-CRITICAL **:
4f50f5
    g_dbus_interface_skeleton_unexport_from_connection: assertion
4f50f5
    'interface_->priv->connections != NULL' failed
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=783548
4f50f5
---
4f50f5
 src/application.js | 5 ++++-
4f50f5
 1 file changed, 4 insertions(+), 1 deletion(-)
4f50f5
4f50f5
diff --git a/src/application.js b/src/application.js
4f50f5
index a82395d6afd2..40a5dd0e5114 100644
4f50f5
--- a/src/application.js
4f50f5
+++ b/src/application.js
4f50f5
@@ -521,7 +521,10 @@ const Application = new Lang.Class({
4f50f5
     },
4f50f5
 
4f50f5
     vfunc_dbus_unregister: function(connection, path) {
4f50f5
-        this._searchProvider.unexport(connection);
4f50f5
+        if (this._searchProvider != null) {
4f50f5
+            this._searchProvider.unexport(connection);
4f50f5
+            this._searchProvider = null;
4f50f5
+        }
4f50f5
 
4f50f5
         this.parent(connection, path);
4f50f5
     },
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From ca10b8d02486630db2f3de746ee4b885490cbaab Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 8 Jun 2017 16:12:15 +0200
4f50f5
Subject: [PATCH 14/16] application: Instantiate ShellSearchProvider only when
4f50f5
 registering
4f50f5
4f50f5
Now that the --version flag was implemented using the
4f50f5
handle_local_options virtual method, it is possible that the
4f50f5
Application may exit without ever touching D-Bus. So it is a tad
4f50f5
wasteful to instantiate the ShellSearchProvider when it is never going
4f50f5
to be used. Since we are unreffing it in dbus_register, we might as
4f50f5
well create it in dbus_register.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=783548
4f50f5
---
4f50f5
 src/application.js | 9 +++++----
4f50f5
 1 file changed, 5 insertions(+), 4 deletions(-)
4f50f5
4f50f5
diff --git a/src/application.js b/src/application.js
4f50f5
index 40a5dd0e5114..2630e1971826 100644
4f50f5
--- a/src/application.js
4f50f5
+++ b/src/application.js
4f50f5
@@ -100,6 +100,7 @@ const Application = new Lang.Class({
4f50f5
         this.minersRunning = [];
4f50f5
         this._activationTimestamp = Gdk.CURRENT_TIME;
4f50f5
         this._extractPriority = null;
4f50f5
+        this._searchProvider = null;
4f50f5
 
4f50f5
         this.isBooks = isBooks;
4f50f5
 
4f50f5
@@ -120,10 +121,6 @@ const Application = new Lang.Class({
4f50f5
 
4f50f5
         this.add_main_option('version', 'v'.charCodeAt(0), GLib.OptionFlags.NONE, GLib.OptionArg.NONE,
4f50f5
                              _("Show the version of the program"), null);
4f50f5
-
4f50f5
-        this._searchProvider = new ShellSearchProvider.ShellSearchProvider();
4f50f5
-        this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult));
4f50f5
-        this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch));
4f50f5
     },
4f50f5
 
4f50f5
     _initGettingStarted: function() {
4f50f5
@@ -516,6 +513,10 @@ const Application = new Lang.Class({
4f50f5
     vfunc_dbus_register: function(connection, path) {
4f50f5
         this.parent(connection, path);
4f50f5
 
4f50f5
+        this._searchProvider = new ShellSearchProvider.ShellSearchProvider();
4f50f5
+        this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult));
4f50f5
+        this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch));
4f50f5
+
4f50f5
         this._searchProvider.export(connection);
4f50f5
         return true;
4f50f5
     },
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From af6130bfe229521869f33a125dd4d354f4327ff4 Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 8 Jun 2017 16:12:34 +0200
4f50f5
Subject: [PATCH 15/16] application: Assert that the ShellSearchProvider's
4f50f5
 lifetime is sane
4f50f5
4f50f5
The ShellSearchProvider should be instantiated in the dbus_register
4f50f5
virtual method, which is expected to be called only once.
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=783548
4f50f5
---
4f50f5
 src/application.js | 3 +++
4f50f5
 1 file changed, 3 insertions(+)
4f50f5
4f50f5
diff --git a/src/application.js b/src/application.js
4f50f5
index 2630e1971826..1e439815f0b4 100644
4f50f5
--- a/src/application.js
4f50f5
+++ b/src/application.js
4f50f5
@@ -513,6 +513,9 @@ const Application = new Lang.Class({
4f50f5
     vfunc_dbus_register: function(connection, path) {
4f50f5
         this.parent(connection, path);
4f50f5
 
4f50f5
+        if (this._searchProvider != null)
4f50f5
+            throw(new Error('ShellSearchProvider already instantiated - dbus_register called twice?'));
4f50f5
+
4f50f5
         this._searchProvider = new ShellSearchProvider.ShellSearchProvider();
4f50f5
         this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult));
4f50f5
         this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch));
4f50f5
-- 
4f50f5
2.9.4
4f50f5
4f50f5
4f50f5
From 4d3476a700ecbb5066269f9fb15fc201d134859e Mon Sep 17 00:00:00 2001
4f50f5
From: Debarshi Ray <debarshir@gnome.org>
4f50f5
Date: Thu, 8 Jun 2017 16:58:08 +0200
4f50f5
Subject: [PATCH 16/16] application: Don't unexport a skeleton that was never
4f50f5
 exported
4f50f5
4f50f5
Otherwise it will again lead to:
4f50f5
  GLib-GIO-CRITICAL **:
4f50f5
    g_dbus_interface_skeleton_unexport_from_connection: assertion
4f50f5
    'interface_->priv->connections != NULL' failed
4f50f5
4f50f5
https://bugzilla.gnome.org/show_bug.cgi?id=783548
4f50f5
---
4f50f5
 src/application.js | 8 +++++++-
4f50f5
 1 file changed, 7 insertions(+), 1 deletion(-)
4f50f5
4f50f5
diff --git a/src/application.js b/src/application.js
4f50f5
index 1e439815f0b4..f9e8b6ae9863 100644
4f50f5
--- a/src/application.js
4f50f5
+++ b/src/application.js
4f50f5
@@ -520,7 +520,13 @@ const Application = new Lang.Class({
4f50f5
         this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult));
4f50f5
         this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch));
4f50f5
 
4f50f5
-        this._searchProvider.export(connection);
4f50f5
+        try {
4f50f5
+            this._searchProvider.export(connection);
4f50f5
+        } catch(e) {
4f50f5
+            this._searchProvider = null;
4f50f5
+            throw(e);
4f50f5
+        }
4f50f5
+
4f50f5
         return true;
4f50f5
     },
4f50f5
 
4f50f5
-- 
4f50f5
2.9.4
4f50f5