diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a0378e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/gnome-documents-3.22.2.tar.xz diff --git a/.gnome-documents.metadata b/.gnome-documents.metadata new file mode 100644 index 0000000..05815a6 --- /dev/null +++ b/.gnome-documents.metadata @@ -0,0 +1 @@ +61295a5226f2e963c46fc4df2f9235643d40b94c SOURCES/gnome-documents-3.22.2.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/gnome-documents-getting-started.patch b/SOURCES/gnome-documents-getting-started.patch new file mode 100644 index 0000000..78a4bf3 --- /dev/null +++ b/SOURCES/gnome-documents-getting-started.patch @@ -0,0 +1,478 @@ +From e7f496a155da98fe6321b157b83c878001ea8fb8 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 7 Dec 2017 20:11:39 +0100 +Subject: [PATCH 1/7] application: Insert the getting started PDF only when + showing a window + +The startup is shared between the application and the search provider. +There is no need to initialize the getting started PDF for the search +provider, since it is only useful when the user runs the application. + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/application.js | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 40506d48627b..73cb01767240 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -488,9 +488,6 @@ var Application = new Lang.Class({ + accels: ['f'] } + ]; + +- if (!this.isBooks) +- this._initGettingStarted(); +- + Utils.populateActionGroup(this, this._actionEntries, 'app'); + }, + +@@ -498,6 +495,9 @@ var Application = new Lang.Class({ + if (this._mainWindow) + return; + ++ if (!this.isBooks) ++ this._initGettingStarted(); ++ + notificationManager = new Notifications.NotificationManager(); + this._connectActionsToMode(); + this._mainWindow = new MainWindow.MainWindow(this); +-- +2.14.3 + + +From c98d19eaf7aeb20eea90d93ba1a0c9c112a2a3e7 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 7 Dec 2017 20:53:10 +0100 +Subject: [PATCH 2/7] application: Make window creation complete asynchronously + +Creating MainWindow starts the TrackerControllers. The getting started +PDF needs to be located before that happens, to let the +TrackerControllers include it in their queries. Since, locating the PDF +is an asynchronous operation, the overall _createWindow method also +needs to complete asynchronously. + +This doesn't make any user-visible changes, but sets the stage for the +subsequent patches. + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/application.js | 81 ++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 54 insertions(+), 27 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 73cb01767240..b80f22ddd03a 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -491,9 +491,16 @@ var Application = new Lang.Class({ + Utils.populateActionGroup(this, this._actionEntries, 'app'); + }, + +- _createWindow: function() { +- if (this._mainWindow) ++ _createWindow: function(callback) { ++ if (this._mainWindow) { ++ Mainloop.idle_add(Lang.bind(this, ++ function() { ++ callback(); ++ return GLib.SOURCE_REMOVE; ++ })); ++ + return; ++ } + + if (!this.isBooks) + this._initGettingStarted(); +@@ -512,6 +519,20 @@ var Application = new Lang.Class({ + + // start miners + this._startMiners(); ++ ++ Mainloop.idle_add(Lang.bind(this, ++ function() { ++ callback(); ++ return GLib.SOURCE_REMOVE; ++ })); ++ }, ++ ++ _presentWindow: function() { ++ if (!this._mainWindow) ++ throw(new Error('this._mainWindow == null')); ++ ++ this._mainWindow.present_with_time(this._activationTimestamp); ++ this._activationTimestamp = Gdk.CURRENT_TIME; + }, + + vfunc_dbus_register: function(connection, path) { +@@ -554,12 +575,14 @@ var Application = new Lang.Class({ + + vfunc_activate: function() { + if (!this._mainWindow) { +- this._createWindow(); +- modeController.setWindowMode(WindowMode.WindowMode.DOCUMENTS); ++ this._createWindow(Lang.bind(this, ++ function() { ++ modeController.setWindowMode(WindowMode.WindowMode.DOCUMENTS); ++ this._presentWindow(); ++ })); ++ } else { ++ this._presentWindow(); + } +- +- this._mainWindow.present_with_time(this._activationTimestamp); +- this._activationTimestamp = Gdk.CURRENT_TIME; + }, + + _clearState: function() { +@@ -598,22 +621,24 @@ var Application = new Lang.Class({ + }, + + _onActivateResult: function(provider, urn, terms, timestamp) { +- this._createWindow(); +- modeController.setWindowMode(WindowMode.WindowMode.PREVIEW_EV); +- +- let doc = documentManager.getItemById(urn); +- if (doc) { +- doActivate.apply(this, [doc]); +- } else { +- let job = new TrackerUtils.SingleItemJob(urn, queryBuilder); +- job.run(Query.QueryFlags.UNFILTERED, Lang.bind(this, +- function(cursor) { +- if (cursor) +- doc = documentManager.addDocumentFromCursor(cursor); ++ this._createWindow(Lang.bind(this, ++ function() { ++ modeController.setWindowMode(WindowMode.WindowMode.PREVIEW_EV); + ++ let doc = documentManager.getItemById(urn); ++ if (doc) { + doActivate.apply(this, [doc]); +- })); +- } ++ } else { ++ let job = new TrackerUtils.SingleItemJob(urn, queryBuilder); ++ job.run(Query.QueryFlags.UNFILTERED, Lang.bind(this, ++ function(cursor) { ++ if (cursor) ++ doc = documentManager.addDocumentFromCursor(cursor); ++ ++ doActivate.apply(this, [doc]); ++ })); ++ } ++ })); + + function doActivate(doc) { + documentManager.setActiveItem(doc); +@@ -637,13 +662,15 @@ var Application = new Lang.Class({ + }, + + _onLaunchSearch: function(provider, terms, timestamp) { +- this._createWindow(); +- modeController.setWindowMode(WindowMode.WindowMode.DOCUMENTS); +- searchController.setString(terms.join(' ')); +- this.change_action_state('search', GLib.Variant.new('b', true)); ++ this._createWindow(Lang.bind(this, ++ function() { ++ modeController.setWindowMode(WindowMode.WindowMode.DOCUMENTS); ++ searchController.setString(terms.join(' ')); ++ this.change_action_state('search', GLib.Variant.new('b', true)); + +- this._activationTimestamp = timestamp; +- this.activate(); ++ this._activationTimestamp = timestamp; ++ this.activate(); ++ })); + }, + + getScaleFactor: function() { +-- +2.14.3 + + +From 935d00626f3a3481e9ae13c0eadb146c10d9625a Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 8 Dec 2017 17:13:52 +0100 +Subject: [PATCH 3/7] application: Tie the catch block more tightly to the + failure site + +Having a lot of code inside a try statement makes it harder to follow +the error handling logic. The catch statements are far away from the +code that can throw an exception, so it is difficult to match them +together. Let's reduce the size of the try blocks by only using them +for fallible operations. + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/application.js | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/src/application.js b/src/application.js +index b80f22ddd03a..8f9b6276ac0a 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -149,19 +149,21 @@ var Application = new Lang.Class({ + function(object, res) { + try { + let info = object.query_info_finish(res); +- this.gettingStartedLocation = file.get_parent(); +- +- manager.index_file_async(file, null, +- function(object, res) { +- try { +- manager.index_file_finish(res); +- } catch (e) { +- log('Error indexing the getting started PDF: ' + e.message); +- } +- }); + } catch (e) { + checkNextFile.apply(this); ++ return; + } ++ ++ this.gettingStartedLocation = file.get_parent(); ++ ++ manager.index_file_async(file, null, ++ function(object, res) { ++ try { ++ manager.index_file_finish(res); ++ } catch (e) { ++ log('Error indexing the getting started PDF: ' + e.message); ++ } ++ }); + })); + } + +-- +2.14.3 + + +From 2362a9b4b6e518ccc04d6d6c6d16f837e3df038d Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 8 Dec 2017 17:29:56 +0100 +Subject: [PATCH 4/7] application: Shuffle some code around + +Having the _initGettingStarted method take care of the isBooks +condition will make it easier to chain it with the window creation. + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/application.js | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 8f9b6276ac0a..81ae382770df 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -127,6 +127,9 @@ var Application = new Lang.Class({ + }, + + _initGettingStarted: function() { ++ if (this.isBooks) ++ return; ++ + let manager = TrackerControl.MinerManager.new_full(false); + + let languages = GLib.get_language_names(); +@@ -504,8 +507,7 @@ var Application = new Lang.Class({ + return; + } + +- if (!this.isBooks) +- this._initGettingStarted(); ++ this._initGettingStarted(); + + notificationManager = new Notifications.NotificationManager(); + this._connectActionsToMode(); +-- +2.14.3 + + +From 4f5d1073d2049422b36c4b809a3f2ae6e8db3f4c Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 8 Dec 2017 17:36:49 +0100 +Subject: [PATCH 5/7] application: Create the window only after detecting the + PDF + +This ensures that the TrackerControllers are started after the getting +started PDF has been initialized, so that it can be included in their +queries. + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/application.js | 55 +++++++++++++++++++++++++++++++++--------------------- + 1 file changed, 34 insertions(+), 21 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 81ae382770df..3c7110323dc3 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -126,9 +126,16 @@ var Application = new Lang.Class({ + _("Show the version of the program"), null); + }, + +- _initGettingStarted: function() { +- if (this.isBooks) ++ _initGettingStarted: function(callback) { ++ if (this.isBooks) { ++ Mainloop.idle_add(Lang.bind(this, ++ function() { ++ callback(); ++ return GLib.SOURCE_REMOVE; ++ })); ++ + return; ++ } + + let manager = TrackerControl.MinerManager.new_full(false); + +@@ -145,6 +152,7 @@ var Application = new Lang.Class({ + let file = files.shift(); + if (!file) { + log('Can\'t find a valid getting started PDF document'); ++ callback(); + return; + } + +@@ -166,11 +174,17 @@ var Application = new Lang.Class({ + } catch (e) { + log('Error indexing the getting started PDF: ' + e.message); + } ++ ++ callback(); + }); + })); + } + +- checkNextFile.apply(this); ++ Mainloop.idle_add(Lang.bind(this, ++ function() { ++ checkNextFile.apply(this); ++ return GLib.SOURCE_REMOVE; ++ })); + }, + + _fullscreenCreateHook: function(action) { +@@ -507,27 +521,26 @@ var Application = new Lang.Class({ + return; + } + +- this._initGettingStarted(); +- +- notificationManager = new Notifications.NotificationManager(); +- this._connectActionsToMode(); +- this._mainWindow = new MainWindow.MainWindow(this); +- this._mainWindow.connect('destroy', Lang.bind(this, this._onWindowDestroy)); +- +- try { +- this._extractPriority = TrackerExtractPriority(); +- this._extractPriority.SetRdfTypesRemote(['nfo:Document']); +- } catch (e) { +- log('Unable to connect to the tracker extractor: ' + e.toString()); +- } ++ this.hold(); ++ this._initGettingStarted(Lang.bind(this, ++ function() { ++ this.release(); ++ notificationManager = new Notifications.NotificationManager(); ++ this._connectActionsToMode(); ++ this._mainWindow = new MainWindow.MainWindow(this); ++ this._mainWindow.connect('destroy', Lang.bind(this, this._onWindowDestroy)); ++ ++ try { ++ this._extractPriority = TrackerExtractPriority(); ++ this._extractPriority.SetRdfTypesRemote(['nfo:Document']); ++ } catch (e) { ++ log('Unable to connect to the tracker extractor: ' + e.toString()); ++ } + +- // start miners +- this._startMiners(); ++ // start miners ++ this._startMiners(); + +- Mainloop.idle_add(Lang.bind(this, +- function() { + callback(); +- return GLib.SOURCE_REMOVE; + })); + }, + +-- +2.14.3 + + +From 95a69188445605be846adb94054a792c09b5e997 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Tue, 12 Dec 2017 16:35:22 +0100 +Subject: [PATCH 6/7] trackerController: Don't submit queries until started + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/trackerController.js | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/trackerController.js b/src/trackerController.js +index 05b7e89f1586..55f1343f1417 100644 +--- a/src/trackerController.js ++++ b/src/trackerController.js +@@ -283,6 +283,10 @@ const TrackerController = new Lang.Class({ + return; + + this.sortBy = sortBy; ++ ++ if (!this._isStarted) ++ return; ++ + this._refreshInternal(RefreshFlags.RESET_OFFSET); + }, + +-- +2.14.3 + + +From 9e57889aeaa9d56ca61059012cccc37a9145f92c Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 8 Dec 2017 20:47:17 +0100 +Subject: [PATCH 7/7] trackerController: Assert against premature queries + +The TrackerControllers are only supposed to issue their queries once +all the pieces of the application that are necessary to formulate them +have been initialized. This is indicated by the invocation of the start +method. For example, if the queries are submitted before the detection +of the getting started PDF has completed, then they won't have the +path to PDF and it will be missing from the UI. + +Throwing an exception forces one to think about the details surrounding +each query submission path, as opposed to having the silently dropping +the request. + +https://bugzilla.gnome.org/show_bug.cgi?id=791518 +--- + src/trackerController.js | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/trackerController.js b/src/trackerController.js +index 55f1343f1417..e45f3a7fc5c3 100644 +--- a/src/trackerController.js ++++ b/src/trackerController.js +@@ -234,7 +234,8 @@ const TrackerController = new Lang.Class({ + }, + + _refreshInternal: function(flags) { +- this._isStarted = true; ++ if (!this._isStarted) ++ throw(new Error('!this._isStarted')); + + if (flags & RefreshFlags.RESET_OFFSET) + this._offsetController.resetOffset(); +@@ -294,6 +295,7 @@ const TrackerController = new Lang.Class({ + if (this._isStarted) + return; + ++ this._isStarted = true; + this._refreshInternal(RefreshFlags.NONE); + } + }); +-- +2.14.3 + diff --git a/SOURCES/gnome-documents-new-gjs-gtk.patch b/SOURCES/gnome-documents-new-gjs-gtk.patch new file mode 100644 index 0000000..ba5219d --- /dev/null +++ b/SOURCES/gnome-documents-new-gjs-gtk.patch @@ -0,0 +1,1381 @@ +From b146e88462f01e7d3ce7d0bbb64739f02b2fa0f5 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Tue, 4 Apr 2017 20:08:51 +0200 +Subject: [PATCH 01/12] lokview: Adjust the LOKDocView detection to work with + GJS 1.48.0 + +https://bugzilla.redhat.com/show_bug.cgi?id=1517704 +--- + src/lokview.js | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/lokview.js b/src/lokview.js +index 3311b602f0f9..b55c91485999 100644 +--- a/src/lokview.js ++++ b/src/lokview.js +@@ -19,8 +19,10 @@ + * + */ + ++let LOKDocView; ++ + try { +- const LOKDocView = imports.gi.LOKDocView; ++ LOKDocView = imports.gi.LOKDocView; + } catch(e) { + // LOKDocView will be undefined, and we'll + // use this to warn when LO files can't be opened +-- +2.14.3 + + +From f830328f845a7f3cff93745b2d8baab576f679b1 Mon Sep 17 00:00:00 2001 +From: Cosimo Cecchi +Date: Mon, 31 Jul 2017 00:31:03 +0100 +Subject: [PATCH 02/12] Use 'var' for classes that are exported + +This avoids warnings with the new GJS. + +https://bugzilla.gnome.org/show_bug.cgi?id=785568 +--- + src/application.js | 44 ++++++++++++++++++++++---------------------- + src/changeMonitor.js | 4 ++-- + src/documents.js | 4 ++-- + src/embed.js | 2 +- + src/epubview.js | 2 +- + src/errorBox.js | 2 +- + src/evinceview.js | 2 +- + src/lokview.js | 2 +- + src/mainToolbar.js | 2 +- + src/mainWindow.js | 2 +- + src/manager.js | 4 ++-- + src/notifications.js | 2 +- + src/preview.js | 8 ++++---- + src/properties.js | 2 +- + src/query.js | 6 +++--- + src/search.js | 14 +++++++------- + src/searchbar.js | 2 +- + src/selections.js | 4 ++-- + src/shellSearchProvider.js | 14 +++++++------- + src/trackerController.js | 8 ++++---- + src/trackerUtils.js | 2 +- + src/view.js | 2 +- + src/windowMode.js | 4 ++-- + 23 files changed, 69 insertions(+), 69 deletions(-) + +diff --git a/src/application.js b/src/application.js +index f9e8b6ae9863..3163a36fa95e 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -49,30 +49,30 @@ const Utils = imports.utils; + const WindowMode = imports.windowMode; + + // used globally +-let application = null; +-let connection = null; +-let connectionQueue = null; +-let goaClient = null; +-let settings = null; ++var application = null; ++var connection = null; ++var connectionQueue = null; ++var goaClient = null; ++var settings = null; + + // used by the application, but not by the search provider +-let changeMonitor = null; ++var changeMonitor = null; + let cssProvider = null; +-let documentManager = null; +-let modeController = null; +-let notificationManager = null; +-let offsetCollectionsController = null; +-let offsetDocumentsController = null; +-let offsetSearchController = null; +-let queryBuilder = null; +-let searchController = null; +-let searchMatchManager = null; +-let searchTypeManager = null; +-let selectionController = null; +-let sourceManager = null; +-let trackerCollectionsController = null; +-let trackerDocumentsController = null; +-let trackerSearchController = null; ++var documentManager = null; ++var modeController = null; ++var notificationManager = null; ++var offsetCollectionsController = null; ++var offsetDocumentsController = null; ++var offsetSearchController = null; ++var queryBuilder = null; ++var searchController = null; ++var searchMatchManager = null; ++var searchTypeManager = null; ++var selectionController = null; ++var sourceManager = null; ++var trackerCollectionsController = null; ++var trackerDocumentsController = null; ++var trackerSearchController = null; + + const TrackerExtractPriorityIface = ' \ + \ +@@ -92,7 +92,7 @@ function TrackerExtractPriority() { + + const MINER_REFRESH_TIMEOUT = 60; /* seconds */ + +-const Application = new Lang.Class({ ++var Application = new Lang.Class({ + Name: 'Application', + Extends: Gtk.Application, + +diff --git a/src/changeMonitor.js b/src/changeMonitor.js +index 594a232bb76f..ab0e570d0141 100644 +--- a/src/changeMonitor.js ++++ b/src/changeMonitor.js +@@ -43,7 +43,7 @@ function TrackerResourcesService() { + '/org/freedesktop/Tracker1/Resources'); + } + +-const ChangeEventType = { ++var ChangeEventType = { + CHANGED: 0, + CREATED: 1, + DELETED: 2 +@@ -84,7 +84,7 @@ const ChangeEvent = new Lang.Class({ + const CHANGE_MONITOR_TIMEOUT = 500; // msecs + const CHANGE_MONITOR_MAX_ITEMS = 500; // items + +-const TrackerChangeMonitor = new Lang.Class({ ++var TrackerChangeMonitor = new Lang.Class({ + Name: 'TrackerChangeMonitor', + + _init: function() { +diff --git a/src/documents.js b/src/documents.js +index 7ff1c96444c1..92c8a269b8e1 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -789,7 +789,7 @@ const DocCommon = new Lang.Class({ + }); + Signals.addSignalMethods(DocCommon.prototype); + +-const LocalDocument = new Lang.Class({ ++var LocalDocument = new Lang.Class({ + Name: 'LocalDocument', + Extends: DocCommon, + +@@ -1432,7 +1432,7 @@ const SkydriveDocument = new Lang.Class({ + } + }); + +-const DocumentManager = new Lang.Class({ ++var DocumentManager = new Lang.Class({ + Name: 'DocumentManager', + Extends: Manager.BaseManager, + +diff --git a/src/embed.js b/src/embed.js +index 5014b3895276..47258712c6bc 100644 +--- a/src/embed.js ++++ b/src/embed.js +@@ -32,7 +32,7 @@ const GLib = imports.gi.GLib; + const Gtk = imports.gi.Gtk; + const _ = imports.gettext.gettext; + +-const Embed = new Lang.Class({ ++var Embed = new Lang.Class({ + Name: 'Embed', + Extends: Gtk.Box, + +diff --git a/src/epubview.js b/src/epubview.js +index 12f392225d6f..032b7bac51c2 100644 +--- a/src/epubview.js ++++ b/src/epubview.js +@@ -35,7 +35,7 @@ function isEpub(mimeType) { + return (mimeType == 'application/epub+zip'); + } + +-const EPUBView = new Lang.Class({ ++var EPUBView = new Lang.Class({ + Name: 'EPUBView', + Extends: Preview.Preview, + +diff --git a/src/errorBox.js b/src/errorBox.js +index 95ec791ab7e5..8fdf154cb4ae 100644 +--- a/src/errorBox.js ++++ b/src/errorBox.js +@@ -26,7 +26,7 @@ const Lang = imports.lang; + + const _ICON_SIZE = 128; + +-const ErrorBox = new Lang.Class({ ++var ErrorBox = new Lang.Class({ + Name: 'ErrorBox', + Extends: Gtk.Grid, + +diff --git a/src/evinceview.js b/src/evinceview.js +index 3e0070bb785c..874a94fbcdc1 100644 +--- a/src/evinceview.js ++++ b/src/evinceview.js +@@ -40,7 +40,7 @@ const WindowMode = imports.windowMode; + + const _FULLSCREEN_TOOLBAR_TIMEOUT = 2; // seconds + +-const EvinceView = new Lang.Class({ ++var EvinceView = new Lang.Class({ + Name: 'EvinceView', + Extends: Preview.Preview, + +diff --git a/src/lokview.js b/src/lokview.js +index b55c91485999..49bacabd28e7 100644 +--- a/src/lokview.js ++++ b/src/lokview.js +@@ -97,7 +97,7 @@ function isOpenDocumentFormat(mimeType) { + return false; + } + +-const LOKView = new Lang.Class({ ++var LOKView = new Lang.Class({ + Name: 'LOKView', + Extends: Preview.Preview, + +diff --git a/src/mainToolbar.js b/src/mainToolbar.js +index 14772c3482c8..6e7f972af57e 100644 +--- a/src/mainToolbar.js ++++ b/src/mainToolbar.js +@@ -32,7 +32,7 @@ const Lang = imports.lang; + const Application = imports.application; + const Searchbar = imports.searchbar; + +-const MainToolbar = new Lang.Class({ ++var MainToolbar = new Lang.Class({ + Name: 'MainToolbar', + Extends: Gtk.Box, + +diff --git a/src/mainWindow.js b/src/mainWindow.js +index 0cac142b1609..b3a9e890ecc8 100644 +--- a/src/mainWindow.js ++++ b/src/mainWindow.js +@@ -37,7 +37,7 @@ const _CONFIGURE_ID_TIMEOUT = 100; // msecs + const _WINDOW_MIN_WIDTH = 600; + const _WINDOW_MIN_HEIGHT = 500; + +-const MainWindow = new Lang.Class({ ++var MainWindow = new Lang.Class({ + Name: 'MainWindow', + Extends: Gtk.ApplicationWindow, + +diff --git a/src/manager.js b/src/manager.js +index 7252b31e1762..c7749e5754c6 100644 +--- a/src/manager.js ++++ b/src/manager.js +@@ -25,7 +25,7 @@ const GLib = imports.gi.GLib; + const Lang = imports.lang; + const Signals = imports.signals; + +-const BaseManager = new Lang.Class({ ++var BaseManager = new Lang.Class({ + Name: 'BaseManager', + + _init: function(title, actionId, context) { +@@ -174,7 +174,7 @@ const BaseManager = new Lang.Class({ + }); + Signals.addSignalMethods(BaseManager.prototype); + +-const BaseModel = new Lang.Class({ ++var BaseModel = new Lang.Class({ + Name: 'BaseModel', + Extends: Gio.Menu, + +diff --git a/src/notifications.js b/src/notifications.js +index 834d0790ebc0..3fd4d4ebd4dc 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -325,7 +325,7 @@ const IndexingNotification = new Lang.Class({ + } + }); + +-const NotificationManager = new Lang.Class({ ++var NotificationManager = new Lang.Class({ + Name: 'NotificationManager', + Extends: Gd.Notification, + +diff --git a/src/preview.js b/src/preview.js +index 29ca3f197f20..db657deba82c 100644 +--- a/src/preview.js ++++ b/src/preview.js +@@ -19,7 +19,7 @@ const Utils = imports.utils; + const _ICON_SIZE = 32; + const _PDF_LOADER_TIMEOUT = 400; + +-const Preview = new Lang.Class({ ++var Preview = new Lang.Class({ + Name: 'Preview', + Extends: Gtk.Stack, + +@@ -245,7 +245,7 @@ const Preview = new Lang.Class({ + } + }); + +-const PreviewToolbar = new Lang.Class({ ++var PreviewToolbar = new Lang.Class({ + Name: 'PreviewToolbar', + Extends: MainToolbar.MainToolbar, + +@@ -310,7 +310,7 @@ const PreviewToolbar = new Lang.Class({ + const _AUTO_HIDE_TIMEOUT = 2; + const PREVIEW_NAVBAR_MARGIN = 30; + +-const PreviewNavControls = new Lang.Class({ ++var PreviewNavControls = new Lang.Class({ + Name: 'PreviewNavControls', + + _init: function(preview, overlay) { +@@ -506,7 +506,7 @@ const PreviewNavControls = new Lang.Class({ + } + }); + +-const PreviewSearchbar = new Lang.Class({ ++var PreviewSearchbar = new Lang.Class({ + Name: 'PreviewSearchbar', + Extends: Searchbar.Searchbar, + +diff --git a/src/properties.js b/src/properties.js +index 80a142bcf1d5..3647ef35b51b 100644 +--- a/src/properties.js ++++ b/src/properties.js +@@ -35,7 +35,7 @@ const Lang = imports.lang; + + const _TITLE_ENTRY_TIMEOUT = 200; + +-const PropertiesDialog = new Lang.Class({ ++var PropertiesDialog = new Lang.Class({ + Name: 'PropertiesDialog', + Extends: Gtk.Dialog, + +diff --git a/src/query.js b/src/query.js +index 9d45b9fa9088..744527bf96fb 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -26,7 +26,7 @@ const GLib = imports.gi.GLib; + const Lang = imports.lang; + const Search = imports.search; + +-const QueryColumns = { ++var QueryColumns = { + URN: 0, + URI: 1, + FILENAME: 2, +@@ -41,7 +41,7 @@ const QueryColumns = { + DATE_CREATED: 11 + }; + +-const QueryFlags = { ++var QueryFlags = { + NONE: 0, + UNFILTERED: 1 << 0, + COLLECTIONS: 1 << 1, +@@ -52,7 +52,7 @@ const QueryFlags = { + const LOCAL_BOOKS_COLLECTIONS_IDENTIFIER = 'gb:collection:local:'; + const LOCAL_DOCUMENTS_COLLECTIONS_IDENTIFIER = 'gd:collection:local:'; + +-const QueryBuilder = new Lang.Class({ ++var QueryBuilder = new Lang.Class({ + Name: 'QueryBuilder', + + _init: function(context) { +diff --git a/src/search.js b/src/search.js +index 681002010b34..54e16c2a9b96 100644 +--- a/src/search.js ++++ b/src/search.js +@@ -99,7 +99,7 @@ const SearchType = new Lang.Class({ + } + }); + +-const SearchTypeStock = { ++var SearchTypeStock = { + ALL: 'all', + COLLECTIONS: 'collections', + PDF: 'pdf', +@@ -201,7 +201,7 @@ const SearchTypeManager = new Lang.Class({ + } + }); + +-const SearchMatchStock = { ++var SearchMatchStock = { + ALL: 'all', + TITLE: 'title', + AUTHOR: 'author', +@@ -316,7 +316,7 @@ const SearchMatchManager = new Lang.Class({ + } + }); + +-const SearchSourceStock = { ++var SearchSourceStock = { + ALL: 'all', + LOCAL: 'local' + }; +@@ -556,7 +556,7 @@ const SourceManager = new Lang.Class({ + } + }); + +-const OFFSET_STEP = 50; ++var OFFSET_STEP = 50; + + const OffsetController = new Lang.Class({ + Name: 'OffsetController', +@@ -628,7 +628,7 @@ const OffsetController = new Lang.Class({ + }); + Signals.addSignalMethods(OffsetController.prototype); + +-const OffsetCollectionsController = new Lang.Class({ ++var OffsetCollectionsController = new Lang.Class({ + Name: 'OffsetCollectionsController', + Extends: OffsetController, + +@@ -649,7 +649,7 @@ const OffsetCollectionsController = new Lang.Class({ + } + }); + +-const OffsetDocumentsController = new Lang.Class({ ++var OffsetDocumentsController = new Lang.Class({ + Name: 'OffsetDocumentsController', + Extends: OffsetController, + +@@ -662,7 +662,7 @@ const OffsetDocumentsController = new Lang.Class({ + } + }); + +-const OffsetSearchController = new Lang.Class({ ++var OffsetSearchController = new Lang.Class({ + Name: 'OffsetSearchController', + Extends: OffsetController, + +diff --git a/src/searchbar.js b/src/searchbar.js +index c560063a7034..9131d1369bf7 100644 +--- a/src/searchbar.js ++++ b/src/searchbar.js +@@ -30,7 +30,7 @@ const Application = imports.application; + const Manager = imports.manager; + const Utils = imports.utils; + +-const Searchbar = new Lang.Class({ ++var Searchbar = new Lang.Class({ + Name: 'Searchbar', + Extends: Gtk.SearchBar, + +diff --git a/src/selections.js b/src/selections.js +index ecfd3ec694c7..3693ad8b0448 100644 +--- a/src/selections.js ++++ b/src/selections.js +@@ -793,7 +793,7 @@ const OrganizeCollectionDialog = new Lang.Class({ + } + }); + +-const SelectionController = new Lang.Class({ ++var SelectionController = new Lang.Class({ + Name: 'SelectionController', + + _init: function() { +@@ -858,7 +858,7 @@ Signals.addSignalMethods(SelectionController.prototype); + + const _SELECTION_TOOLBAR_DEFAULT_WIDTH = 500; + +-const SelectionToolbar = new Lang.Class({ ++var SelectionToolbar = new Lang.Class({ + Name: 'SelectionToolbar', + Extends: Gtk.ActionBar, + Template: 'resource:///org/gnome/Documents/ui/selection-toolbar.ui', +diff --git a/src/shellSearchProvider.js b/src/shellSearchProvider.js +index 0dd54f1dd2a9..6fb9763546b2 100644 +--- a/src/shellSearchProvider.js ++++ b/src/shellSearchProvider.js +@@ -33,12 +33,12 @@ const Query = imports.query; + const TrackerUtils = imports.trackerUtils; + const Utils = imports.utils; + +-let documentManager = null; +-let queryBuilder = null; +-let searchMatchManager = null; +-let searchTypeManager = null; +-let searchController = null; +-let sourceManager = null; ++var documentManager = null; ++var queryBuilder = null; ++var searchMatchManager = null; ++var searchTypeManager = null; ++var searchController = null; ++var sourceManager = null; + + const SEARCH_PROVIDER_IFACE = 'org.gnome.Shell.SearchProvider2'; + const SEARCH_PROVIDER_PATH = '/org/gnome/Documents/SearchProvider'; +@@ -348,7 +348,7 @@ const FetchIdsJob = new Lang.Class({ + } + }); + +-const ShellSearchProvider = new Lang.Class({ ++var ShellSearchProvider = new Lang.Class({ + Name: 'ShellSearchProvider', + + _init: function() { +diff --git a/src/trackerController.js b/src/trackerController.js +index 836f7c4ae024..05b7e89f1586 100644 +--- a/src/trackerController.js ++++ b/src/trackerController.js +@@ -37,7 +37,7 @@ const QueryType = { + UPDATE_BLANK: 2 + }; + +-const TrackerConnectionQueue = new Lang.Class({ ++var TrackerConnectionQueue = new Lang.Class({ + Name: 'TrackerConnectionQueue', + + _init: function() { +@@ -295,7 +295,7 @@ const TrackerController = new Lang.Class({ + }); + Signals.addSignalMethods(TrackerController.prototype); + +-const TrackerCollectionsController = new Lang.Class({ ++var TrackerCollectionsController = new Lang.Class({ + Name: 'TrackerCollectionsController', + Extends: TrackerController, + +@@ -329,7 +329,7 @@ const TrackerCollectionsController = new Lang.Class({ + }, + }); + +-const TrackerDocumentsController = new Lang.Class({ ++var TrackerDocumentsController = new Lang.Class({ + Name: 'TrackerDocumentsController', + Extends: TrackerController, + +@@ -348,7 +348,7 @@ const TrackerDocumentsController = new Lang.Class({ + }, + }); + +-const TrackerSearchController = new Lang.Class({ ++var TrackerSearchController = new Lang.Class({ + Name: 'TrackerSearchController', + Extends: TrackerController, + +diff --git a/src/trackerUtils.js b/src/trackerUtils.js +index 97f236956535..f54fb2d66577 100644 +--- a/src/trackerUtils.js ++++ b/src/trackerUtils.js +@@ -40,7 +40,7 @@ function setEditedName(newTitle, docId, callback) { + + } + +-const SingleItemJob = new Lang.Class({ ++var SingleItemJob = new Lang.Class({ + Name: 'SingleItemJob', + + _init: function(urn, queryBuilder) { +diff --git a/src/view.js b/src/view.js +index 286654fe668e..6ec4abf90fb3 100644 +--- a/src/view.js ++++ b/src/view.js +@@ -728,7 +728,7 @@ const ViewContainer = new Lang.Class({ + } + }); + +-const View = new Lang.Class({ ++var View = new Lang.Class({ + Name: 'View', + Extends: Gtk.Overlay, + +diff --git a/src/windowMode.js b/src/windowMode.js +index d8527c52f436..0d062c66c1f3 100644 +--- a/src/windowMode.js ++++ b/src/windowMode.js +@@ -22,7 +22,7 @@ + const Lang = imports.lang; + const Signals = imports.signals; + +-const WindowMode = { ++var WindowMode = { + NONE: 0, + DOCUMENTS: 1, + PREVIEW_EV: 2, +@@ -33,7 +33,7 @@ const WindowMode = { + SEARCH: 7, + }; + +-const ModeController = new Lang.Class({ ++var ModeController = new Lang.Class({ + Name: 'ModeController', + + _init: function() { +-- +2.14.3 + + +From b73c93e420a88e739fbbc4e16ea9d887560f4b46 Mon Sep 17 00:00:00 2001 +From: Jeremy Bicha +Date: Sun, 6 Aug 2017 21:01:59 -0400 +Subject: [PATCH 03/12] Use 'var' for more classes that are exported + +This avoids warnings with the new GJS. + +https://bugzilla.gnome.org/show_bug.cgi?id=785568 +--- + src/notifications.js | 4 ++-- + src/presentation.js | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/notifications.js b/src/notifications.js +index 3fd4d4ebd4dc..b1b947f52231 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -34,7 +34,7 @@ const Signals = imports.signals; + + const DELETE_TIMEOUT = 10; // seconds + +-const DeleteNotification = new Lang.Class({ ++var DeleteNotification = new Lang.Class({ + Name: 'DeleteNotification', + + _init: function(docs) { +@@ -110,7 +110,7 @@ const DeleteNotification = new Lang.Class({ + } + }); + +-const PrintNotification = new Lang.Class({ ++var PrintNotification = new Lang.Class({ + Name: 'PrintNotification', + + _init: function(printOp, doc) { +diff --git a/src/presentation.js b/src/presentation.js +index 5a4535cec098..741f01e5a6c1 100644 +--- a/src/presentation.js ++++ b/src/presentation.js +@@ -29,7 +29,7 @@ const Utils = imports.utils; + + const Application = imports.application; + +-const PresentationWindow = new Lang.Class({ ++var PresentationWindow = new Lang.Class({ + Name: 'PresentationWindow', + Extends: Gtk.Window, + +@@ -225,7 +225,7 @@ const PresentationOutputChooser = new Lang.Class({ + }); + Utils.addJSSignalMethods(PresentationOutputChooser.prototype); + +-const PresentationOutputs = new Lang.Class({ ++var PresentationOutputs = new Lang.Class({ + Name: 'PresentationOutputs', + + _init: function() { +-- +2.14.3 + + +From 054ea2802f7187622d81051832c90a9080b7db58 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 29 Nov 2017 19:02:20 +0100 +Subject: [PATCH 04/12] Use 'var' for more classes that are exported + +This avoids warnings with GJS 1.50. + +https://bugzilla.gnome.org/show_bug.cgi?id=785568 +--- + src/edit.js | 2 +- + src/mainToolbar.js | 2 +- + src/password.js | 2 +- + src/places.js | 2 +- + src/presentation.js | 2 +- + src/search.js | 2 +- + src/searchbar.js | 2 +- + src/sharing.js | 2 +- + 8 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/edit.js b/src/edit.js +index c07abe6e4a88..93e6545472ae 100644 +--- a/src/edit.js ++++ b/src/edit.js +@@ -32,7 +32,7 @@ const WindowMode = imports.windowMode; + + const _BLANK_URI = "about:blank"; + +-const EditView = new Lang.Class({ ++var EditView = new Lang.Class({ + Name: 'EditView', + Extends: Preview.Preview, + +diff --git a/src/mainToolbar.js b/src/mainToolbar.js +index 6e7f972af57e..f356de3bbdc8 100644 +--- a/src/mainToolbar.js ++++ b/src/mainToolbar.js +@@ -130,7 +130,7 @@ var MainToolbar = new Lang.Class({ + } + }); + +-const OverviewToolbar = new Lang.Class({ ++var OverviewToolbar = new Lang.Class({ + Name: 'OverviewToolbar', + Extends: MainToolbar, + +diff --git a/src/password.js b/src/password.js +index 09be1676c3dd..5a179be92982 100644 +--- a/src/password.js ++++ b/src/password.js +@@ -26,7 +26,7 @@ const Application = imports.application; + + const Lang = imports.lang; + +-const PasswordDialog = new Lang.Class({ ++var PasswordDialog = new Lang.Class({ + Name: 'PasswordDialog', + Extends: Gtk.Dialog, + +diff --git a/src/places.js b/src/places.js +index 5023b80ed62e..220cd3119a82 100644 +--- a/src/places.js ++++ b/src/places.js +@@ -25,7 +25,7 @@ const Application = imports.application; + + const Lang = imports.lang; + +-const PlacesDialog = new Lang.Class({ ++var PlacesDialog = new Lang.Class({ + Name: 'PlacesDialog', + Extends: Gtk.Dialog, + +diff --git a/src/presentation.js b/src/presentation.js +index 741f01e5a6c1..33b3322cf6ac 100644 +--- a/src/presentation.js ++++ b/src/presentation.js +@@ -111,7 +111,7 @@ var PresentationWindow = new Lang.Class({ + } + }); + +-const PresentationOutputChooser = new Lang.Class({ ++var PresentationOutputChooser = new Lang.Class({ + Name: 'PresentationOutputChooser', + Extends: Gtk.Dialog, + +diff --git a/src/search.js b/src/search.js +index 54e16c2a9b96..ff26a225a9e2 100644 +--- a/src/search.js ++++ b/src/search.js +@@ -42,7 +42,7 @@ function initSearch(context) { + context.queryBuilder = new Query.QueryBuilder(context); + }; + +-const SearchState = new Lang.Class({ ++var SearchState = new Lang.Class({ + Name: 'SearchState', + + _init: function(searchMatch, searchType, source, str) { +diff --git a/src/searchbar.js b/src/searchbar.js +index 9131d1369bf7..30a29cef5a03 100644 +--- a/src/searchbar.js ++++ b/src/searchbar.js +@@ -146,7 +146,7 @@ const Dropdown = new Lang.Class({ + } + }); + +-const OverviewSearchbar = new Lang.Class({ ++var OverviewSearchbar = new Lang.Class({ + Name: 'OverviewSearchbar', + Extends: Searchbar, + +diff --git a/src/sharing.js b/src/sharing.js +index 9af15ab224bb..88958d539522 100644 +--- a/src/sharing.js ++++ b/src/sharing.js +@@ -68,7 +68,7 @@ const DocumentUpdateType = { + DELETE_SHARE_LINK: 4 + }; + +-const SharingDialog = new Lang.Class({ ++var SharingDialog = new Lang.Class({ + Name: 'SharingDialog', + Extends: Gtk.Dialog, + +-- +2.14.3 + + +From 422982b395b63218c77a013645efdd815ba00977 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 29 Nov 2017 19:15:24 +0100 +Subject: [PATCH 05/12] Explicitly specify the Gepub API version + +--- + src/main.js | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/main.js b/src/main.js +index 78f1475f6164..8ed772004b39 100644 +--- a/src/main.js ++++ b/src/main.js +@@ -28,6 +28,7 @@ pkg.initSubmodule('src'); + pkg.require({ 'EvinceDocument': '3.0', + 'Gd': '1.0', + 'GdPrivate': '1.0', ++ 'Gepub': '0.4', + 'Gio': '2.0', + 'GLib': '2.0', + 'Goa': '1.0', +-- +2.14.3 + + +From 715ca106de7e6aee57b91b000b9dca7b79fb0dc5 Mon Sep 17 00:00:00 2001 +From: Cosimo Cecchi +Date: Sun, 27 Nov 2016 13:16:51 +0100 +Subject: [PATCH 06/12] notifications: don't use GdNotification + +These days we can just use a GtkRevealer with the right style class. +--- + src/notifications.js | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/src/notifications.js b/src/notifications.js +index b1b947f52231..c9217ec89f78 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -327,17 +327,20 @@ const IndexingNotification = new Lang.Class({ + + var NotificationManager = new Lang.Class({ + Name: 'NotificationManager', +- Extends: Gd.Notification, ++ Extends: Gtk.Revealer, + + _init: function() { +- this.parent({ timeout: -1, +- show_close_button: false, +- halign: Gtk.Align.CENTER, ++ this.parent({ halign: Gtk.Align.CENTER, + valign: Gtk.Align.START }); ++ ++ let frame = new Gtk.Frame(); ++ frame.get_style_context().add_class('app-notification'); ++ this.add(frame); ++ + this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.VERTICAL, + row_spacing: 6 }); + +- this.add(this._grid); ++ frame.add(this._grid); + + // add indexing monitor notification + this._indexingNotification = new IndexingNotification(); +@@ -348,13 +351,14 @@ var NotificationManager = new Lang.Class({ + notification.widget.connect('destroy', Lang.bind(this, this._onWidgetDestroy)); + + this.show_all(); ++ this.reveal_child = true; + }, + + _onWidgetDestroy: function() { + let children = this._grid.get_children(); + + if (children.length == 0) +- this.hide(); ++ this.reveal_child = false; + } + }); + Signals.addSignalMethods(NotificationManager.prototype); +-- +2.14.3 + + +From 9fc3185bb6cf4fcd4ae382bdab5cac403b73fbae Mon Sep 17 00:00:00 2001 +From: Cosimo Cecchi +Date: Sat, 11 Feb 2017 15:22:02 -0800 +Subject: [PATCH 07/12] notifications: don't use signal decorator + +We don't have any signal, and these override GObject methods. +--- + src/notifications.js | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/notifications.js b/src/notifications.js +index c9217ec89f78..843ccdd2d74b 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -30,7 +30,6 @@ const WindowMode = imports.windowMode; + + const Lang = imports.lang; + const Mainloop = imports.mainloop; +-const Signals = imports.signals; + + const DELETE_TIMEOUT = 10; // seconds + +@@ -361,4 +360,3 @@ var NotificationManager = new Lang.Class({ + this.reveal_child = false; + } + }); +-Signals.addSignalMethods(NotificationManager.prototype); +-- +2.14.3 + + +From 64bbf0e96ac3fe46a02ce4e42b4f533cfd0f9213 Mon Sep 17 00:00:00 2001 +From: Cosimo Cecchi +Date: Sat, 1 Apr 2017 15:28:59 -0700 +Subject: [PATCH 08/12] application: remove unused signal argument + +--- + src/application.js | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 3163a36fa95e..fc71ffa153d0 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -303,7 +303,7 @@ var Application = new Lang.Class({ + return false; + + this.minersRunning.push(miner); +- this.emitJS('miners-changed', this.minersRunning); ++ this.emitJS('miners-changed'); + + miner._cancellable = new Gio.Cancellable(); + miner.RefreshDBRemote(['documents'], miner._cancellable, Lang.bind(this, +@@ -312,7 +312,7 @@ var Application = new Lang.Class({ + function(element) { + return element != miner; + }); +- this.emitJS('miners-changed', this.minersRunning); ++ this.emitJS('miners-changed'); + + if (error) { + if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) +-- +2.14.3 + + +From 25150ca9b99b83ccd306efc626a878fef708e93d Mon Sep 17 00:00:00 2001 +From: Cosimo Cecchi +Date: Sat, 1 Apr 2017 15:41:03 -0700 +Subject: [PATCH 09/12] Remove Utils.addJSSignalMethods() + +We can use GObject signals and remove this quirk. +--- + src/application.js | 10 ++++++---- + src/embed.js | 4 ++-- + src/evinceview.js | 21 ++++++++++++++------- + src/notifications.js | 2 +- + src/presentation.js | 11 +++++++---- + src/searchbar.js | 7 ++++--- + src/utils.js | 7 ------- + 7 files changed, 34 insertions(+), 28 deletions(-) + +diff --git a/src/application.js b/src/application.js +index fc71ffa153d0..40506d48627b 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -95,6 +95,9 @@ const MINER_REFRESH_TIMEOUT = 60; /* seconds */ + var Application = new Lang.Class({ + Name: 'Application', + Extends: Gtk.Application, ++ Signals: { ++ 'miners-changed': {} ++ }, + + _init: function(isBooks) { + this.minersRunning = []; +@@ -303,7 +306,7 @@ var Application = new Lang.Class({ + return false; + + this.minersRunning.push(miner); +- this.emitJS('miners-changed'); ++ this.emit('miners-changed'); + + miner._cancellable = new Gio.Cancellable(); + miner.RefreshDBRemote(['documents'], miner._cancellable, Lang.bind(this, +@@ -312,7 +315,7 @@ var Application = new Lang.Class({ + function(element) { + return element != miner; + }); +- this.emitJS('miners-changed'); ++ this.emit('miners-changed'); + + if (error) { + if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) +@@ -386,6 +389,7 @@ var Application = new Lang.Class({ + function(miner) { + miner._cancellable.cancel(); + })); ++ this.minersRunning = []; + + this.gdataMiner = null; + this.owncloudMiner = null; +@@ -570,7 +574,6 @@ var Application = new Lang.Class({ + trackerSearchController.disconnectAll(); + selectionController.disconnectAll(); + modeController.disconnectAll(); +- this.disconnectAllJS(); + + // reset state + documentManager.clearRowRefs(); +@@ -659,4 +662,3 @@ var Application = new Lang.Class({ + return window; + } + }); +-Utils.addJSSignalMethods(Application.prototype); +diff --git a/src/embed.js b/src/embed.js +index 47258712c6bc..a028f2a0b6ce 100644 +--- a/src/embed.js ++++ b/src/embed.js +@@ -129,8 +129,8 @@ var Embed = new Lang.Class({ + // pack the toolbar + this._toolbar = this._view.createToolbar(); + if (this._toolbar.searchbar) +- this._toolbar.searchbar.connectJS('activate-result', +- Lang.bind(this, this._onActivateResult)); ++ this._toolbar.searchbar.connect('activate-result', ++ Lang.bind(this, this._onActivateResult)); + this._titlebar.add(this._toolbar); + } + }, +diff --git a/src/evinceview.js b/src/evinceview.js +index 874a94fbcdc1..b1ef1b9e0046 100644 +--- a/src/evinceview.js ++++ b/src/evinceview.js +@@ -24,6 +24,7 @@ const EvView = imports.gi.EvinceView; + const GdPrivate = imports.gi.GdPrivate; + const Gio = imports.gi.Gio; + const GLib = imports.gi.GLib; ++const GObject = imports.gi.GObject; + const Gtk = imports.gi.Gtk; + const _ = imports.gettext.gettext; + +@@ -43,6 +44,11 @@ const _FULLSCREEN_TOOLBAR_TIMEOUT = 2; // seconds + var EvinceView = new Lang.Class({ + Name: 'EvinceView', + Extends: Preview.Preview, ++ Signals: { ++ 'search-changed': { ++ param_types: [GObject.TYPE_BOOLEAN] ++ } ++ }, + + _init: function(overlay, mainWindow) { + this._model = null; +@@ -331,7 +337,7 @@ var EvinceView = new Lang.Class({ + this._showPresentation(); + } else { + let chooser = new Presentation.PresentationOutputChooser(outputs); +- chooser.connectJS('output-activated', Lang.bind(this, ++ chooser.connect('output-activated', Lang.bind(this, + function(chooser, output) { + if (output) { + this._showPresentation(output); +@@ -450,7 +456,7 @@ var EvinceView = new Lang.Class({ + this._fsToolbar.setModel(this._model); + this.overlay.add_overlay(this._fsToolbar); + +- this._fsToolbar.connectJS('show-controls', Lang.bind(this, ++ this._fsToolbar.connect('show-controls', Lang.bind(this, + function() { + this.controlsVisible = true; + })); +@@ -571,7 +577,7 @@ var EvinceView = new Lang.Class({ + // FIXME: ev_job_find_get_results() returns a GList ** + // and thus is not introspectable + GdPrivate.ev_view_find_changed(this._evView, job, page); +- this.emitJS('search-changed', job.has_results()); ++ this.emit('search-changed', job.has_results()); + }, + + _loadMetadata: function() { +@@ -636,7 +642,6 @@ var EvinceView = new Lang.Class({ + return this._evView; + } + }); +-Utils.addJSSignalMethods(EvinceView.prototype); + + const EvinceViewNavControls = new Lang.Class({ + Name: 'EvinceViewNavControls', +@@ -734,7 +739,7 @@ const EvinceViewSearchbar = new Lang.Class({ + _init: function(preview) { + this.parent(preview); + +- this.preview.connectJS('search-changed', Lang.bind(this, this._onSearchChanged)); ++ this.preview.connect('search-changed', Lang.bind(this, this._onSearchChanged)); + this._onSearchChanged(this.preview, false); + }, + +@@ -762,6 +767,9 @@ const EvinceViewSearchbar = new Lang.Class({ + const EvinceViewFullscreenToolbar = new Lang.Class({ + Name: 'EvinceViewFullscreenToolbar', + Extends: Gtk.Revealer, ++ Signals: { ++ 'show-controls': {} ++ }, + + _init: function(previewView) { + this.parent({ valign: Gtk.Align.START }); +@@ -782,7 +790,7 @@ const EvinceViewFullscreenToolbar = new Lang.Class({ + function(actionGroup, actionName, value) { + let state = value.get_boolean(); + if (state) +- this.emitJS('show-controls'); ++ this.emit('show-controls'); + })); + + signalIds.push(signalId); +@@ -814,4 +822,3 @@ const EvinceViewFullscreenToolbar = new Lang.Class({ + Application.application.change_action_state('search', GLib.Variant.new('b', false)); + } + }); +-Utils.addJSSignalMethods(EvinceViewFullscreenToolbar.prototype); +diff --git a/src/notifications.js b/src/notifications.js +index 843ccdd2d74b..914bbb8db431 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -185,7 +185,7 @@ const IndexingNotification = new Lang.Class({ + return; + } + +- Application.application.connectJS('miners-changed', Lang.bind(this, this._checkNotification)); ++ Application.application.connect('miners-changed', Lang.bind(this, this._checkNotification)); + Application.modeController.connect('window-mode-changed', Lang.bind(this, this._checkNotification)); + }, + +diff --git a/src/presentation.js b/src/presentation.js +index 33b3322cf6ac..36290d0d4abc 100644 +--- a/src/presentation.js ++++ b/src/presentation.js +@@ -25,7 +25,6 @@ const Gtk = imports.gi.Gtk; + const _ = imports.gettext.gettext; + + const Lang = imports.lang; +-const Utils = imports.utils; + + const Application = imports.application; + +@@ -114,6 +113,11 @@ var PresentationWindow = new Lang.Class({ + var PresentationOutputChooser = new Lang.Class({ + Name: 'PresentationOutputChooser', + Extends: Gtk.Dialog, ++ Signals: { ++ 'output-activated': { ++ param_types: [GnomeDesktop.RROutputInfo.$gtype] ++ } ++ }, + + _init: function(outputs) { + let toplevel = Application.application.get_windows()[0]; +@@ -185,7 +189,7 @@ var PresentationOutputChooser = new Lang.Class({ + return; + + this.output = output; +- this.emitJS('output-activated', this.output); ++ this.emit('output-activated', this.output); + this.close(); + }, + +@@ -196,7 +200,7 @@ var PresentationOutputChooser = new Lang.Class({ + _createWindow: function() { + this.connect('response', Lang.bind(this, + function(widget, response) { +- this.emitJS('output-activated', null); ++ this.emit('output-activated', null); + })); + + let frame = new Gtk.Frame({ shadow_type: Gtk.ShadowType.IN }); +@@ -223,7 +227,6 @@ var PresentationOutputChooser = new Lang.Class({ + contentArea.pack_start(frame, true, false, 0); + } + }); +-Utils.addJSSignalMethods(PresentationOutputChooser.prototype); + + var PresentationOutputs = new Lang.Class({ + Name: 'PresentationOutputs', +diff --git a/src/searchbar.js b/src/searchbar.js +index 30a29cef5a03..2dc23d1900eb 100644 +--- a/src/searchbar.js ++++ b/src/searchbar.js +@@ -28,11 +28,13 @@ const Lang = imports.lang; + + const Application = imports.application; + const Manager = imports.manager; +-const Utils = imports.utils; + + var Searchbar = new Lang.Class({ + Name: 'Searchbar', + Extends: Gtk.SearchBar, ++ Signals: { ++ 'activate-result': {} ++ }, + + _init: function() { + this.searchChangeBlocked = false; +@@ -94,7 +96,7 @@ var Searchbar = new Lang.Class({ + + let keyval = event.get_keyval()[1]; + if (this.search_mode_enabled && keyval == Gdk.KEY_Return) { +- this.emitJS('activate-result'); ++ this.emit('activate-result'); + return true; + } + +@@ -115,7 +117,6 @@ var Searchbar = new Lang.Class({ + this.searchEntry.set_text(''); + } + }); +-Utils.addJSSignalMethods(Searchbar.prototype); + + const Dropdown = new Lang.Class({ + Name: 'Dropdown', +diff --git a/src/utils.js b/src/utils.js +index dfdcd974ad6d..bb45adfd7fae 100644 +--- a/src/utils.js ++++ b/src/utils.js +@@ -114,13 +114,6 @@ function debug(str) { + log('DEBUG: ' + str); + } + +-function addJSSignalMethods(proto) { +- proto.connectJS = Signals._connect; +- proto.disconnectJS = Signals._disconnect; +- proto.emitJS = Signals._emit; +- proto.disconnectAllJS = Signals._disconnectAll; +-} +- + function actionToggleCallback(action) { + let state = action.get_state(); + action.change_state(GLib.Variant.new('b', !state.get_boolean())); +-- +2.14.3 + + +From 5857b6f0bfa45c4f596f717aabe6797f2e8b1f62 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 7 Dec 2017 14:32:31 +0100 +Subject: [PATCH 10/12] preview: Use 'var' for exported constant + +This avoids warnings with GJS 1.50. + +https://bugzilla.gnome.org/show_bug.cgi?id=785568 +--- + src/preview.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/preview.js b/src/preview.js +index db657deba82c..fb1116b8a804 100644 +--- a/src/preview.js ++++ b/src/preview.js +@@ -308,7 +308,7 @@ var PreviewToolbar = new Lang.Class({ + }); + + const _AUTO_HIDE_TIMEOUT = 2; +-const PREVIEW_NAVBAR_MARGIN = 30; ++var PREVIEW_NAVBAR_MARGIN = 30; + + var PreviewNavControls = new Lang.Class({ + Name: 'PreviewNavControls', +-- +2.14.3 + + +From cc612448f5afc3b80c5da6acde4f33eb4747eb3c Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 14 Dec 2017 14:36:49 +0100 +Subject: [PATCH 11/12] notifications, query: Use 'var' for exported constant + +This avoids warnings with GJS 1.50. + +https://bugzilla.gnome.org/show_bug.cgi?id=785568 +--- + src/notifications.js | 2 +- + src/query.js | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/notifications.js b/src/notifications.js +index 914bbb8db431..6a6c773b6cbe 100644 +--- a/src/notifications.js ++++ b/src/notifications.js +@@ -31,7 +31,7 @@ const WindowMode = imports.windowMode; + const Lang = imports.lang; + const Mainloop = imports.mainloop; + +-const DELETE_TIMEOUT = 10; // seconds ++var DELETE_TIMEOUT = 10; // seconds + + var DeleteNotification = new Lang.Class({ + Name: 'DeleteNotification', +diff --git a/src/query.js b/src/query.js +index 744527bf96fb..1c156f1febee 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -49,8 +49,8 @@ var QueryFlags = { + SEARCH: 1 << 3 + }; + +-const LOCAL_BOOKS_COLLECTIONS_IDENTIFIER = 'gb:collection:local:'; +-const LOCAL_DOCUMENTS_COLLECTIONS_IDENTIFIER = 'gd:collection:local:'; ++var LOCAL_BOOKS_COLLECTIONS_IDENTIFIER = 'gb:collection:local:'; ++var LOCAL_DOCUMENTS_COLLECTIONS_IDENTIFIER = 'gd:collection:local:'; + + var QueryBuilder = new Lang.Class({ + Name: 'QueryBuilder', +-- +2.14.3 + + +From 7c8a381977467d0468423475207b83fce6a14a7f Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 14 Dec 2017 14:25:31 +0100 +Subject: [PATCH 12/12] documents, query: Use the standard dialect of + String.prototype.replace + +The Gecko-specific dialect doesn't work with GJS 1.50. + +https://bugzilla.gnome.org/show_bug.cgi?id=791613 +--- + src/documents.js | 2 +- + src/query.js | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index 92c8a269b8e1..9f8b54edaf76 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -274,7 +274,7 @@ const DocCommon = new Lang.Class({ + }, + + _sanitizeTitle: function() { +- this.name = this.name.replace('Microsoft Word - ', '', 'g'); ++ this.name = this.name.replace(/Microsoft Word - /g, ''); + }, + + populateFromCursor: function(cursor) { +diff --git a/src/query.js b/src/query.js +index 1c156f1febee..554ce1357a1c 100644 +--- a/src/query.js ++++ b/src/query.js +@@ -199,7 +199,7 @@ var QueryBuilder = new Lang.Class({ + + buildSingleQuery: function(flags, resource) { + let sparql = this._buildQueryInternal(false, flags, null); +- sparql = sparql.replace('?urn', '<' + resource + '>', 'g'); ++ sparql = sparql.replace(/\?urn/g, '<' + resource + '>'); + + return this._createQuery(sparql); + }, +@@ -223,7 +223,7 @@ var QueryBuilder = new Lang.Class({ + 'tracker:coalesce(nfo:fileLastModified(?urn), nie:contentLastModified(?urn)) AS ?mtime ' + + 'WHERE { ?urn nie:isPartOf ?collUrn } ' + + 'ORDER BY DESC (?mtime)' + +- 'LIMIT 4').replace('?collUrn', '<' + resource + '>'); ++ 'LIMIT 4').replace(/\?collUrn/, '<' + resource + '>'); + + return this._createQuery(sparql); + }, +@@ -234,7 +234,7 @@ var QueryBuilder = new Lang.Class({ + ('SELECT ' + + '?urn ' + + 'WHERE { ?urn a nfo:DataContainer . ?docUrn nie:isPartOf ?urn }' +- ).replace('?docUrn', '<' + resource + '>'); ++ ).replace(/\?docUrn/, '<' + resource + '>'); + + return this._createQuery(sparql); + }, +-- +2.14.3 + diff --git a/SOURCES/gnome-documents-skydrive-printing-and-lok-fixes.patch b/SOURCES/gnome-documents-skydrive-printing-and-lok-fixes.patch new file mode 100644 index 0000000..262eadd --- /dev/null +++ b/SOURCES/gnome-documents-skydrive-printing-and-lok-fixes.patch @@ -0,0 +1,1520 @@ +From 4ba7db7a91de431134c23bd2b43ca4e5e63e2bac Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 29 Mar 2017 16:04:08 +0200 +Subject: [PATCH 01/16] documents: Simplify calculation of thumbnail paths for + GoogleDocuments + +https://bugzilla.gnome.org/show_bug.cgi?id=780718 +--- + src/documents.js | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index 50cfbdafc7ee..2071882218b2 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -30,6 +30,7 @@ const GdPrivate = imports.gi.GdPrivate; + const Gdk = imports.gi.Gdk; + const GData = imports.gi.GData; + const GLib = imports.gi.GLib; ++const GnomeDesktop = imports.gi.GnomeDesktop; + const Gtk = imports.gi.Gtk; + const Zpj = imports.gi.Zpj; + const _ = imports.gettext.gettext; +@@ -916,12 +917,10 @@ const GoogleDocument = new Lang.Class({ + authorization_domain: authorizationDomain, + download_uri: uri }); + +- let checksum = new GLib.Checksum(GLib.ChecksumType.MD5); +- checksum.update(this.uri, -1); +- let dirPath = GLib.build_filenamev([GLib.get_user_cache_dir(), "thumbnails", "normal"]); ++ let path = GnomeDesktop.desktop_thumbnail_path_for_uri (this.uri, ++ GnomeDesktop.DesktopThumbnailSize.NORMAL); ++ let dirPath = GLib.path_get_dirname(path); + GLib.mkdir_with_parents(dirPath, 448); +- let basename = checksum.get_string() + '.png'; +- let path = GLib.build_filenamev([dirPath, basename]) + + let downloadFile = Gio.File.new_for_path(path); + downloadFile.replace_async +-- +2.9.4 + + +From 7597a3e77b5c0192fc848f5fc7f65bb5b662ed20 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 30 Mar 2017 16:54:15 +0200 +Subject: [PATCH 02/16] documents: Track nfo:fileName for later use + +Now that we can open ODFs and OOXMLs in LOKDocView, we don't need to +convert all remote documents to PDF. For example, we can open office +documents stored from OneDrive without any format conversion. The +nfo:fileName can be used to determine the extension of the cached file. + +https://bugzilla.gnome.org/show_bug.cgi?id=774937 +--- + src/documents.js | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index 2071882218b2..6ecc255c9407 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -229,6 +229,7 @@ const DocCommon = new Lang.Class({ + _init: function(cursor) { + this.id = null; + this.uri = null; ++ this.filename = null; + this.name = null; + this.author = null; + this.mtime = null; +@@ -306,12 +307,12 @@ const DocCommon = new Lang.Class({ + this.uri = ''; + + let title = cursor.get_string(Query.QueryColumns.TITLE)[0]; +- let filename = cursor.get_string(Query.QueryColumns.FILENAME)[0]; ++ this.filename = cursor.get_string(Query.QueryColumns.FILENAME)[0]; + + if (title && title != '') + this.name = title; +- else if (filename) +- this.name = GdPrivate.filename_strip_extension(filename); ++ else if (this.filename) ++ this.name = GdPrivate.filename_strip_extension(this.filename); + else + this.name = ''; + +-- +2.9.4 + + +From 291a12b177411b960c91413a51f05493daf98bd1 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 30 Mar 2017 17:25:44 +0200 +Subject: [PATCH 03/16] documents: Add property to denote the URI to be loaded + by the preview + +We want to open ODFs and OOXMLs from OneDrive using LOKDocView, not +EvView. Therefore, the logic to convert a remote document into +something that can be loaded by the different preview widgets can no +longer be hidden inside GdPdfLoader. LOKDocView needs to know the URI +it can load without hitting the network. + +For local and ownCloud this is the same as the actual URI because they +are natively handled by GIO. The property is not defined for Google +because it is still handled entirely by GdPdfLoader. + +This changes the caching for SkydriveDocuments. The old scheme was: + ~/.cache/gnome-documents/gnome-documents-.pdf +The new structure is: + ~/.cache/gnome-documents/skydrive/. + +The new scheme namespaces each document type and uses a hash function +that can be easily replicated by other tools for debugging. This is a +good time to change this because we are about to invalidate existing +caches by not using the ".pdf" extension for all SkydriveDocuments. + +https://bugzilla.gnome.org/show_bug.cgi?id=774937 +--- + src/documents.js | 24 +++++++++++++++++++++++- + src/epubview.js | 2 +- + src/lokview.js | 2 +- + 3 files changed, 25 insertions(+), 3 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index 6ecc255c9407..c50d50078f2f 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -229,6 +229,7 @@ const DocCommon = new Lang.Class({ + _init: function(cursor) { + this.id = null; + this.uri = null; ++ this.uriToLoad = null; + this.filename = null; + this.name = null; + this.author = null; +@@ -618,7 +619,7 @@ const DocCommon = new Lang.Class({ + return; + } + +- GdPrivate.pdf_loader_load_uri_async(this.uri, passwd, cancellable, Lang.bind(this, ++ GdPrivate.pdf_loader_load_uri_async(this.uriToLoad, passwd, cancellable, Lang.bind(this, + function(source, res) { + try { + let docModel = GdPrivate.pdf_loader_load_uri_finish(res); +@@ -749,6 +750,7 @@ const LocalDocument = new Lang.Class({ + + populateFromCursor: function(cursor) { + this.parent(cursor); ++ this.uriToLoad = this.uri; + + if (!Application.application.gettingStartedLocation) + return; +@@ -1013,6 +1015,11 @@ const OwncloudDocument = new Lang.Class({ + this.defaultAppName = this.defaultApp.get_name(); + }, + ++ populateFromCursor: function(cursor) { ++ this.parent(cursor); ++ this.uriToLoad = this.uri; ++ }, ++ + createThumbnail: function(callback) { + GdPrivate.queue_thumbnail_job_for_file_async(this._file, Lang.bind(this, + function(object, res) { +@@ -1071,6 +1078,21 @@ const SkydriveDocument = new Lang.Class({ + this.sourceName = _("OneDrive"); + }, + ++ populateFromCursor: function(cursor) { ++ this.parent(cursor); ++ ++ let localDir = GLib.build_filenamev([GLib.get_user_cache_dir(), "gnome-documents", "skydrive"]); ++ ++ let identifierHash = GLib.compute_checksum_for_string(GLib.ChecksumType.SHA1, this.identifier, -1); ++ let filenameStripped = GdPrivate.filename_strip_extension(this.filename); ++ let extension = this.filename.substring(filenameStripped.length); ++ let localFilename = identifierHash + extension; ++ ++ let localPath = GLib.build_filenamev([localDir, localFilename]); ++ let localFile = Gio.File.new_for_path(localPath); ++ this.uriToLoad = localFile.get_uri(); ++ }, ++ + _createZpjEntry: function(cancellable, callback) { + let source = Application.sourceManager.getItemById(this.resourceUrn); + +diff --git a/src/epubview.js b/src/epubview.js +index 923b0aa265ab..12f392225d6f 100644 +--- a/src/epubview.js ++++ b/src/epubview.js +@@ -65,7 +65,7 @@ const EPUBView = new Lang.Class({ + onLoadFinished: function(manager, doc) { + this.parent(manager, doc); + +- let f = Gio.File.new_for_uri(doc.uri); ++ let f = Gio.File.new_for_uri(doc.uriToLoad); + this._epubdoc = new Gepub.Doc({ path: f.get_path() }); + this._epubdoc.init(null); + +diff --git a/src/lokview.js b/src/lokview.js +index 092adc5a0471..988db963d5d9 100644 +--- a/src/lokview.js ++++ b/src/lokview.js +@@ -148,7 +148,7 @@ const LOKView = new Lang.Class({ + if (!isAvailable()) + return; + this._doc = doc; +- this._lokview.open_document(doc.uri, '{}', null, Lang.bind(this, this._onDocumentOpened)); ++ this._lokview.open_document(doc.uriToLoad, '{}', null, Lang.bind(this, this._onDocumentOpened)); + this._progressBar.show(); + }, + +-- +2.9.4 + + +From 0ea69b0519a4e374feabc1923c82e1e0c71d5914 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 30 Mar 2017 18:18:16 +0200 +Subject: [PATCH 04/16] documents: Let everybody provide their own download + implementation + +This is meant to reduce our reliance on GdPdfLoader for loading remote +documents. We can open ODFs and OOXMLs in LOKDocView, so we don't need +to convert everything to PDFs. In the future, remote sub-classes will +provider their own implementation to download a document, and this will +help unify the loading across the various sub-classes. + +https://bugzilla.gnome.org/show_bug.cgi?id=774937 +--- + src/documents.js | 42 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/src/documents.js b/src/documents.js +index c50d50078f2f..9028e9b5084f 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -360,6 +360,48 @@ const DocCommon = new Lang.Class({ + } + }, + ++ download: function(useCache, cancellable, callback) { ++ let localFile = Gio.File.new_for_uri(this.uriToLoad); ++ let localPath = localFile.get_path(); ++ let localDir = GLib.path_get_dirname(localPath); ++ GLib.mkdir_with_parents(localDir, 448); ++ ++ if (!useCache) { ++ this.downloadImpl(localFile, cancellable, callback); ++ return; ++ } ++ ++ localFile.query_info_async(Gio.FILE_ATTRIBUTE_TIME_MODIFIED, ++ Gio.FileQueryInfoFlags.NONE, ++ GLib.PRIORITY_DEFAULT, ++ cancellable, ++ Lang.bind(this, ++ function(object, res) { ++ let info; ++ ++ try { ++ info = object.query_info_finish(res); ++ } catch (e) { ++ this.downloadImpl(localFile, cancellable, callback); ++ return; ++ } ++ ++ let cacheMtime = info.get_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_MODIFIED); ++ cacheMtime /= 1000000; ++ ++ if (this.mtime <= cacheMtime) { ++ callback(true, null); ++ return; ++ } ++ ++ this.downloadImpl(localFile, cancellable, callback); ++ })); ++ }, ++ ++ downloadImpl: function(localFile, cancellable, callback) { ++ throw(new Error('DocCommon implementations must override downloadImpl')); ++ }, ++ + load: function() { + log('Error: DocCommon implementations must override load'); + }, +-- +2.9.4 + + +From 630fc1a93bbd3a93ee242231a6a1129aef924127 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 30 Mar 2017 18:23:27 +0200 +Subject: [PATCH 05/16] documents: Implement the downloadImpl vfunc for + SkydriveDocument + +https://bugzilla.gnome.org/show_bug.cgi?id=774937 +--- + src/documents.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/src/documents.js b/src/documents.js +index 9028e9b5084f..781019091754 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -1161,6 +1161,62 @@ const SkydriveDocument = new Lang.Class({ + })); + }, + ++ downloadImpl: function(localFile, cancellable, callback) { ++ this._createZpjEntry(cancellable, Lang.bind(this, ++ function(entry, service, error) { ++ if (error) { ++ callback(false, error); ++ return; ++ } ++ ++ service.download_file_to_stream_async(entry, cancellable, Lang.bind(this, ++ function(object, res) { ++ let inputStream; ++ ++ try { ++ inputStream = object.download_file_to_stream_finish(res); ++ } catch (e) { ++ callback(false, e); ++ return; ++ } ++ ++ localFile.replace_async(null, ++ false, ++ Gio.FileCreateFlags.PRIVATE, ++ GLib.PRIORITY_DEFAULT, ++ cancellable, ++ Lang.bind(this, ++ function(object, res) { ++ let outputStream; ++ ++ try { ++ outputStream = object.replace_finish(res); ++ } catch (e) { ++ callback(false, e); ++ return; ++ } ++ ++ outputStream.splice_async(inputStream, ++ Gio.OutputStreamSpliceFlags.CLOSE_SOURCE | ++ Gio.OutputStreamSpliceFlags.CLOSE_TARGET, ++ GLib.PRIORITY_DEFAULT, ++ cancellable, ++ Lang.bind(this, ++ function(object, res) { ++ try { ++ object.splice_finish(res); ++ } catch (e) { ++ callback(false, e); ++ return; ++ } ++ ++ callback(false, null); ++ })); ++ })); ++ })); ++ })); ++ }, ++ + load: function(passwd, cancellable, callback) { + this._createZpjEntry(cancellable, Lang.bind(this, + function(entry, service, exception) { +-- +2.9.4 + + +From c21f27f63ec2cf31c254896ad8343689b9cc9499 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 30 Mar 2017 18:31:18 +0200 +Subject: [PATCH 06/16] documents, pdf-loader: Fix previewing of ODFs and + OOXMLs on OneDrive + +OneDrive documents were being converted to PDFs via GdPdfLoader, but +LOKDocView was being used instead of EvView to render them. LOKDocView +uses the document's URI property, and in this case it is not a valid +URI that it can use. As a result the preview would fail and sometimes +crash the application. + +Solve all that by removing the PDF conversion, and passing the correct +URI to LOKDocView. + +This effectively reverts 0bfb23786dc84d390c4bd6bde5f20987874e1e9b + +https://bugzilla.gnome.org/show_bug.cgi?id=774937 +--- + configure.ac | 4 +- + src/documents.js | 50 ++++++------ + src/lib/gd-pdf-loader.c | 205 +----------------------------------------------- + src/lib/gd-pdf-loader.h | 9 --- + 4 files changed, 29 insertions(+), 239 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 78cda4f799d5..8098515028d1 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -57,7 +57,6 @@ GOBJECT_INTROSPECTION_MIN_VERSION=1.31.6 + GDATA_MIN_VERSION=0.13.3 + GOA_MIN_VERSION=3.2.0 + TRACKER_MIN_VERSION=0.17.3 +-ZAPOJIT_MIN_VERSION=0.0.2 + SOUP_MIN_VERSION=2.41.3 + + AC_ARG_ENABLE(documentation, +@@ -85,8 +84,7 @@ PKG_CHECK_MODULES(DOCUMENTS, + tracker-control-1.0 >= $TRACKER_MIN_VERSION + tracker-sparql-1.0 >= $TRACKER_MIN_VERSION + goa-1.0 >= $GOA_MIN_VERSION +- libgdata >= $GDATA_MIN_VERSION +- zapojit-0.0 >= $ZAPOJIT_MIN_VERSION) ++ libgdata >= $GDATA_MIN_VERSION) + + # Although GTK+ 3.10 includes hi-dpi functionality, it does not require a cairo with + # cairo_surface_set_device_scale(), which we also need if we're to support hi-dpi, +diff --git a/src/documents.js b/src/documents.js +index 781019091754..ca48e53db25d 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -1218,34 +1218,36 @@ const SkydriveDocument = new Lang.Class({ + }, + + load: function(passwd, cancellable, callback) { +- this._createZpjEntry(cancellable, Lang.bind(this, +- function(entry, service, exception) { +- if (exception) { +- // try loading from the most recent cache, if any +- GdPrivate.pdf_loader_load_uri_async(this.identifier, passwd, cancellable, Lang.bind(this, +- function(source, res) { +- try { +- let docModel = GdPrivate.pdf_loader_load_uri_finish(res); +- callback(this, docModel, null); +- } catch (e) { +- // report the outmost error only +- callback(this, null, exception); +- } +- })); +- ++ this.download(true, cancellable, Lang.bind(this, ++ function(fromCache, error) { ++ if (error) { ++ callback(this, null, error); + return; + } + +- GdPrivate.pdf_loader_load_zpj_entry_async +- (entry, service, cancellable, Lang.bind(this, +- function(source, res) { +- try { +- let docModel = GdPrivate.pdf_loader_load_zpj_entry_finish(res); +- callback(this, docModel, null); +- } catch (e) { +- callback(this, null, e); ++ this.loadLocal(passwd, cancellable, Lang.bind(this, ++ function(doc, docModel, error) { ++ if (error) { ++ if (fromCache && ++ !error.matches(EvDocument.DocumentError, EvDocument.DocumentError.ENCRYPTED)) { ++ this.download(false, cancellable, Lang.bind(this, ++ function(fromCache, error) { ++ if (error) { ++ callback(this, null, error); ++ return; ++ } ++ ++ this.loadLocal(passwd, cancellable, callback); ++ })); ++ } else { ++ callback(this, null, error); + } +- })); ++ ++ return; ++ } ++ ++ callback(this, docModel, null); ++ })); + })); + }, + +diff --git a/src/lib/gd-pdf-loader.c b/src/lib/gd-pdf-loader.c +index 7a8890e75891..202f6cc0a65f 100644 +--- a/src/lib/gd-pdf-loader.c ++++ b/src/lib/gd-pdf-loader.c +@@ -51,9 +51,6 @@ typedef struct { + GDataService *gdata_service; + gchar *resource_id; + +- ZpjSkydriveEntry *zpj_entry; +- ZpjSkydrive *zpj_service; +- + guint64 pdf_cache_mtime; + guint64 original_file_mtime; + +@@ -64,7 +61,6 @@ typedef struct { + static void pdf_load_job_from_openoffice (PdfLoadJob *job); + static void pdf_load_job_gdata_refresh_cache (PdfLoadJob *job); + static void pdf_load_job_openoffice_refresh_cache (PdfLoadJob *job); +-static void pdf_load_job_zpj_refresh_cache (PdfLoadJob *job); + + /* --------------------------- utils -------------------------------- */ + +@@ -134,8 +130,6 @@ pdf_load_job_free (PdfLoadJob *job) + g_clear_object (&job->download_file); + g_clear_object (&job->gdata_service); + g_clear_object (&job->gdata_entry); +- g_clear_object (&job->zpj_service); +- g_clear_object (&job->zpj_entry); + + g_free (job->uri); + g_free (job->passwd); +@@ -160,7 +154,6 @@ static PdfLoadJob * + pdf_load_job_new (GSimpleAsyncResult *result, + const gchar *uri, + GDataEntry *gdata_entry, +- ZpjSkydriveEntry *zpj_entry, + const gchar *passwd, + GCancellable *cancellable) + { +@@ -178,8 +171,6 @@ pdf_load_job_new (GSimpleAsyncResult *result, + retval->passwd = g_strdup (passwd); + if (gdata_entry != NULL) + retval->gdata_entry = g_object_ref (gdata_entry); +- if (zpj_entry != NULL) +- retval->zpj_entry = g_object_ref (zpj_entry); + if (cancellable != NULL) + retval->cancellable = g_object_ref (cancellable); + +@@ -216,8 +207,6 @@ pdf_load_job_force_refresh_cache (PdfLoadJob *job) + + if (job->gdata_entry != NULL) + pdf_load_job_gdata_refresh_cache (job); +- if (job->zpj_entry != NULL) +- pdf_load_job_zpj_refresh_cache (job); + else + pdf_load_job_openoffice_refresh_cache (job); + } +@@ -429,61 +418,6 @@ pdf_load_job_gdata_refresh_cache (PdfLoadJob *job) + } + + static void +-zpj_download_stream_ready (GObject *source, +- GAsyncResult *res, +- gpointer user_data) +-{ +- GError *error = NULL; +- PdfLoadJob *job = (PdfLoadJob *) user_data; +- const gchar *name; +- const gchar *extension; +- +- job->stream = zpj_skydrive_download_file_to_stream_finish (ZPJ_SKYDRIVE (source), res, &error); +- if (error != NULL) { +- pdf_load_job_complete_error (job, error); +- return; +- } +- +- name = zpj_skydrive_entry_get_name (job->zpj_entry); +- extension = gd_filename_get_extension_offset (name); +- +- /* If it is not a PDF, we need to convert it afterwards. +- * http://msdn.microsoft.com/en-us/library/live/hh826545#fileformats +- */ +- if (g_strcmp0 (extension, ".pdf") != 0) +- { +- GFileIOStream *iostream; +- +- job->download_file = g_file_new_tmp (NULL, &iostream, &error); +- if (error != NULL) { +- pdf_load_job_complete_error (job, error); +- return; +- } +- +- /* We don't need the iostream. */ +- g_io_stream_close (G_IO_STREAM (iostream), NULL, NULL); +- } +- else +- job->download_file = g_file_new_for_path (job->pdf_path); +- +- g_file_replace_async (job->download_file, NULL, FALSE, +- G_FILE_CREATE_PRIVATE, +- G_PRIORITY_DEFAULT, +- job->cancellable, file_replace_ready_cb, +- job); +-} +- +-static void +-pdf_load_job_zpj_refresh_cache (PdfLoadJob *job) +-{ +- zpj_skydrive_download_file_to_stream_async (job->zpj_service, +- ZPJ_SKYDRIVE_FILE (job->zpj_entry), +- job->cancellable, +- zpj_download_stream_ready, +- job); +-} +- +-static void + gdata_cache_query_info_ready_cb (GObject *source, + GAsyncResult *res, + gpointer user_data) +@@ -518,40 +452,6 @@ gdata_cache_query_info_ready_cb (GObject *source, + } + + static void +-zpj_cache_query_info_ready_cb (GObject *source, +- GAsyncResult *res, +- gpointer user_data) +-{ +- PdfLoadJob *job = user_data; +- GError *error = NULL; +- GFileInfo *info; +- guint64 cache_mtime; +- +- info = g_file_query_info_finish (G_FILE (source), res, &error); +- +- if (error != NULL) { +- /* create/invalidate cache */ +- pdf_load_job_zpj_refresh_cache (job); +- g_error_free (error); +- +- return; +- } +- +- job->pdf_cache_mtime = cache_mtime = +- g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED); +- g_object_unref (info); +- +- if (job->original_file_mtime != cache_mtime) { +- pdf_load_job_zpj_refresh_cache (job); +- } else { +- job->from_old_cache = TRUE; +- +- /* load the cached file */ +- pdf_load_job_from_pdf (job); +- } +-} +- +-static void + pdf_load_job_from_google_documents (PdfLoadJob *job) + { + gchar *tmp_name; +@@ -583,39 +483,6 @@ pdf_load_job_from_google_documents (PdfLoadJob *job) + } + + static void +-pdf_load_job_from_skydrive (PdfLoadJob *job) +-{ +- gchar *tmp_name; +- gchar *tmp_path, *pdf_path; +- GDateTime *updated_time; +- GFile *pdf_file; +- +- updated_time = zpj_skydrive_entry_get_updated_time (job->zpj_entry); +- job->original_file_mtime = (guint64) g_date_time_to_unix (updated_time); +- +- tmp_name = g_strdup_printf ("gnome-documents-%u.pdf", +- g_str_hash (zpj_skydrive_entry_get_id (job->zpj_entry))); +- tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL); +- job->pdf_path = pdf_path = +- g_build_filename (tmp_path, tmp_name, NULL); +- g_mkdir_with_parents (tmp_path, 0700); +- +- pdf_file = g_file_new_for_path (pdf_path); +- +- g_file_query_info_async (pdf_file, +- G_FILE_ATTRIBUTE_TIME_MODIFIED, +- G_FILE_QUERY_INFO_NONE, +- G_PRIORITY_DEFAULT, +- job->cancellable, +- zpj_cache_query_info_ready_cb, +- job); +- +- g_free (tmp_name); +- g_free (tmp_path); +- g_object_unref (pdf_file); +-} +- +-static void + pdf_load_job_from_gdata_cache (PdfLoadJob *job) + { + gchar *tmp_name; +@@ -633,23 +500,6 @@ pdf_load_job_from_gdata_cache (PdfLoadJob *job) + } + + static void +-pdf_load_job_from_zpj_cache (PdfLoadJob *job) +-{ +- gchar *tmp_name; +- gchar *tmp_path; +- +- tmp_name = g_strdup_printf ("gnome-documents-%u.pdf", +- g_str_hash (job->resource_id)); +- tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL); +- job->pdf_path = g_build_filename (tmp_path, tmp_name, NULL); +- +- pdf_load_job_from_pdf (job); +- +- g_free (tmp_path); +- g_free (tmp_name); +-} +- +-static void + unoconv_cancelled_cb (GCancellable *cancellable, + gpointer user_data) + { +@@ -1134,7 +984,6 @@ pdf_load_job_from_uri (PdfLoadJob *job) + { + GFile *file; + const gchar *gdata_prefix = "google:drive:"; +- const gchar *zpj_prefix = "windows-live:skydrive:"; + + if (g_str_has_prefix (job->uri, gdata_prefix)) { + job->resource_id = g_strdup (job->uri + strlen (gdata_prefix)); +@@ -1142,12 +991,6 @@ pdf_load_job_from_uri (PdfLoadJob *job) + return; + } + +- if (g_str_has_prefix (job->uri, zpj_prefix)) { +- job->resource_id = g_strdup (job->uri + strlen (zpj_prefix)); +- pdf_load_job_from_zpj_cache (job); +- return; +- } +- + file = g_file_new_for_uri (job->uri); + if (!g_file_is_native (file)) + pdf_load_job_from_remote_file (job); +@@ -1162,8 +1005,6 @@ pdf_load_job_start (PdfLoadJob *job) + { + if (job->gdata_entry != NULL) + pdf_load_job_from_google_documents (job); +- else if (job->zpj_entry != NULL) +- pdf_load_job_from_skydrive (job); + else + pdf_load_job_from_uri (job); + } +@@ -1189,7 +1030,7 @@ gd_pdf_loader_load_uri_async (const gchar *uri, + result = g_simple_async_result_new (NULL, callback, user_data, + gd_pdf_loader_load_uri_async); + +- job = pdf_load_job_new (result, uri, NULL, NULL, passwd, cancellable); ++ job = pdf_load_job_new (result, uri, NULL, passwd, cancellable); + + pdf_load_job_start (job); + +@@ -1230,7 +1071,7 @@ gd_pdf_loader_load_gdata_entry_async (GDataEntry *entry, + result = g_simple_async_result_new (NULL, callback, user_data, + gd_pdf_loader_load_gdata_entry_async); + +- job = pdf_load_job_new (result, NULL, entry, NULL, NULL, cancellable); ++ job = pdf_load_job_new (result, NULL, entry, NULL, cancellable); + job->gdata_service = g_object_ref (service); + + pdf_load_job_start (job); +@@ -1257,45 +1098,3 @@ gd_pdf_loader_load_gdata_entry_finish (GAsyncResult *res, + retval = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + return retval; + } +- +- +-void +-gd_pdf_loader_load_zpj_entry_async (ZpjSkydriveEntry *entry, +- ZpjSkydrive *service, +- GCancellable *cancellable, +- GAsyncReadyCallback callback, +- gpointer user_data) +-{ +- PdfLoadJob *job; +- GSimpleAsyncResult *result; +- +- result = g_simple_async_result_new (NULL, callback, user_data, +- gd_pdf_loader_load_zpj_entry_async); +- +- job = pdf_load_job_new (result, NULL, NULL, entry, NULL, cancellable); +- job->zpj_service = g_object_ref (service); +- +- pdf_load_job_start (job); +- +- g_object_unref (result); +-} +- +-/** +- * gd_pdf_loader_load_zpj_entry_finish: +- * @res: +- * @error: (allow-none) (out): +- * +- * Returns: (transfer full): +- */ +-EvDocumentModel * +-gd_pdf_loader_load_zpj_entry_finish (GAsyncResult *res, +- GError **error) +-{ +- EvDocumentModel *retval; +- +- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) +- return NULL; +- +- retval = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); +- return retval; +-} +diff --git a/src/lib/gd-pdf-loader.h b/src/lib/gd-pdf-loader.h +index 9e5ffb737eee..70ded295dad3 100644 +--- a/src/lib/gd-pdf-loader.h ++++ b/src/lib/gd-pdf-loader.h +@@ -28,7 +28,6 @@ + + #define GOA_API_IS_SUBJECT_TO_CHANGE + #include +-#include + + G_BEGIN_DECLS + +@@ -48,14 +47,6 @@ void gd_pdf_loader_load_gdata_entry_async (GDataEntry *entry, + EvDocumentModel *gd_pdf_loader_load_gdata_entry_finish (GAsyncResult *res, + GError **error); + +-void gd_pdf_loader_load_zpj_entry_async (ZpjSkydriveEntry *entry, +- ZpjSkydrive *service, +- GCancellable *cancellable, +- GAsyncReadyCallback callback, +- gpointer user_data); +-EvDocumentModel *gd_pdf_loader_load_zpj_entry_finish (GAsyncResult *res, +- GError **error); +- + G_END_DECLS + + #endif /* __GD_PDF_LOADER_H__ */ +-- +2.9.4 + + +From b80863a8d5666c9bd246a09bf770a8ea58367637 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 20 Apr 2017 11:51:47 +0200 +Subject: [PATCH 07/16] documents: Fix the retrieval of the cache's + modification time + +Gio.FILE_ATTRIBUTE_TIME_MODIFIED returns a value in seconds, not +microseconds. + +Fallout from 4133adf06a0ff473e6234f8ab3eb88c47589e627 + +https://bugzilla.gnome.org/show_bug.cgi?id=774937 +--- + src/documents.js | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index ca48e53db25d..4db7d07029b4 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -387,8 +387,6 @@ const DocCommon = new Lang.Class({ + } + + let cacheMtime = info.get_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_MODIFIED); +- cacheMtime /= 1000000; +- + if (this.mtime <= cacheMtime) { + callback(true, null); + return; +-- +2.9.4 + + +From dd1343e7869882d632d75307b396de0c3fde4447 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Tue, 18 Apr 2017 19:01:26 +0200 +Subject: [PATCH 08/16] Optionally load the document when determining if it can + be printed + +https://bugzilla.gnome.org/show_bug.cgi?id=781533 +--- + src/documents.js | 99 ++++++++++++++++++++++++++++++++++++------------------- + src/evinceview.js | 8 ++++- + 2 files changed, 72 insertions(+), 35 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index 4db7d07029b4..fb0eee962548 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -36,6 +36,7 @@ const Zpj = imports.gi.Zpj; + const _ = imports.gettext.gettext; + + const Lang = imports.lang; ++const Mainloop = imports.mainloop; + const Signals = imports.signals; + + const Application = imports.application; +@@ -416,11 +417,37 @@ const DocCommon = new Lang.Class({ + log('Error: DocCommon implementations must override canTrash'); + }, + +- canPrint: function(docModel) { +- if (!docModel) +- return false; ++ canPrint: function(docModel, cancellable, callback) { ++ if (docModel) { ++ Mainloop.idle_add(Lang.bind(this, ++ function() { ++ this._canPrint(docModel, callback); ++ return GLib.SOURCE_REMOVE; ++ })); ++ ++ return; ++ } ++ ++ this.load(null, cancellable, Lang.bind(this, ++ function(doc, docModel, error) { ++ if (error) { ++ callback(this, false); ++ return; ++ } ++ ++ this._canPrint(docModel, callback); ++ })); ++ }, ++ ++ _canPrint: function(docModel, callback) { ++ if (!docModel) { ++ callback(this, false); ++ return; ++ } + +- return EvView.PrintOperation.exists_for_document(docModel.get_document()); ++ let evDoc = docModel.get_document(); ++ let supported = EvView.PrintOperation.exists_for_document(evDoc); ++ callback(this, supported); + }, + + trash: function() { +@@ -694,41 +721,45 @@ const DocCommon = new Lang.Class({ + return; + } + +- if (!this.canPrint(docModel)) +- return; ++ this.canPrint(docModel, null, Lang.bind(this, ++ function(doc, supported) { ++ if (!supported) ++ return; + +- let printOp = EvView.PrintOperation.new(docModel.get_document()); ++ let printOp = EvView.PrintOperation.new(docModel.get_document()); + +- printOp.connect('begin-print', Lang.bind(this, +- function() { +- Application.selectionController.setSelectionMode(false); +- })); + +- printOp.connect('done', Lang.bind(this, +- function(op, res) { +- if (res == Gtk.PrintOperationResult.ERROR) { +- try { +- printOp.get_error(); +- } catch (e) { +- let errorDialog = new Gtk.MessageDialog ({ transient_for: toplevel, +- modal: true, +- destroy_with_parent: true, +- buttons: Gtk.ButtonsType.OK, +- message_type: Gtk.MessageType.ERROR, +- text: _("Failed to print document"), +- secondary_text: e.message }); +- errorDialog.connect ('response', Lang.bind(this, +- function() { +- errorDialog.destroy(); +- })); +- errorDialog.show(); +- } +- } +- })); ++ printOp.connect('begin-print', Lang.bind(this, ++ function() { ++ Application.selectionController.setSelectionMode(false); ++ })); + +- let printNotification = new Notifications.PrintNotification(printOp, doc); ++ printOp.connect('done', Lang.bind(this, ++ function(op, res) { ++ if (res == Gtk.PrintOperationResult.ERROR) { ++ try { ++ printOp.get_error(); ++ } catch (e) { ++ let errorDialog = new Gtk.MessageDialog ({ transient_for: toplevel, ++ modal: true, ++ destroy_with_parent: true, ++ buttons: Gtk.ButtonsType.OK, ++ message_type: Gtk.MessageType.ERROR, ++ text: _("Failed to print document"), ++ secondary_text: e.message }); ++ errorDialog.connect ('response', Lang.bind(this, ++ function() { ++ errorDialog.destroy(); ++ })); ++ errorDialog.show(); ++ } ++ } ++ })); ++ ++ let printNotification = new Notifications.PrintNotification(printOp, doc); + +- printOp.run(toplevel); ++ printOp.run(toplevel); ++ })); + })); + }, + +diff --git a/src/evinceview.js b/src/evinceview.js +index d4ea883e76b4..3e0070bb785c 100644 +--- a/src/evinceview.js ++++ b/src/evinceview.js +@@ -264,7 +264,13 @@ const EvinceView = new Lang.Class({ + + this.getAction('copy').enabled = false; + this.getAction('edit-current').enabled = doc.canEdit(); +- this.getAction('print-current').enabled = doc.canPrint(docModel); ++ ++ this.getAction('print-current').enabled = false; ++ doc.canPrint(docModel, null, Lang.bind(this, ++ function(doc, supported) { ++ this.getAction('print-current').enabled = supported; ++ })); ++ + let presentCurrent = this.getAction('present-current'); + if (presentCurrent) + presentCurrent.enabled = true; +-- +2.9.4 + + +From c37a9a62610ba301f09d2e53a4004dcbf12dadec Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 20 Apr 2017 14:40:40 +0200 +Subject: [PATCH 09/16] documents: Check whether it is a collection in canPrint + +https://bugzilla.gnome.org/show_bug.cgi?id=781533 +--- + src/documents.js | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/documents.js b/src/documents.js +index fb0eee962548..3bed18c36a49 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -418,6 +418,16 @@ const DocCommon = new Lang.Class({ + }, + + canPrint: function(docModel, cancellable, callback) { ++ if (this.collection) { ++ Mainloop.idle_add(Lang.bind(this, ++ function() { ++ callback(this, false); ++ return GLib.SOURCE_REMOVE; ++ })); ++ ++ return; ++ } ++ + if (docModel) { + Mainloop.idle_add(Lang.bind(this, + function() { +-- +2.9.4 + + +From 7d63e3fc760aef6ec56868a16e930af8977f0973 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 20 Apr 2017 14:59:12 +0200 +Subject: [PATCH 10/16] selections: Enable printing only for documents handled + by EvView + +Now that we don't convert everything to PDFs, we might not be able to +print everything that's not a collection. eg., we can't print EPUBs, +ODFs and OOXMLs. Therefore it is not enough to only check for +collections. + +Instead, let's use canPrint which encapsulates all the conditions that +need to be met for printing. + +https://bugzilla.gnome.org/show_bug.cgi?id=781533 +--- + src/selections.js | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/selections.js b/src/selections.js +index b864c8f8a634..ecfd3ec694c7 100644 +--- a/src/selections.js ++++ b/src/selections.js +@@ -946,7 +946,7 @@ const SelectionToolbar = new Lang.Class({ + let hasSelection = (selection.length > 0); + + let showTrash = hasSelection; +- let showPrint = hasSelection; ++ let showPrint = false; + let showProperties = hasSelection; + let showOpen = hasSelection; + let showShare = hasSelection; +@@ -967,16 +967,21 @@ const SelectionToolbar = new Lang.Class({ + showShare = false; + + showTrash &= doc.canTrash(); +- showPrint &= !doc.collection; + })); + + showOpen = (apps.length > 0); + +- if (selection.length > 1) { +- showPrint = false; +- showProperties = false; ++ if (selection.length == 1) { ++ let doc = Application.documentManager.getItemById(selection[0]); ++ doc.canPrint(null, null, Lang.bind(this, ++ function(doc, supported) { ++ this._toolbarPrint.set_sensitive(supported); ++ })); + } + ++ if (selection.length > 1) ++ showProperties = false; ++ + let openLabel = null; + if (apps.length == 1) { + // Translators: this is the Open action in a context menu +-- +2.9.4 + + +From aa507bc55aef99815308fe7865f016d40ed6f76d Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Mon, 27 Mar 2017 16:08:57 +0200 +Subject: [PATCH 11/16] documents: Thumbnail SkydriveDocuments once they are + loaded +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Historically, unlike GoogleDocuments, we were unable to fetch +server-side thumbnails for SkydriveDocuments due to limitations of +OneDrive's REST API. Newer versions of the REST API do support it [1], +but it is not implemented in libzapojit. + +Some ways to work around these limitations: + - Create the thumbnail from the EvDocument when it is loaded for + previewing + - Use a cached copy of the document as source for the thumbnail + +Even if we can fetch thumbnails from the server in future, these would +still be nice optimizations to have — reduces network consumption and +offers a cheap way to jump ahead in the thumbnailing queue. + +[1] https://dev.onedrive.com/items/thumbnails.htm +--- + src/documents.js | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 109 insertions(+), 2 deletions(-) + +diff --git a/src/documents.js b/src/documents.js +index 3bed18c36a49..27518b2251d1 100644 +--- a/src/documents.js ++++ b/src/documents.js +@@ -1150,7 +1150,7 @@ const SkydriveDocument = new Lang.Class({ + Extends: DocCommon, + + _init: function(cursor) { +- this._failedThumbnailing = true; ++ this._failedThumbnailing = false; + + this.parent(cursor); + +@@ -1174,6 +1174,54 @@ const SkydriveDocument = new Lang.Class({ + this.uriToLoad = localFile.get_uri(); + }, + ++ _createThumbnailFromEvDocument: function(evDoc, cancellable, callback) { ++ let thumbnailPath = GnomeDesktop.desktop_thumbnail_path_for_uri (this.uri, ++ GnomeDesktop.DesktopThumbnailSize.LARGE); ++ let thumbnailFile = Gio.File.new_for_path(thumbnailPath); ++ ++ let thumbnailDir = GLib.path_get_dirname(thumbnailPath); ++ GLib.mkdir_with_parents(thumbnailDir, 448); ++ ++ thumbnailFile.replace_async(null, ++ false, ++ Gio.FileCreateFlags.PRIVATE, ++ GLib.PRIORITY_DEFAULT, ++ cancellable, ++ Lang.bind(this, ++ function(source, res) { ++ let outputStream; ++ ++ try { ++ outputStream = thumbnailFile.replace_finish(res); ++ } catch (e) { ++ callback(e); ++ return; ++ } ++ ++ let [width, height] = evDoc.get_page_size(0); ++ let maxDimension = Math.max(width, height); ++ let scale = Application.application.getScaleFactor(); ++ let size = 128 * scale; ++ let zoom = size / maxDimension; ++ ++ let page = evDoc.get_page(0); ++ ++ let rc = EvDocument.RenderContext.new(page, 0, zoom); ++ let pixbuf = evDoc.get_thumbnail(rc); ++ pixbuf.save_to_streamv_async(outputStream, "png", [], [], cancellable, Lang.bind(this, ++ function(source, res) { ++ try { ++ GdkPixbuf.Pixbuf.save_to_stream_finish(res); ++ } catch (e) { ++ callback(e); ++ return; ++ } ++ ++ callback(null); ++ })); ++ })); ++ }, ++ + _createZpjEntry: function(cancellable, callback) { + let source = Application.sourceManager.getItemById(this.resourceUrn); + +@@ -1276,7 +1324,16 @@ const SkydriveDocument = new Lang.Class({ + return; + } + +- this.loadLocal(passwd, cancellable, callback); ++ this.loadLocal(passwd, cancellable, Lang.bind(this, ++ function(doc, docModel, error) { ++ if (error) { ++ callback(this, null, error); ++ return; ++ } ++ ++ callback(this, docModel, null); ++ this._postLoad(docModel); ++ })); + })); + } else { + callback(this, null, error); +@@ -1286,6 +1343,56 @@ const SkydriveDocument = new Lang.Class({ + } + + callback(this, docModel, null); ++ this._postLoad(docModel); ++ })); ++ })); ++ }, ++ ++ _postLoad: function(docModel) { ++ if (this._thumbPath) ++ return; ++ ++ if (!docModel) ++ return; ++ ++ this._createThumbnailFromEvDocument(docModel.document, null, Lang.bind(this, ++ function(error) { ++ if (error) { ++ logError(error, 'Unable to create thumbnail from EvDocument'); ++ return; ++ } ++ ++ this._failedThumbnailing = false; ++ this.refreshIcon(); ++ })); ++ }, ++ ++ createThumbnail: function(callback) { ++ // try loading from the most recent cache, if any ++ this.loadLocal(null, null, Lang.bind(this, ++ function(doc, docModel, error) { ++ if (error) { ++ if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) && ++ !error.matches(EvDocument.DocumentError, EvDocument.DocumentError.ENCRYPTED)) { ++ logError(error, 'Unable to load document from the cache'); ++ callback(false); ++ return; ++ } ++ } ++ ++ if (!docModel) { ++ callback(false); ++ return; ++ } ++ ++ this._createThumbnailFromEvDocument(docModel.document, null, Lang.bind(this, ++ function(error) { ++ if (error) { ++ logError(error, 'Unable to create thumbnail from EvDocument'); ++ return; ++ } ++ ++ callback(true); + })); + })); + }, +-- +2.9.4 + + +From 3bd516524432f9decb0a15ab209a9957b7ae7488 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 8 May 2017 16:44:32 +0100 +Subject: [PATCH 12/16] lokview: Fix crash on repeated open of presentations + +Ensure prompt destruction of the LOKDocView widget when the view is +destroyed. This gives LOK a chance to shutdown at the right time. + +https://bugzilla.gnome.org/show_bug.cgi?id=782508 +--- + src/lokview.js | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/lokview.js b/src/lokview.js +index 988db963d5d9..238832ed4502 100644 +--- a/src/lokview.js ++++ b/src/lokview.js +@@ -137,11 +137,19 @@ const LOKView = new Lang.Class({ + 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)); ++ this.connect('destroy', Lang.bind(this, this._destroyView)); + } + + return sw; + }, + ++ _destroyView: function() { ++ if (this._lokview) { ++ this._lokview.destroy(); ++ this._lokview = null; ++ } ++ }, ++ + onLoadFinished: function(manager, doc) { + this.parent(manager, doc); + +@@ -237,10 +245,10 @@ const LOKView = new Lang.Class({ + }, + + get page() { +- return this._lokview.get_part(); ++ return this._lokview ? this._lokview.get_part() : 0; + }, + + get numPages() { +- return this._lokview.get_parts(); ++ return this._lokview ? this._lokview.get_parts() : 0; + } + }); +-- +2.9.4 + + +From 238a4d4c95b78eff9d1a764f184936ddc58db73d Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 8 Jun 2017 16:10:57 +0200 +Subject: [PATCH 13/16] application: Avoid CRITICALs if a primary instance is + already present + +The dbus_unregister method can be invoked more than once. Trying to +unexport an already unexported GDBusInterfaceSkeleton led to: + GLib-GIO-CRITICAL **: + g_dbus_interface_skeleton_unexport_from_connection: assertion + 'interface_->priv->connections != NULL' failed + +https://bugzilla.gnome.org/show_bug.cgi?id=783548 +--- + src/application.js | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/application.js b/src/application.js +index a82395d6afd2..40a5dd0e5114 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -521,7 +521,10 @@ const Application = new Lang.Class({ + }, + + vfunc_dbus_unregister: function(connection, path) { +- this._searchProvider.unexport(connection); ++ if (this._searchProvider != null) { ++ this._searchProvider.unexport(connection); ++ this._searchProvider = null; ++ } + + this.parent(connection, path); + }, +-- +2.9.4 + + +From ca10b8d02486630db2f3de746ee4b885490cbaab Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 8 Jun 2017 16:12:15 +0200 +Subject: [PATCH 14/16] application: Instantiate ShellSearchProvider only when + registering + +Now that the --version flag was implemented using the +handle_local_options virtual method, it is possible that the +Application may exit without ever touching D-Bus. So it is a tad +wasteful to instantiate the ShellSearchProvider when it is never going +to be used. Since we are unreffing it in dbus_register, we might as +well create it in dbus_register. + +https://bugzilla.gnome.org/show_bug.cgi?id=783548 +--- + src/application.js | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/application.js b/src/application.js +index 40a5dd0e5114..2630e1971826 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -100,6 +100,7 @@ const Application = new Lang.Class({ + this.minersRunning = []; + this._activationTimestamp = Gdk.CURRENT_TIME; + this._extractPriority = null; ++ this._searchProvider = null; + + this.isBooks = isBooks; + +@@ -120,10 +121,6 @@ const Application = new Lang.Class({ + + this.add_main_option('version', 'v'.charCodeAt(0), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, + _("Show the version of the program"), null); +- +- this._searchProvider = new ShellSearchProvider.ShellSearchProvider(); +- this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult)); +- this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch)); + }, + + _initGettingStarted: function() { +@@ -516,6 +513,10 @@ const Application = new Lang.Class({ + vfunc_dbus_register: function(connection, path) { + this.parent(connection, path); + ++ this._searchProvider = new ShellSearchProvider.ShellSearchProvider(); ++ this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult)); ++ this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch)); ++ + this._searchProvider.export(connection); + return true; + }, +-- +2.9.4 + + +From af6130bfe229521869f33a125dd4d354f4327ff4 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 8 Jun 2017 16:12:34 +0200 +Subject: [PATCH 15/16] application: Assert that the ShellSearchProvider's + lifetime is sane + +The ShellSearchProvider should be instantiated in the dbus_register +virtual method, which is expected to be called only once. + +https://bugzilla.gnome.org/show_bug.cgi?id=783548 +--- + src/application.js | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/application.js b/src/application.js +index 2630e1971826..1e439815f0b4 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -513,6 +513,9 @@ const Application = new Lang.Class({ + vfunc_dbus_register: function(connection, path) { + this.parent(connection, path); + ++ if (this._searchProvider != null) ++ throw(new Error('ShellSearchProvider already instantiated - dbus_register called twice?')); ++ + this._searchProvider = new ShellSearchProvider.ShellSearchProvider(); + this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult)); + this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch)); +-- +2.9.4 + + +From 4d3476a700ecbb5066269f9fb15fc201d134859e Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 8 Jun 2017 16:58:08 +0200 +Subject: [PATCH 16/16] application: Don't unexport a skeleton that was never + exported + +Otherwise it will again lead to: + GLib-GIO-CRITICAL **: + g_dbus_interface_skeleton_unexport_from_connection: assertion + 'interface_->priv->connections != NULL' failed + +https://bugzilla.gnome.org/show_bug.cgi?id=783548 +--- + src/application.js | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/application.js b/src/application.js +index 1e439815f0b4..f9e8b6ae9863 100644 +--- a/src/application.js ++++ b/src/application.js +@@ -520,7 +520,13 @@ const Application = new Lang.Class({ + this._searchProvider.connect('activate-result', Lang.bind(this, this._onActivateResult)); + this._searchProvider.connect('launch-search', Lang.bind(this, this._onLaunchSearch)); + +- this._searchProvider.export(connection); ++ try { ++ this._searchProvider.export(connection); ++ } catch(e) { ++ this._searchProvider = null; ++ throw(e); ++ } ++ + return true; + }, + +-- +2.9.4 + diff --git a/SPECS/gnome-documents.spec b/SPECS/gnome-documents.spec new file mode 100644 index 0000000..5e0557b --- /dev/null +++ b/SPECS/gnome-documents.spec @@ -0,0 +1,407 @@ +%define evince_version 3.13.3 +%define gjs_version 1.50.2-3 +%define gnome_online_miners_version 3.22.0-2 +%define gtk3_version 3.19.1 + +Name: gnome-documents +Version: 3.22.2 +Release: 8%{?dist} +Summary: A document manager application for GNOME + +License: GPLv2+ +URL: https://wiki.gnome.org/Apps/Documents +Source0: https://download.gnome.org/sources/%{name}/3.22/%{name}-%{version}.tar.xz + +# https://bugzilla.redhat.com/show_bug.cgi?id=985887 +# https://bugzilla.redhat.com/show_bug.cgi?id=1436566 +# https://bugzilla.redhat.com/show_bug.cgi?id=1436682 +# https://bugzilla.redhat.com/show_bug.cgi?id=1438362 +# https://bugzilla.redhat.com/show_bug.cgi?id=1444437 +Patch0: gnome-documents-skydrive-printing-and-lok-fixes.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1517770 +# https://bugzilla.redhat.com/show_bug.cgi?id=1517704 +Patch1: gnome-documents-new-gjs-gtk.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1517770 +Patch2: gnome-documents-getting-started.patch + +BuildRequires: autoconf automake libtool +BuildRequires: gnome-common +BuildRequires: yelp-tools +BuildRequires: pkgconfig(evince-document-3.0) >= %{evince_version} +BuildRequires: pkgconfig(evince-view-3.0) >= %{evince_version} +BuildRequires: pkgconfig(webkit2gtk-4.0) +BuildRequires: pkgconfig(gtk+-3.0) >= %{gtk3_version} +BuildRequires: pkgconfig(gjs-1.0) >= %{gjs_version} +BuildRequires: pkgconfig(tracker-control-1.0) >= 0.17.0 +BuildRequires: pkgconfig(tracker-sparql-1.0) >= 0.17.0 +BuildRequires: pkgconfig(goa-1.0) +BuildRequires: pkgconfig(gnome-desktop-3.0) +BuildRequires: pkgconfig(libgdata) +BuildRequires: pkgconfig(libgepub) +BuildRequires: pkgconfig(zapojit-0.0) +BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: intltool +BuildRequires: liboauth-devel +BuildRequires: desktop-file-utils +BuildRequires: itstool +BuildRequires: inkscape +BuildRequires: poppler-utils +BuildRequires: docbook-style-xsl + +Requires: evince-libs%{?_isa} >= %{evince_version} +Requires: gjs >= %{gjs_version} +Requires: gtk3%{?_isa} >= %{gtk3_version} +Requires: gnome-online-miners >= %{gnome_online_miners_version} +Requires: libgepub%{?_isa} +Requires: libreofficekit +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description +gnome-documents is a document manager application for GNOME, +aiming to be a simple and elegant replacement for using Files to show +the Documents directory. + +%package libs +Summary: Common libraries and data files for %{name} +%description libs +%{summary}. + +%prep +%setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 + +%build +autoreconf --force --install +%configure --disable-static --enable-getting-started +make %{?_smp_mflags} + +%install +%make_install +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + +# Disable gnome-books +rm -f $RPM_BUILD_ROOT/%{_bindir}/gnome-books +rm -f $RPM_BUILD_ROOT/%{_datadir}/dbus-1/services/org.gnome.Books.service +rm -f $RPM_BUILD_ROOT/%{_datadir}/glib-2.0/schemas/org.gnome.books.gschema.xml +rm -f $RPM_BUILD_ROOT/%{_datadir}/applications/org.gnome.Books.desktop +rm -f $RPM_BUILD_ROOT/%{_datadir}/icons/hicolor/*/apps/org.gnome.Books.png +rm -f $RPM_BUILD_ROOT/%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Books-symbolic.svg +rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/gnome-books.1* +rm -f $RPM_BUILD_ROOT/%{_datadir}/appdata/org.gnome.Books.appdata.xml + +desktop-file-validate $RPM_BUILD_ROOT/%{_datadir}/applications/org.gnome.Documents.desktop +%find_lang %{name} --with-gnome + +%post +/sbin/ldconfig +touch --no-create %{_datadir}/icons/hicolor >&/dev/null || : + +%postun +/sbin/ldconfig +if [ $1 -eq 0 ] ; then + touch --no-create %{_datadir}/icons/hicolor >&/dev/null || : + gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : + /usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : +fi + +%posttrans +gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : +/usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : + +%files -f %{name}.lang +%license COPYING +%doc README AUTHORS NEWS TODO +%{_bindir}/%{name} +%{_datadir}/appdata/org.gnome.Documents.appdata.xml +%{_datadir}/dbus-1/services/org.gnome.Documents.service +%{_datadir}/glib-2.0/schemas/org.gnome.documents.gschema.xml +%{_datadir}/applications/org.gnome.Documents.desktop +%{_datadir}/icons/hicolor/*/apps/org.gnome.Documents.png +%{_datadir}/icons/hicolor/scalable/apps/org.gnome.Documents-symbolic.svg +%{_mandir}/man1/gnome-documents.1* +# co-own these directories +%dir %{_datadir}/gnome-shell +%dir %{_datadir}/gnome-shell/search-providers +%{_datadir}/gnome-shell/search-providers/org.gnome.Documents.search-provider.ini + +%files libs +%{_datadir}/%{name} +%{_datadir}/glib-2.0/schemas/org.gnome.Documents.enums.xml +%{_libdir}/gnome-documents/ + +%changelog +* Tue Dec 12 2017 Debarshi Ray - 3.22.2-8 +- Initialize the getting started PDF only when presenting a UI, and before any + SPARQL has been submitted +- Suppress WARNINGs from GJS 1.50.0 by using var instead of let/const for + exported symbols +- Use the standard dialect of String.prototype.replace + Resolves: #1517770 + +* Wed Dec 06 2017 Debarshi Ray - 3.22.2-7 +- Suppress WARNINGs from GJS 1.50.0 about replacing GObject signal methods + Resolves: #1517770 + +* Mon Nov 27 2017 Debarshi Ray - 3.22.2-6 +- Adjust the LOKDocView detection to work with GJS 1.48.0 +- Suppress WARNINGs from GJS 1.50.0 by using var instead of let/const for + exported symbols + Resolves: #1517704 + +* Fri Jun 09 2017 Debarshi Ray - 3.22.2-5 +- Fix CRITICALs on invoking the application when a primary instance is present + Resolves: #1436566 + +* Thu May 11 2017 Debarshi Ray - 3.22.2-4 +- Fix crash on repeated opening of presentations + Resolves: #1444437 + +* Fri Apr 21 2017 Debarshi Ray - 3.22.2-3 +- Disable the print button in the selection toolbar when printing isn't + supported + Resolves: #1438362 + +* Tue Apr 04 2017 Debarshi Ray - 3.22.2-2 +- Unable to preview LOKDocView-supported documents from OneDrive + Resolves: #1436682 + +* Mon Mar 27 2017 Debarshi Ray - 3.22.2-1 +- Update to 3.22.2 +- Thumbnail OneDrive entries once they are loaded + Resolves: #985887, #1386892 + +* Wed Mar 22 2017 Debarshi Ray - 3.22.1-2 +- Drop gnome-books due to unavailability of gnome-epub-thumbnailer + Resolves: #1433418 + +* Sun Mar 12 2017 Debarshi Ray - 3.22.1-1 +- Update to 3.22.1 + Resolves: #1386892 + +* Wed Jun 15 2016 Debarshi Ray - 3.14.3-3 +- Prevent nested collections + Resolves: #958690 + +* Wed May 20 2015 Debarshi Ray - 3.14.3-2 +- Show a back button when loading + Resolves: #1057160 + +* Fri May 15 2015 Debarshi Ray - 3.14.3-1 +- Update to 3.14.3 + Update translations + Resolves: #1174601 + +* Mon Mar 23 2015 Richard Hughes - 3.14.2-1 +- Update to 3.14.2 + Resolves: #1174601 + +* Fri Mar 7 2014 Debarshi Ray - 3.8.5-10 +- get_pretty_name mixes up ASCII and UTF8 characters + Resolves: #1073383 + +* Wed Feb 26 2014 Debarshi Ray - 3.8.5-9 +- The sharing dialog is Google specific + Resolves: #1062608 + +* Tue Feb 25 2014 Debarshi Ray - 3.8.5-8 +- Fix the patch to preview encrypted PDFs +- Fix the patch to protect against spurious view-as signals + Resolves: #959175 + +* Tue Feb 11 2014 Debarshi Ray - 3.8.5-7 +- Use decimal instead of octal literal + Resolves: #1035573 + +* Tue Feb 11 2014 Debarshi Ray - 3.8.5-6 +- No indication of a document failing to print + Resolves: #162299 + +* Mon Feb 10 2014 Debarshi Ray - 3.8.5-5 +- Protect against spurious changed::view-as signals + Resolves: #1056032 + +* Fri Jan 24 2014 Daniel Mach - 3.8.5-4 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 3.8.5-3 +- Mass rebuild 2013-12-27 + +* Wed Dec 11 2013 Matthias Clasen - 3.8.5-2 +- Update translations + Resolves: #1030340 + +* Thu Oct 24 2013 Debarshi Ray - 3.8.5-1 +- Update to 3.8.5 + +* Fri Aug 30 2013 Debarshi Ray - 3.8.4-1 +- Update to 3.8.4 + +* Thu Jul 11 2013 Debarshi Ray - 3.8.3.1-2 +- Backport support for previewing password protected PDFs (GNOME #700716) + +* Fri Jun 14 2013 Debarshi Ray - 3.8.3.1-1 +- Update to 3.8.3.1 + +* Sun Jun 9 2013 Matthias Clasen - 3.8.3-1 +- Update to 3.8.3 + +* Mon May 13 2013 Matthias Clasen - 3.8.2.1-1 +- Update to 3.8.2.1 + +* Tue Apr 16 2013 Richard Hughes - 3.8.1-1 +- Update to 3.8.1 + +* Thu Mar 28 2013 Cosimo Cecchi - 3.8.0-2 +- Enable generation of getting-started tutorial PDF + +* Tue Mar 26 2013 Kalev Lember - 3.8.0-1 +- Update to 3.8.0 + +* Wed Mar 20 2013 Kalev Lember - 3.7.92-1 +- Update to 3.7.92 + +* Thu Mar 7 2013 Matthias Clasen - 3.7.91-1 +- Update to 3.7.91 + +* Tue Feb 26 2013 Kalev Lember - 3.7.90-1 +- Update to 3.7.90 + +* Thu Feb 21 2013 Kalev Lember - 3.7.5-3 +- Rebuilt for cogl soname bump + +* Wed Feb 20 2013 Kalev Lember - 3.7.5-2 +- Rebuilt for libgnome-desktop soname bump + +* Thu Feb 07 2013 Richard Hughes - 3.7.5-1 +- Update to 3.7.5 + +* Fri Jan 25 2013 Peter Robinson 3.7.4-2 +- Rebuild for new cogl + +* Tue Jan 15 2013 Matthias Clasen - 3.7.4-1 +- Update to 3.7.4 + +* Fri Dec 21 2012 Kalev Lember - 3.7.3-1 +- Update to 3.7.3 + +* Tue Nov 20 2012 Richard Hughes - 3.7.2-1 +- Update to 3.7.2 + +* Tue Nov 13 2012 Kalev Lember - 3.6.2-1 +- Update to 3.6.2 + +* Mon Oct 15 2012 Cosimo Cecchi - 3.6.1-1 +- Update to 3.6.1 + +* Tue Sep 25 2012 Cosimo Cecchi - 3.6.0-1 +- Update to 3.6.0 + +* Tue Sep 18 2012 Cosimo Cecchi - 3.5.92-1 +- Update to 3.5.92 + +* Sun Sep 09 2012 Kalev Lember - 3.5.91-2 +- Rebuild against new cogl/clutter + +* Tue Sep 04 2012 Cosimo Cecchi - 3.5.91-1 +- Update to 3.5.91 + +* Tue Aug 28 2012 Matthias Clasen - 3.5.90-2 +- Rebuild against new cogl/clutter + +* Tue Aug 21 2012 Elad Alfassa - 3.5.90-1 +- Update to latest upstream release + +* Fri Aug 10 2012 Cosimo Cecchi - 0.5.5-1 +- Update to 0.5.5 + +* Thu Jul 19 2012 Fedora Release Engineering - 0.5.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 17 2012 Richard Hughes - 0.5.4-1 +- Update to 0.5.4 + +* Wed Jun 27 2012 Cosimo Cecchi - 0.5.3-1 +- Update to 0.5.3 + +* Thu Jun 07 2012 Matthias Clasen - 0.5.2.1-2 +- Rebuild + +* Thu Jun 07 2012 Richard Hughes - 0.5.2.1-1 +- Update to 0.5.2.1 + +* Sat May 05 2012 Kalev Lember - 0.5.1-1 +- Update to 0.5.1 + +* Tue Apr 17 2012 Kalev Lember - 0.4.1-1 +- Update to 0.4.1 + +* Mon Mar 26 2012 Cosimo Cecchi - 0.4.0.1-1 +- Update to 0.4.0.1 + +* Mon Mar 26 2012 Cosimo Cecchi - 0.4.0-2 +- Rebuild against current libevdocument3 soname + +* Mon Mar 26 2012 Cosimo Cecchi - 0.4.0-1 +- Update to 0.4.0 + +* Wed Mar 21 2012 Kalev Lember - 0.3.92-4 +- Rebuild for libevdocument3 soname bump + +* Tue Mar 20 2012 Adam Williamson - 0.3.92-3 +- revert unoconv requirement, it pulls LO into the live image + +* Tue Mar 20 2012 Adam Williamson - 0.3.92-2 +- requires: unoconv (RHBZ #754516) + +* Tue Mar 20 2012 Cosimo Cecchi - 0.3.92-1 +- Update to 0.3.92 + +* Sat Mar 10 2012 Matthias Clasen - 0.3.91-2 +- Rebuild against new cogl + +* Tue Mar 06 2012 Cosimo Cecchi - 0.3.91-1 +- Update to 0.3.91 + +* Sun Feb 26 2012 Matthias Clasen - 0.3.90-1 +- Update to 0.3.90 + +* Thu Jan 19 2012 Matthias Clasen - 0.3.4-2 +- Rebuild against new cogl + +* Tue Jan 17 2012 Cosimo Cecchi - 0.3.4-1 +- Update to 0.3.4 + +* Fri Jan 13 2012 Fedora Release Engineering - 0.3.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Dec 20 2011 Matthias Clasen - 0.3.3-1 +- Update to 0.3.3 + +* Wed Nov 23 2011 Matthias Clasen - 0.3.2-1 +- Update to 0.3.2 + +* Tue Oct 18 2011 Elad Alfassa - 0.2.1-1 +- New upstream release + +* Tue Sep 27 2011 Ray - 0.2.0-1 +- Update to 0.2.0 + +* Tue Sep 20 2011 Matthias Clasen - 0.1.92-2 +- Rebuild against newer clutter + +* Tue Sep 20 2011 Elad Alfassa - 0.1.92-1 +- Update to 0.1.92 + +* Wed Sep 7 2011 Matthias Clasen - 0.1.91-1 +- Update to 0.1.91 + +* Sat Sep 03 2011 Elad Alfassa - 0.1.90-2 +- Fix #735341 + +* Fri Sep 02 2011 Elad Alfassa - 0.1.90-1 +- Initial packaging. +