Merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-lok-qsg-zoom into lp:ubuntu-docviewer-app

Proposed by Stefano Verzegnassi
Status: Merged
Approved by: Stefano Verzegnassi
Approved revision: 177
Merged at revision: 184
Proposed branch: lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-lok-qsg-zoom
Merge into: lp:ubuntu-docviewer-app
Diff against target: 2053 lines (+1203/-236)
27 files modified
po/com.ubuntu.docviewer.pot (+56/-19)
src/app/main.cpp (+1/-0)
src/app/qml/loView/KeybHelper.js (+57/-0)
src/app/qml/loView/LOViewDefaultHeader.qml (+7/-5)
src/app/qml/loView/LOViewDelegate.qml (+0/-95)
src/app/qml/loView/LOViewGotoDialog.qml (+0/-64)
src/app/qml/loView/LOViewPage.qml (+164/-26)
src/app/qml/loView/LOViewZoomHeader.qml (+59/-0)
src/app/qml/loView/PanelButton.qml (+31/-0)
src/app/qml/loView/PartsView.qml (+81/-0)
src/app/qml/loView/SlideControllerPanel.qml (+67/-0)
src/app/qml/loView/ZoomSelector.qml (+149/-0)
src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt (+2/-0)
src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp (+51/-5)
src/plugin/libreofficetoolkit-qml-plugin/lodocument.h (+16/-1)
src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp (+77/-0)
src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h (+35/-0)
src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp (+125/-0)
src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h (+70/-0)
src/plugin/libreofficetoolkit-qml-plugin/loview.cpp (+108/-9)
src/plugin/libreofficetoolkit-qml-plugin/loview.h (+19/-3)
src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp (+2/-0)
src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml (+12/-2)
src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp (+3/-3)
src/plugin/libreofficetoolkit-qml-plugin/renderengine.h (+4/-2)
src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp (+2/-1)
src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h (+5/-1)
To merge this branch: bzr merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-lok-qsg-zoom
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Ubuntu Document Viewer Developers Pending
Review via email: mp+271895@code.launchpad.net

Commit message

[loviewer] Implemented zoom:
* Added a manual zoom mode
* Added an automatic zoom mode (fit zoom to flickable width)
* Added a bottom panel with a zoom selector (which includes a TextField and an OptionSelector)

Description of the change

[loviewer] Implemented zoom:
* Added a manual zoom mode
* Added an automatic zoom mode (fit zoom to flickable width)
* Added a bottom panel with a zoom selector (which includes a TextField and an OptionSelector)

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
176. By Stefano Verzegnassi

Merged 'reboot' trunk

177. By Stefano Verzegnassi

Updated translation template

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'po/com.ubuntu.docviewer.pot'
2--- po/com.ubuntu.docviewer.pot 2015-09-30 23:56:04 +0000
3+++ po/com.ubuntu.docviewer.pot 2015-10-10 12:15:25 +0000
4@@ -8,7 +8,7 @@
5 msgstr ""
6 "Project-Id-Version: \n"
7 "Report-Msgid-Bugs-To: \n"
8-"POT-Creation-Date: 2015-10-01 01:55+0200\n"
9+"POT-Creation-Date: 2015-10-10 14:14+0200\n"
10 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12 "Language-Team: LANGUAGE <LL@li.org>\n"
13@@ -19,12 +19,12 @@
14 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
15
16 #: ../src/app/docviewer-application.cpp:162
17-#: /tmp/build-reboot-lok-goto-dialog-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
18+#: /tmp/build-reboot-lok-qsg-zoom-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
19 msgid "Document Viewer"
20 msgstr ""
21
22 #: ../src/app/qml/common/DetailsPage.qml:27
23-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:114
24+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:116
25 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:97
26 #: ../src/app/qml/textView/TextViewDefaultHeader.qml:83
27 msgid "Details"
28@@ -63,7 +63,7 @@
29 #: ../src/app/qml/common/RejectedImportDialog.qml:38
30 #: ../src/app/qml/documentPage/DocumentPageSelectionModeHeader.qml:32
31 #: ../src/app/qml/documentPage/SortSettingsDialog.qml:53
32-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:77
33+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:80
34 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
35 #: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
36 msgid "Close"
37@@ -254,7 +254,8 @@
38 msgstr ""
39
40 #: ../src/app/qml/documentPage/DocumentPageSearchHeader.qml:27
41-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:77
42+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:80
43+#: ../src/app/qml/loView/LOViewPage.qml:186
44 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
45 #: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
46 msgid "Back"
47@@ -305,41 +306,50 @@
48 msgid "Reverse order"
49 msgstr ""
50
51-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:58
52+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:57
53+#: ../src/app/qml/textView/TextView.qml:42
54+msgid "Loading..."
55+msgstr ""
56+
57+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:61
58 msgid "LibreOffice text document"
59 msgstr ""
60
61-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:60
62+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:63
63 msgid "LibreOffice spread sheet"
64 msgstr ""
65
66-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:62
67+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:65
68 msgid "LibreOffice presentation"
69 msgstr ""
70
71-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:64
72+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:67
73 msgid "LibreOffice Draw document"
74 msgstr ""
75
76-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:66
77+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:69
78 msgid "Unknown LibreOffice document"
79 msgstr ""
80
81-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:68
82+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:71
83 msgid "Unknown type document"
84 msgstr ""
85
86-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:101
87+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:96
88+msgid "Show zoom controls"
89+msgstr ""
90+
91+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:103
92 msgid "Go to position..."
93 msgstr ""
94
95-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:108
96+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:110
97 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:91
98 #: ../src/app/qml/textView/TextViewDefaultHeader.qml:77
99 msgid "Disable night mode"
100 msgstr ""
101
102-#: ../src/app/qml/loView/LOViewDefaultHeader.qml:108
103+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:110
104 #: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:91
105 #: ../src/app/qml/textView/TextViewDefaultHeader.qml:77
106 msgid "Enable night mode"
107@@ -358,6 +368,37 @@
108 msgid "GO!"
109 msgstr ""
110
111+#: ../src/app/qml/loView/LOViewPage.qml:41
112+#: ../src/app/qml/loView/LOViewPage.qml:184
113+msgid "Slides"
114+msgstr ""
115+
116+#: ../src/app/qml/loView/LOViewZoomHeader.qml:42
117+msgid "Hide zoom controls"
118+msgstr ""
119+
120+#: ../src/app/qml/loView/LOViewZoomHeader.qml:49
121+msgid "Zoom in"
122+msgstr ""
123+
124+#: ../src/app/qml/loView/LOViewZoomHeader.qml:55
125+msgid "Zoom out"
126+msgstr ""
127+
128+#: ../src/app/qml/loView/ZoomSelector.qml:29
129+msgid "Automatic (Fit width)"
130+msgstr ""
131+
132+#: ../src/app/qml/loView/ZoomSelector.qml:94
133+#, qt-format
134+msgid "Automatic (%1%)"
135+msgstr ""
136+
137+#: ../src/app/qml/loView/ZoomSelector.qml:95
138+#, qt-format
139+msgid "Zoom: %1%"
140+msgstr ""
141+
142 #. TRANSLATORS: "Contents" refers to the "Table of Contents" of a PDF document.
143 #: ../src/app/qml/pdfView/PdfContentsPage.qml:32
144 #: ../src/app/qml/pdfView/PdfView.qml:37
145@@ -388,10 +429,6 @@
146 msgid "Choose a page between 1 and %1"
147 msgstr ""
148
149-#: ../src/app/qml/textView/TextView.qml:42
150-msgid "Loading..."
151-msgstr ""
152-
153 #. TRANSLATORS: This string is used for renaming a copied file,
154 #. when a file with the same name already exists in user's
155 #. Documents folder.
156@@ -406,6 +443,6 @@
157 msgid "copy %1"
158 msgstr ""
159
160-#: /tmp/build-reboot-lok-goto-dialog-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
161+#: /tmp/build-reboot-lok-qsg-zoom-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
162 msgid "documents;viewer;pdf;reader;"
163 msgstr ""
164
165=== modified file 'src/app/main.cpp'
166--- src/app/main.cpp 2015-03-03 16:49:48 +0000
167+++ src/app/main.cpp 2015-10-10 12:15:25 +0000
168@@ -19,6 +19,7 @@
169
170 // Uncomment if you need to use QML analyzer
171 // #define QT_QML_DEBUG
172+// #include <QtQuick>
173
174 #include "docviewer-application.h"
175 #include <QDebug>
176
177=== added file 'src/app/qml/loView/KeybHelper.js'
178--- src/app/qml/loView/KeybHelper.js 1970-01-01 00:00:00 +0000
179+++ src/app/qml/loView/KeybHelper.js 2015-10-10 12:15:25 +0000
180@@ -0,0 +1,57 @@
181+/*
182+ * Copyright (C) 2015 Stefano Verzegnassi
183+ *
184+ * This program is free software; you can redistribute it and/or modify
185+ * it under the terms of the GNU General Public License as published by
186+ * the Free Software Foundation; version 3.
187+ *
188+ * This program is distributed in the hope that it will be useful,
189+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
190+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
191+ * GNU General Public License for more details.
192+ *
193+ * You should have received a copy of the GNU General Public License
194+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
195+ */
196+
197+function parseEvent(event) {
198+ var pixelDiff = 5;
199+
200+ if (event.key == Qt.Key_PageUp) {
201+ if (loDocument.documentType == LO.Document.PresentationDocument)
202+ loDocument.currentPart -= 1
203+ else
204+ loPage.moveView("vertical", -loView.height)
205+
206+ return;
207+ }
208+
209+ if (event.key == Qt.Key_PageDown) {
210+ if (loDocument.documentType == LO.Document.PresentationDocument)
211+ loDocument.currentPart += 1
212+ else
213+ loPage.moveView("vertical", loView.height)
214+
215+ return;
216+ }
217+
218+ if (event.key == Qt.Key_Up) {
219+ loPage.moveView("vertical", -pixelDiff)
220+ return;
221+ }
222+
223+ if (event.key == Qt.Key_Down) {
224+ loPage.moveView("vertical", pixelDiff)
225+ return;
226+ }
227+
228+ if (event.key == Qt.Key_Left) {
229+ loPage.moveView("horizontal", -pixelDiff)
230+ return;
231+ }
232+
233+ if (event.key == Qt.Key_Right) {
234+ loPage.moveView("horizontal", pixelDiff)
235+ return;
236+ }
237+}
238
239=== modified file 'src/app/qml/loView/LOViewDefaultHeader.qml'
240--- src/app/qml/loView/LOViewDefaultHeader.qml 2015-09-18 18:30:05 +0000
241+++ src/app/qml/loView/LOViewDefaultHeader.qml 2015-10-10 12:15:25 +0000
242@@ -53,7 +53,10 @@
243
244 fontSize: "small"
245 text: {
246- switch(loDocument.documentType) {
247+ if (!loPageContentLoader.item)
248+ return i18n.tr("Loading...")
249+
250+ switch(loPageContentLoader.item.loDocument.documentType) {
251 case 0:
252 return i18n.tr("LibreOffice text document")
253 case 1:
254@@ -89,10 +92,9 @@
255
256 actions: [
257 Action {
258- iconName: "search"
259- // onTriggered: pageMain.state = "search"
260- //Disable it until we provide search in Poppler plugin.
261- enabled: false
262+ iconName: "zoom-in"
263+ text: i18n.tr("Show zoom controls")
264+ onTriggered: targetPage.state = "zoom"
265 },
266
267 Action {
268
269=== removed file 'src/app/qml/loView/LOViewDelegate.qml'
270--- src/app/qml/loView/LOViewDelegate.qml 2015-06-24 12:04:16 +0000
271+++ src/app/qml/loView/LOViewDelegate.qml 1970-01-01 00:00:00 +0000
272@@ -1,95 +0,0 @@
273-/*
274- * Copyright (C) 2013-2015 Canonical, Ltd.
275- *
276- * This program is free software; you can redistribute it and/or modify
277- * it under the terms of the GNU General Public License as published by
278- * the Free Software Foundation; version 3.
279- *
280- * This program is distributed in the hope that it will be useful,
281- * but WITHOUT ANY WARRANTY; without even the implied warranty of
282- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
283- * GNU General Public License for more details.
284- *
285- * You should have received a copy of the GNU General Public License
286- * along with this program. If not, see <http://www.gnu.org/licenses/>.
287- */
288-import QtQuick 2.3
289-import Ubuntu.Components 1.1
290-
291-Rectangle {
292- id: loPage
293-
294- property int index: model.index
295- property bool _previewFetched: false
296-
297- property alias status: pageImg.status
298-
299- width: parent.width
300- height: width * (model.height / model.width)
301- color: "#E6E6E6"
302-
303- // Preview page rendering. Used as placeholder while zooming the page.
304- // We generate the low resolution preview from the texture of the PDF page,
305- // so that we can keep page rendering as fast as possible.
306- ShaderEffectSource {
307- id: previewImg
308- anchors.fill: parent
309-
310- // We cannot change its opacity or visibility, otherwise the texture will be refreshed,
311- // even if live is false.
312- live: false
313- textureSize: Qt.size(256, 256 * (model.height / model.width))
314- }
315-
316- Image {
317- id: pageImg
318- anchors.fill: parent
319-
320- source: "image://libreoffice/page/" + index;
321- sourceSize.width: loPage.width
322-
323- onStatusChanged: {
324- // This is supposed to run the first time PdfViewDelegate gets the page rendering.
325- if (!_previewFetched) {
326- if (status == Image.Ready) {
327- previewImg.sourceItem = pageImg
328- // Re-assign sourceItem property, so the texture is not updated when Image status changes.
329- previewImg.sourceItem = loPage
330- }
331- }
332- }
333-
334- // Request a new page rendering. The order, which pages are requested with, depends on the distance from the currentPage
335- Timer {
336- id: _zoomTimer
337- interval: {
338- var diff = Math.abs(loView.currentPageIndex - model.index)
339- var prov = loDocument.providersNumber * 0.5
340-
341- if (diff < prov)
342- return 0
343- else
344- return (diff - prov) * 10
345- }
346-
347- onTriggered: {
348- pageImg.sourceSize.width = loPage.width;
349- }
350- }
351- }
352-
353- // Page rendering depends on the width of PdfViewDelegate.
354- // Because of this, we have multiple callings to ImageProvider while zooming.
355- // Just avoid it.
356- Connections {
357- target: pinchy
358-
359- onPinchStarted: _zoomTimer.stop();
360- onPinchUpdated: {
361- // This ensures that page image is not reloaded when the maximumScale or minimumScale has already been reached.
362- if ( !(_zoomHelper.scale >= 2.5 && pinch.scale > 1.0) && !(_zoomHelper.scale <= 1.0 && pinch.scale < 1.0) )
363- pageImg.sourceSize.width = 0;
364- }
365- onPinchFinished: _zoomTimer.restart();
366- }
367-}
368
369=== added file 'src/app/qml/loView/LOViewGotoDialog.qml'
370--- src/app/qml/loView/LOViewGotoDialog.qml 1970-01-01 00:00:00 +0000
371+++ src/app/qml/loView/LOViewGotoDialog.qml 2015-10-10 12:15:25 +0000
372@@ -0,0 +1,64 @@
373+/*
374+ * Copyright (C) 2014-2015 Canonical, Ltd.
375+ *
376+ * This program is free software; you can redistribute it and/or modify
377+ * it under the terms of the GNU General Public License as published by
378+ * the Free Software Foundation; version 3.
379+ *
380+ * This program is distributed in the hope that it will be useful,
381+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
382+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
383+ * GNU General Public License for more details.
384+ *
385+ * You should have received a copy of the GNU General Public License
386+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
387+ */
388+
389+import QtQuick 2.3
390+import Ubuntu.Components 1.1
391+import Ubuntu.Components.Popups 1.0
392+
393+// TODO: Use page breaks detection, when LibreOfficeKit will support it.
394+
395+Dialog {
396+ id: goToPageDialog
397+ objectName: "LOViewGotoDialog"
398+
399+ title: i18n.tr("Go to position")
400+ text: i18n.tr("Choose a position between 1% and 100%")
401+
402+ TextField {
403+ id: goToPageTextField
404+ objectName:"goToPageTextField"
405+
406+ width: parent.width
407+
408+ hasClearButton: true
409+ inputMethodHints: Qt.ImhFormattedNumbersOnly
410+ validator: IntValidator{ bottom: 1; top: 100 }
411+
412+ Keys.onReturnPressed: goToPage()
413+ Component.onCompleted: forceActiveFocus()
414+ }
415+
416+ Button {
417+ objectName:"GOButton"
418+ text: i18n.tr("GO!")
419+ color: UbuntuColors.green
420+
421+ enabled: goToPageTextField.acceptableInput
422+ onClicked: goToPage()
423+ }
424+
425+ Button {
426+ text: i18n.tr("Cancel")
427+ onClicked: PopupUtils.close(goToPageDialog)
428+ }
429+
430+ function goToPage() {
431+ var pos = loView.contentHeight * parseInt(goToPageTextField.text) / 100
432+
433+ loView.contentY = Math.min(pos, (loView.contentHeight - loView.height))
434+ PopupUtils.close(goToPageDialog)
435+ }
436+}
437
438=== removed file 'src/app/qml/loView/LOViewGotoDialog.qml'
439--- src/app/qml/loView/LOViewGotoDialog.qml 2015-09-18 18:30:05 +0000
440+++ src/app/qml/loView/LOViewGotoDialog.qml 1970-01-01 00:00:00 +0000
441@@ -1,64 +0,0 @@
442-/*
443- * Copyright (C) 2014-2015 Canonical, Ltd.
444- *
445- * This program is free software; you can redistribute it and/or modify
446- * it under the terms of the GNU General Public License as published by
447- * the Free Software Foundation; version 3.
448- *
449- * This program is distributed in the hope that it will be useful,
450- * but WITHOUT ANY WARRANTY; without even the implied warranty of
451- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
452- * GNU General Public License for more details.
453- *
454- * You should have received a copy of the GNU General Public License
455- * along with this program. If not, see <http://www.gnu.org/licenses/>.
456- */
457-
458-import QtQuick 2.3
459-import Ubuntu.Components 1.1
460-import Ubuntu.Components.Popups 1.0
461-
462-// TODO: Use page breaks detection, when LibreOfficeKit will support it.
463-
464-Dialog {
465- id: goToPageDialog
466- objectName: "LOViewGotoDialog"
467-
468- title: i18n.tr("Go to position")
469- text: i18n.tr("Choose a position between 1% and 100%")
470-
471- TextField {
472- id: goToPageTextField
473- objectName:"goToPageTextField"
474-
475- width: parent.width
476-
477- hasClearButton: true
478- inputMethodHints: Qt.ImhFormattedNumbersOnly
479- validator: IntValidator{ bottom: 1; top: 100 }
480-
481- Keys.onReturnPressed: goToPage()
482- Component.onCompleted: forceActiveFocus()
483- }
484-
485- Button {
486- objectName:"GOButton"
487- text: i18n.tr("GO!")
488- color: UbuntuColors.green
489-
490- enabled: goToPageTextField.acceptableInput
491- onClicked: goToPage()
492- }
493-
494- Button {
495- text: i18n.tr("Cancel")
496- onClicked: PopupUtils.close(goToPageDialog)
497- }
498-
499- function goToPage() {
500- var pos = loView.contentHeight * parseInt(goToPageTextField.text) / 100
501-
502- loView.contentY = Math.min(pos, (loView.contentHeight - loView.height))
503- PopupUtils.close(goToPageDialog)
504- }
505-}
506
507=== modified file 'src/app/qml/loView/LOViewPage.qml'
508--- src/app/qml/loView/LOViewPage.qml 2015-09-19 15:16:51 +0000
509+++ src/app/qml/loView/LOViewPage.qml 2015-10-10 12:15:25 +0000
510@@ -16,28 +16,53 @@
511
512 import QtQuick 2.3
513 import Ubuntu.Components 1.1
514+import Ubuntu.Layouts 1.0
515 import DocumentViewer.LibreOffice 1.0 as LO
516
517+import "../upstreamComponents"
518+
519 import "../common/utils.js" as Utils
520-import "../upstreamComponents"
521+import "KeybHelper.js" as KeybHelper
522
523-Page {
524+PageWithBottomEdge {
525 id: loPage
526 title: Utils.getNameOfFile(file.path);
527-
528- // Disable header auto-hide.
529 flickable: null
530
531+ readonly property bool wideWindow: width > units.gu(120)
532+
533+ bottomEdgeEnabled: {
534+ if (!loPageContentLoader.loaded)
535+ return false
536+
537+ // else
538+ return loPageContentLoader.item.loDocument.documentType == LO.Document.PresentationDocument && !wideWindow
539+ }
540+ bottomEdgeTitle: i18n.tr("Slides")
541+
542 Loader {
543- id: contentLoader
544+ id: loPageContentLoader
545
546 asynchronous: true
547 anchors.fill: parent
548 sourceComponent: loPageContentComponent
549+
550+ onLoaded: {
551+ if (loaded) {
552+ // FIXME: At the moment don't hide header if the document is a presentation
553+ var isPresentation = (item.loDocument.documentType === LO.Document.PresentationDocument)
554+ loPage.flickable = isPresentation ? null : item.loView
555+
556+ loPage.bottomEdgePageComponent = item.bottomEdgePartsPage
557+
558+ } else {
559+ loPage.flickable = null
560+ }
561+ }
562 }
563
564 ActivityIndicator {
565- running: contentLoader.status != Loader.Ready
566+ running: loPageContentLoader.status != Loader.Ready
567 visible: running
568 anchors.centerIn: parent
569 }
570@@ -46,32 +71,145 @@
571 id: loPageContentComponent
572
573 Item {
574+ id: loPageContent
575+ anchors.fill: parent
576 property alias loDocument: loView.document
577-
578- LO.Viewer {
579- id: loView
580- objectName: "loView"
581+ property alias loView: loView
582+ property alias bottomEdgePartsPage: bottomEdgePartsPage
583+
584+ function moveView(axis, diff) {
585+ if (axis == "vertical") {
586+ var maxContentY = Math.max(0, loView.contentHeight - loView.height)
587+ loView.contentY = Math.max(0, Math.min(loView.contentY + diff, maxContentY ))
588+ } else {
589+ var maxContentX = Math.max(0, loView.contentWidth - loView.width)
590+ loView.contentX = Math.max(0, Math.min(loView.contentX + diff, maxContentX ))
591+ }
592+ }
593+
594+ Layouts {
595+ id: layouts
596 anchors.fill: parent
597
598- clip: true
599- documentPath: file.path
600-
601- Component.onCompleted: {
602- // WORKAROUND: Fix for wrong grid unit size
603- flickDeceleration = 1500 * units.gridUnit / 8
604- maximumFlickVelocity = 2500 * units.gridUnit / 8
605- }
606- }
607-
608- Scrollbar { flickableItem: loView }
609- Scrollbar { flickableItem: loView; align: Qt.AlignBottom }
610+ layouts: [
611+ ConditionalLayout {
612+ when: wideWindow
613+ name: "wideWindowLayout"
614+
615+ Item {
616+ anchors.fill: parent
617+
618+ // TODO: Add a setting to show/hide sidebar when width > units.gu(80)
619+ PartsView {
620+ id: partsView
621+ anchors {
622+ top: parent.top
623+ bottom: bottomBarLayoutItem.top
624+ left: parent.left
625+ }
626+
627+ model: partsModel
628+ visible: model
629+ width: visible ? units.gu(40) : 0
630+ }
631+
632+ Item {
633+ anchors {
634+ left: partsView.right
635+ right: parent.right
636+ top: parent.top
637+ bottom: bottomBarLayoutItem.top
638+ }
639+ ItemLayout { item: "loView"; anchors.fill: parent }
640+ }
641+
642+ Item {
643+ id: bottomBarLayoutItem
644+ visible: loDocument.documentType == LO.Document.PresentationDocument
645+ height: visible ? units.gu(5) : 0
646+ anchors {
647+ left: parent.left
648+ right: parent.right
649+ bottom: parent.bottom
650+ }
651+
652+ ItemLayout { item: "bottomBar"; anchors.fill: parent }
653+ }
654+ }
655+ }
656+ ]
657+
658+ LO.Viewer {
659+ id: loView
660+ objectName: "loView"
661+ Layouts.item: "loView"
662+ anchors {
663+ left: parent.left
664+ right: parent.right
665+ top: parent.top
666+ bottom: bottomBar.top
667+ }
668+
669+ clip: true
670+ documentPath: file.path
671+
672+ Component.onCompleted: {
673+ // WORKAROUND: Fix for wrong grid unit size
674+ flickDeceleration = 1500 * units.gridUnit / 8
675+ maximumFlickVelocity = 2500 * units.gridUnit / 8
676+ }
677+
678+ Scrollbar { flickableItem: loView; parent: loView.parent }
679+ Scrollbar { flickableItem: loView; parent: loView.parent; align: Qt.AlignBottom }
680+ }
681+
682+ // TODO: When we'll have to merge this with the zooming branch, replace this
683+ // and use a single bottom panel
684+ SlideControllerPanel {
685+ id: bottomBar
686+ Layouts.item: "bottomBar"
687+ visible: loDocument.documentType == LO.Document.PresentationDocument
688+ height: visible ? units.gu(5) : 0
689+ anchors {
690+ left: parent.left
691+ right: parent.right
692+ bottom: parent.bottom
693+ }
694+ }
695+ }
696+
697+ Component {
698+ id: bottomEdgePartsPage
699+ Page {
700+ title: i18n.tr("Slides")
701+ head.backAction: Action {
702+ text: i18n.tr("Back")
703+ iconName: "down"
704+ onTriggered: pageStack.pop()
705+ }
706+
707+ flickable: null
708+
709+ PartsView {
710+ anchors.fill: parent
711+ model: LO.PartsModel { document: loPageContent.loDocument }
712+ }
713+ }
714+ }
715 }
716 }
717
718 // *** HEADER ***
719 state: "default"
720- states: LOViewDefaultHeader {
721- name: "default"
722- targetPage: loPage
723- }
724+ states: [
725+ LOViewDefaultHeader {
726+ name: "default"
727+ targetPage: loPage
728+ },
729+
730+ LOViewZoomHeader {
731+ name: "zoom"
732+ targetPage: loPage
733+ }
734+ ]
735 }
736
737=== added file 'src/app/qml/loView/LOViewZoomHeader.qml'
738--- src/app/qml/loView/LOViewZoomHeader.qml 1970-01-01 00:00:00 +0000
739+++ src/app/qml/loView/LOViewZoomHeader.qml 2015-10-10 12:15:25 +0000
740@@ -0,0 +1,59 @@
741+/*
742+ * Copyright (C) 2014-2015 Canonical, Ltd.
743+ *
744+ * This program is free software; you can redistribute it and/or modify
745+ * it under the terms of the GNU General Public License as published by
746+ * the Free Software Foundation; version 3.
747+ *
748+ * This program is distributed in the hope that it will be useful,
749+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
750+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
751+ * GNU General Public License for more details.
752+ *
753+ * You should have received a copy of the GNU General Public License
754+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
755+ */
756+
757+import QtQuick 2.3
758+import Ubuntu.Components 1.1
759+import QtQuick.Layouts 1.1
760+import Ubuntu.Components.Popups 1.0
761+
762+PageHeadState {
763+ id: rootItem
764+
765+ property Page targetPage
766+ head: targetPage.head
767+
768+ contents: Item {
769+ anchors.fill: parent
770+
771+ ZoomSelector {
772+ width: units.gu(24)
773+ anchors {
774+ right: parent.right
775+ verticalCenter: parent.verticalCenter
776+ }
777+ }
778+ }
779+
780+ backAction: Action {
781+ iconName: "close"
782+ text: i18n.tr("Hide zoom controls")
783+ onTriggered: targetPage.state = "default"
784+ }
785+
786+ actions: [
787+ Action {
788+ iconName: "zoom-in"
789+ text: i18n.tr("Zoom in")
790+ onTriggered: loPageContentLoader.item.loView.zoomFactor += 0.1
791+ },
792+
793+ Action {
794+ iconName: "zoom-out"
795+ text: i18n.tr("Zoom out")
796+ onTriggered: loPageContentLoader.item.loView.zoomFactor -= 0.1
797+ }
798+ ]
799+}
800
801=== added file 'src/app/qml/loView/PanelButton.qml'
802--- src/app/qml/loView/PanelButton.qml 1970-01-01 00:00:00 +0000
803+++ src/app/qml/loView/PanelButton.qml 2015-10-10 12:15:25 +0000
804@@ -0,0 +1,31 @@
805+/*
806+ * Copyright (C) 2015 Canonical, Ltd.
807+ *
808+ * This program is free software; you can redistribute it and/or modify
809+ * it under the terms of the GNU General Public License as published by
810+ * the Free Software Foundation; version 3.
811+ *
812+ * This program is distributed in the hope that it will be useful,
813+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
814+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
815+ * GNU General Public License for more details.
816+ *
817+ * You should have received a copy of the GNU General Public License
818+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
819+ */
820+
821+import QtQuick 2.3
822+import Ubuntu.Components 1.1
823+
824+AbstractButton {
825+ width: units.gu(4); height: parent.height
826+
827+ property alias iconName: icon.name
828+ property alias iconSource: icon.source
829+
830+ Icon {
831+ id: icon
832+ anchors.centerIn: parent
833+ width: units.gu(2.5); height: width
834+ }
835+}
836
837=== added file 'src/app/qml/loView/PartsView.qml'
838--- src/app/qml/loView/PartsView.qml 1970-01-01 00:00:00 +0000
839+++ src/app/qml/loView/PartsView.qml 2015-10-10 12:15:25 +0000
840@@ -0,0 +1,81 @@
841+/*
842+ * Copyright (C) 2015 Stefano Verzegnassi
843+ *
844+ * This program is free software; you can redistribute it and/or modify
845+ * it under the terms of the GNU General Public License as published by
846+ * the Free Software Foundation; version 3.
847+ *
848+ * This program is distributed in the hope that it will be useful,
849+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
850+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
851+ * GNU General Public License for more details.
852+ *
853+ * You should have received a copy of the GNU General Public License
854+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
855+ */
856+
857+import QtQuick 2.3
858+import Ubuntu.Components 1.1
859+import QtQuick.Layouts 1.1
860+import DocumentViewer.LibreOffice 1.0 as LibreOffice
861+
862+import "../upstreamComponents"
863+
864+ListView {
865+ id: view
866+ objectName: "view"
867+ clip: true
868+
869+ property bool expanded: true
870+
871+ currentIndex: view.model ? view.model.document.currentPart : -1
872+
873+ delegate: ListItemWithActions {
874+ id: delegate
875+
876+ width: parent.width
877+ height: units.gu(16)
878+
879+ color: (view.model.document.currentPart === model.index) ? Theme.palette.selected.background
880+ : "transparent"
881+
882+ AbstractButton {
883+ objectName: "abstractbutton"
884+ anchors.fill: parent
885+
886+ onClicked: {
887+ view.model.document.currentPart = model.index
888+ pageStack.pop();
889+ }
890+ }
891+
892+ RowLayout {
893+ anchors.fill: parent
894+ spacing: units.gu(1)
895+
896+ Image {
897+ Layout.fillHeight: true
898+ Layout.preferredWidth: height
899+ fillMode: Image.PreserveAspectFit
900+
901+ source: "image://lok/part/" + model.index
902+ }
903+
904+ Label {
905+ Layout.fillWidth: true
906+ wrapMode: Text.WordWrap
907+ text: model.name
908+ color: (view.model.document.currentPart === model.index) ? UbuntuColors.orange
909+ : Theme.palette.selected.backgroundText
910+ }
911+
912+ Label {
913+ text: model.index + 1
914+ color: (view.model.document.currentPart === model.index) ? UbuntuColors.orange
915+ : Theme.palette.selected.backgroundText
916+ }
917+ }
918+ }
919+
920+ Scrollbar { flickableItem: view; parent: view.parent }
921+}
922
923=== added file 'src/app/qml/loView/SlideControllerPanel.qml'
924--- src/app/qml/loView/SlideControllerPanel.qml 1970-01-01 00:00:00 +0000
925+++ src/app/qml/loView/SlideControllerPanel.qml 2015-10-10 12:15:25 +0000
926@@ -0,0 +1,67 @@
927+/*
928+ * Copyright (C) 2015 Stefano Verzegnassi
929+ *
930+ * This program is free software; you can redistribute it and/or modify
931+ * it under the terms of the GNU General Public License as published by
932+ * the Free Software Foundation; version 3.
933+ *
934+ * This program is distributed in the hope that it will be useful,
935+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
936+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
937+ * GNU General Public License for more details.
938+ *
939+ * You should have received a copy of the GNU General Public License
940+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
941+ */
942+
943+import QtQuick 2.3
944+import Ubuntu.Components 1.1
945+import QtQuick.Layouts 1.1
946+import Ubuntu.Components.ListItems 1.0 as ListItems
947+
948+Rectangle {
949+ id: bottomBar
950+ color: "transparent"
951+ height: units.gu(5)
952+
953+ ListItems.ThinDivider {
954+ anchors {
955+ top: parent.top
956+ left: parent.left
957+ right: parent.right
958+ }
959+ }
960+
961+ Row {
962+ anchors.centerIn: parent
963+ spacing: units.gu(2)
964+
965+ AbstractButton {
966+ width: units.gu(4); height: parent.height
967+ onClicked: loPageContentLoader.item.loDocument.currentPart -= 1
968+
969+ Icon {
970+ id: icon
971+ anchors.centerIn: parent
972+ width: units.gu(2.5); height: width
973+ name: "go-previous"
974+ }
975+ }
976+
977+ Label {
978+ text: "%1 of %2".arg(loPageContentLoader.item.loDocument.currentPart + 1)
979+ .arg(loPageContentLoader.item.loDocument.partsCount)
980+ }
981+
982+ AbstractButton {
983+ width: units.gu(4); height: parent.height
984+ onClicked: loPageContentLoader.item.loDocument.currentPart += 1
985+
986+ Icon {
987+ anchors.centerIn: parent
988+ width: units.gu(2.5); height: width
989+ name: "go-next"
990+ }
991+ }
992+ }
993+}
994
995=== added file 'src/app/qml/loView/ZoomSelector.qml'
996--- src/app/qml/loView/ZoomSelector.qml 1970-01-01 00:00:00 +0000
997+++ src/app/qml/loView/ZoomSelector.qml 2015-10-10 12:15:25 +0000
998@@ -0,0 +1,149 @@
999+/*
1000+ * Copyright (C) 2015 Canonical, Ltd.
1001+ *
1002+ * This program is free software; you can redistribute it and/or modify
1003+ * it under the terms of the GNU General Public License as published by
1004+ * the Free Software Foundation; version 3.
1005+ *
1006+ * This program is distributed in the hope that it will be useful,
1007+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1008+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1009+ * GNU General Public License for more details.
1010+ *
1011+ * You should have received a copy of the GNU General Public License
1012+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1013+ */
1014+
1015+import QtQuick 2.3
1016+import Ubuntu.Components 1.1
1017+import Ubuntu.Components.Popups 1.0
1018+import DocumentViewer.LibreOffice 1.0 as LibreOffice
1019+
1020+TextField {
1021+ id: textField
1022+ anchors.verticalCenter: parent.verticalCenter
1023+ width: units.gu(24)
1024+
1025+ property var values: ["auto", 0.5, 0.7, 0.85, 1.0, 1.25, 1.5, 1.75, 2.0, 3.0, 4.0]
1026+ property var labels: [
1027+ i18n.tr("Automatic (Fit width)"),
1028+ "50%", "70%", "85%", "100%", "125%",
1029+ "150%", "175%","200%", "300%", "400%"
1030+ ]
1031+
1032+ property bool expanded: false
1033+
1034+ hasClearButton: true
1035+ inputMethodHints: Qt.ImhFormattedNumbersOnly
1036+ validator: IntValidator{ bottom: 50; top: 400 }
1037+
1038+ onAccepted: {
1039+ loPageContentLoader.item.loView.zoomFactor = parseInt(text) / 100
1040+ focus = false
1041+ }
1042+
1043+ secondaryItem: AbstractButton {
1044+ visible: !textField.highlighted
1045+ id: listButton
1046+ height: parent.height
1047+ width: visible ? height : 0
1048+
1049+ Rectangle {
1050+ anchors.left: parent.left
1051+ anchors.verticalCenter: parent.verticalCenter
1052+ height: parent.height - units.gu(1)
1053+
1054+ width: units.dp(1)
1055+ color: "Grey"
1056+ opacity: 0.5
1057+ }
1058+
1059+ Icon {
1060+ id: _upArrow
1061+
1062+ width: units.gu(2)
1063+ height: width
1064+ anchors.centerIn: parent
1065+
1066+ name: "go-down"
1067+ color: "Grey"
1068+ rotation: textField.expanded ? 180 : 0
1069+
1070+ Behavior on rotation {
1071+ UbuntuNumberAnimation {}
1072+ }
1073+ }
1074+
1075+ onClicked: {
1076+ textField.expanded = true
1077+ PopupUtils.open(zoomSelectorDialog, listButton)
1078+ }
1079+ }
1080+
1081+ onHighlightedChanged: {
1082+ if (highlighted) {
1083+ text = parseInt(loPageContentLoader.item.loView.zoomFactor * 100)
1084+ } else text = ""
1085+ }
1086+
1087+ Label {
1088+ anchors.verticalCenter: parent.verticalCenter
1089+ anchors.left: parent.left
1090+ anchors.leftMargin: units.gu(2)
1091+ visible: !textField.highlighted
1092+ text: loPageContentLoader.item.loView.zoomMode == LibreOffice.View.FitToWidth ? i18n.tr("Automatic (%1%)").arg(parseInt(loPageContentLoader.item.loView.zoomFactor*100))
1093+ : i18n.tr("Zoom: %1%").arg(parseInt(loPageContentLoader.item.loView.zoomFactor*100))
1094+ }
1095+
1096+ Component {
1097+ id: zoomSelectorDialog
1098+ Popover {
1099+ id: zoomSelectorDialogue
1100+ autoClose: false
1101+ contentHeight: units.gu(24)
1102+ contentWidth: units.gu(24)
1103+ Component.onDestruction: textField.expanded = false
1104+
1105+ // We don't use 'autoClose' property, since we want to propagate
1106+ // mouse/touch events to other items (e.g. when zoomSelectorDialogue
1107+ // is visible, and user taps the zoom+ button on its right, we want
1108+ // the zoom button to receive the event).
1109+ InverseMouseArea {
1110+ anchors.fill: parent
1111+ propagateComposedEvents: true
1112+
1113+ onPressed: {
1114+ mouse.accepted = false
1115+ PopupUtils.close(zoomSelectorDialogue)
1116+ }
1117+ }
1118+
1119+ OptionSelector {
1120+ expanded: true
1121+ width: parent.width
1122+ containerHeight: units.gu(24)
1123+ model: textField.labels
1124+ selectedIndex: {
1125+ if (loPageContentLoader.item.loView.zoomMode == LibreOffice.View.FitToWidth)
1126+ return 0
1127+
1128+ for (var i=0; i<textField.values.length; i++) {
1129+ if (values[i] == loView.zoomFactor)
1130+ return i
1131+ }
1132+ return -1
1133+ }
1134+
1135+ onSelectedIndexChanged: {
1136+ if (selectedIndex == 0) {
1137+ loView.adjustZoomToWidth();
1138+ return;
1139+ }
1140+
1141+ loPageContentLoader.item.loView.zoomFactor = textField.values[selectedIndex]
1142+ PopupUtils.close(zoomSelectorDialogue)
1143+ }
1144+ }
1145+ }
1146+ }
1147+}
1148
1149=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
1150--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-09-18 09:35:04 +0000
1151+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-10-10 12:15:25 +0000
1152@@ -17,6 +17,8 @@
1153 lodocument.cpp
1154 loview.cpp
1155 sgtileitem.cpp
1156+ lopartsimageprovider.cpp
1157+ lopartsmodel.cpp
1158 renderengine.cpp
1159 ${QML_SRCS}
1160 )
1161
1162=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
1163--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-09-18 11:18:17 +0000
1164+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-10-10 12:15:25 +0000
1165@@ -60,6 +60,25 @@
1166 this->loadDocument(m_path);
1167 }
1168
1169+int LODocument::currentPart() {
1170+ if (!m_document)
1171+ return int(-1);
1172+
1173+ return m_document->getPart();
1174+}
1175+
1176+void LODocument::setCurrentPart(int index)
1177+{
1178+ if (!m_document)
1179+ return;
1180+
1181+ if (this->currentPart() == index || index < 0 || index > partsCount() - 1)
1182+ return;
1183+
1184+ m_document->setPart(index);
1185+ Q_EMIT currentPartChanged();
1186+}
1187+
1188 // Load the document
1189 bool LODocument::loadDocument(const QString &pathName)
1190 {
1191@@ -106,7 +125,7 @@
1192
1193 // Paint a tile, with size=canvasSize, of the part of the document defined by
1194 // the rect tileSize.
1195-QImage LODocument::paintTile(const QSize& canvasSize, const QRect& tileSize)
1196+QImage LODocument::paintTile(const QSize& canvasSize, const QRect& tileSize, const qreal &zoom)
1197 {
1198 QImage result = QImage(canvasSize.width(), canvasSize.height(), QImage::Format_RGB32);
1199
1200@@ -117,10 +136,10 @@
1201
1202 m_document->paintTile(result.bits(),
1203 canvasSize.width(), canvasSize.height(),
1204- Twips::convertPixelsToTwips(tileSize.x()),
1205- Twips::convertPixelsToTwips(tileSize.y()),
1206- Twips::convertPixelsToTwips(tileSize.width()),
1207- Twips::convertPixelsToTwips(tileSize.height()));
1208+ Twips::convertPixelsToTwips(tileSize.x(), zoom),
1209+ Twips::convertPixelsToTwips(tileSize.y(), zoom),
1210+ Twips::convertPixelsToTwips(tileSize.width(), zoom),
1211+ Twips::convertPixelsToTwips(tileSize.height(), zoom));
1212
1213 #ifdef DEBUG_TILE_BENCHMARK
1214 qDebug() << "Time to render the tile:" << renderTimer.elapsed() << "ms";
1215@@ -129,6 +148,33 @@
1216 return result.rgbSwapped();
1217 }
1218
1219+int LODocument::partsCount()
1220+{
1221+ if (!m_document)
1222+ return int(0);
1223+
1224+ return m_document->getParts();
1225+}
1226+
1227+QString LODocument::getPartName(int index) const
1228+{
1229+ if (!m_document)
1230+ return QString();
1231+
1232+ return QString::fromLatin1(m_document->getPartName(index));
1233+}
1234+
1235+// This is used by LOPartsImageProvider to temporarily change the current part,
1236+// in order to generate thumbnails.
1237+// FIXME: We need to disable tiled rendering when we're generating the thumbnail.
1238+int LODocument::swapCurrentPart(int newPartIndex)
1239+{
1240+ int oldIndex = this->currentPart();
1241+
1242+ m_document->setPart(newPartIndex);
1243+ return oldIndex;
1244+}
1245+
1246 /* Export the file in a given format:
1247 * - url is a mandatory argument.
1248 * - format is optional. If not specified, lok will try to get it from the file
1249
1250=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.h'
1251--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2015-09-18 11:18:17 +0000
1252+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2015-10-10 12:15:25 +0000
1253@@ -31,6 +31,9 @@
1254 Q_DISABLE_COPY(LODocument)
1255
1256 Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
1257+ Q_PROPERTY(int currentPart READ currentPart WRITE setCurrentPart NOTIFY currentPartChanged)
1258+ // Declare partsCount as constant at the moment, since LOK-plugin is just a viewer for now.
1259+ Q_PROPERTY(int partsCount READ partsCount CONSTANT)
1260 Q_PROPERTY(DocumentType documentType READ documentType NOTIFY documentTypeChanged)
1261 Q_ENUMS(DocumentType)
1262
1263@@ -49,15 +52,27 @@
1264 QString path() const;
1265 void setPath(const QString& pathName);
1266
1267+ int currentPart();
1268+ void setCurrentPart(int index);
1269+
1270 DocumentType documentType() const;
1271
1272 QSize documentSize() const;
1273- QImage paintTile(const QSize& canvasSize, const QRect& tileSize);
1274+
1275+ QImage paintTile(const QSize& canvasSize, const QRect& tileSize, const qreal& zoom = 1.0);
1276+
1277+ int partsCount();
1278+
1279+ QString getPartName(int index) const;
1280+ int swapCurrentPart(int newPartIndex);
1281+
1282+ void setPart(int index);
1283
1284 Q_INVOKABLE bool saveAs(QString url, QString format, QString filterOptions);
1285
1286 Q_SIGNALS:
1287 void pathChanged();
1288+ void currentPartChanged();
1289 void documentTypeChanged();
1290
1291 private:
1292
1293=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp'
1294--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 1970-01-01 00:00:00 +0000
1295+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2015-10-10 12:15:25 +0000
1296@@ -0,0 +1,77 @@
1297+/*
1298+ * Copyright (C) 2015 Canonical, Ltd.
1299+ *
1300+ * This program is free software: you can redistribute it and/or modify it
1301+ * under the terms of the GNU General Public License version 3, as published
1302+ * by the Free Software Foundation.
1303+ *
1304+ * This program is distributed in the hope that it will be useful, but
1305+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1306+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1307+ * PURPOSE. See the GNU General Public License for more details.
1308+ *
1309+ * You should have received a copy of the GNU General Public License along
1310+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1311+ */
1312+
1313+#include "lopartsimageprovider.h"
1314+#include "lodocument.h"
1315+#include "config.h"
1316+#include "twips.h"
1317+
1318+#include <QDebug>
1319+
1320+LOPartsImageProvider::LOPartsImageProvider(LODocument *document)
1321+ : QQuickImageProvider(QQuickImageProvider::Image, QQuickImageProvider::ForceAsynchronousImageLoading)
1322+{
1323+ m_document = document;
1324+}
1325+
1326+QImage LOPartsImageProvider::requestImage(const QString & id, QSize * size, const QSize & requestedSize)
1327+{
1328+ Q_UNUSED(size)
1329+ Q_UNUSED(requestedSize)
1330+
1331+ if (m_document->documentType() != LODocument::PresentationDocument)
1332+ return QImage();
1333+
1334+ // Here's the tricky magic. For getting a thumbnail of a document part
1335+ // (e.g. a specific slide in a Impress document), we need to change the
1336+ // current active part in LODocument, render the thumbnail, then re-set
1337+ // the previous value through lok::Document::setPath(index).
1338+ QString type = id.section("/", 0, 0);
1339+
1340+ if (type != "part")
1341+ return QImage();
1342+
1343+ int partNumber = id.section("/", 1, 1).toInt();
1344+ QImage result;
1345+ QSize partSize;
1346+ QSize resultSize;
1347+
1348+ // Get the current part index and set the index of the part to be rendered.
1349+ int currentPart = m_document->swapCurrentPart(partNumber);
1350+
1351+ // Get the size of the part
1352+ partSize = m_document->documentSize();
1353+ partSize.setHeight(Twips::convertTwipsToPixels(partSize.height()));
1354+ partSize.setWidth(Twips::convertTwipsToPixels(partSize.width()));
1355+
1356+ // Set the size of the rendered thumbnail
1357+ if (partSize.width() > partSize.height()) {
1358+ resultSize.setWidth(TILE_SIZE);
1359+ resultSize.setHeight(TILE_SIZE * partSize.height() / partSize.width());
1360+ } else {
1361+ resultSize.setHeight(TILE_SIZE);
1362+ resultSize.setWidth(TILE_SIZE * partSize.width() / partSize.height());
1363+ }
1364+
1365+ // Render the part to QImage
1366+ result = m_document->paintTile(resultSize, QRect(QPoint(0, 0), partSize));
1367+
1368+ // Re-set the earlier current part
1369+ m_document->swapCurrentPart(currentPart);
1370+
1371+ return result;
1372+
1373+}
1374
1375=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h'
1376--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 1970-01-01 00:00:00 +0000
1377+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2015-10-10 12:15:25 +0000
1378@@ -0,0 +1,35 @@
1379+/*
1380+ * Copyright (C) 2015 Canonical, Ltd.
1381+ *
1382+ * This program is free software: you can redistribute it and/or modify it
1383+ * under the terms of the GNU General Public License version 3, as published
1384+ * by the Free Software Foundation.
1385+ *
1386+ * This program is distributed in the hope that it will be useful, but
1387+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1388+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1389+ * PURPOSE. See the GNU General Public License for more details.
1390+ *
1391+ * You should have received a copy of the GNU General Public License along
1392+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1393+ *
1394+ */
1395+
1396+#ifndef LOPARTSIMAGEPROVIDER_H
1397+#define LOPARTSIMAGEPROVIDER_H
1398+
1399+#include <QQuickImageProvider>
1400+
1401+class LODocument;
1402+
1403+class LOPartsImageProvider : public QQuickImageProvider
1404+{
1405+public:
1406+ LOPartsImageProvider(LODocument *document);
1407+ QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize);
1408+
1409+private:
1410+ LODocument *m_document;
1411+};
1412+
1413+#endif // LOPARTSIMAGEPROVIDER_H
1414
1415=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp'
1416--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 1970-01-01 00:00:00 +0000
1417+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 2015-10-10 12:15:25 +0000
1418@@ -0,0 +1,125 @@
1419+/*
1420+ * Copyright (C) 2015 Canonical Ltd.
1421+ *
1422+ * This program is free software: you can redistribute it and/or modify it
1423+ * under the terms of the GNU General Public License version 3, as published
1424+ * by the Free Software Foundation.
1425+ *
1426+ * This program is distributed in the hope that it will be useful, but
1427+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1428+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1429+ * PURPOSE. See the GNU General Public License for more details.
1430+ *
1431+ * You should have received a copy of the GNU General Public License along
1432+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1433+ *
1434+ */
1435+
1436+#include "lopartsmodel.h"
1437+#include "lodocument.h"
1438+#include "lopartsimageprovider.h"
1439+
1440+#include <QQmlContext>
1441+#include <QQmlEngine>
1442+#include <QDebug>
1443+
1444+LOPartsModel::LOPartsModel(QAbstractListModel *parent):
1445+ QAbstractListModel(parent)
1446+{
1447+ connect(this, SIGNAL(documentChanged()), this, SLOT(fillModel()));
1448+}
1449+
1450+void LOPartsModel::setDocument(LODocument *document)
1451+{
1452+ if (m_document == document)
1453+ return;
1454+
1455+ m_document = document;
1456+ Q_EMIT documentChanged();
1457+
1458+ QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
1459+ QString imageProviderName = "lok";
1460+
1461+ if (engine->imageProvider(imageProviderName))
1462+ engine->removeImageProvider(imageProviderName);
1463+
1464+ engine->addImageProvider(imageProviderName, new LOPartsImageProvider(m_document));
1465+
1466+}
1467+
1468+QHash<int, QByteArray> LOPartsModel::roleNames() const
1469+{
1470+ QHash<int, QByteArray> roles;
1471+ roles[IndexRole] = "index";
1472+ roles[NameRole] = "name";
1473+
1474+ return roles;
1475+}
1476+
1477+int LOPartsModel::rowCount(const QModelIndex & parent) const
1478+{
1479+ Q_UNUSED(parent)
1480+ return m_entries.count();
1481+}
1482+
1483+QVariant LOPartsModel::data(const QModelIndex & index, int role) const
1484+{
1485+ if (index.row() < 0 || index.row() > m_entries.count())
1486+ return QVariant();
1487+
1488+ const LOPartEntry &part = m_entries.at(index.row());
1489+
1490+ switch (role) {
1491+ case IndexRole:
1492+ return part.index;
1493+ case NameRole:
1494+ return part.name;
1495+
1496+ default:
1497+ return 0;
1498+ }
1499+}
1500+
1501+QVariantMap LOPartsModel::get(int index) const
1502+{
1503+ if (index < 0 || index > m_entries.count() - 1) {
1504+ qWarning() << Q_FUNC_INFO << "Index not valid, return undefined";
1505+ return QVariantMap();
1506+ }
1507+
1508+ const LOPartEntry &part = m_entries.at(index);
1509+
1510+ QVariantMap map;
1511+ map["name"] = part.name;
1512+ map["index"] = part.index;
1513+
1514+ return map;
1515+}
1516+
1517+void LOPartsModel::fillModel() {
1518+ if (m_document) {
1519+ if (!m_entries.isEmpty()) {
1520+ beginRemoveRows(QModelIndex(), 0, rowCount());
1521+ m_entries.clear();
1522+ endRemoveRows();
1523+ }
1524+
1525+ int partsCount = m_document->partsCount();
1526+
1527+ for (int i = 0; i < partsCount; i++) {
1528+ LOPartEntry part;
1529+ part.index = i;
1530+ part.name = m_document->getPartName(i);
1531+
1532+ beginRemoveRows(QModelIndex(), rowCount(), rowCount());
1533+ m_entries.append(part);
1534+ endRemoveRows();
1535+ }
1536+
1537+ Q_EMIT countChanged();
1538+ }
1539+}
1540+
1541+LOPartsModel::~LOPartsModel()
1542+{
1543+}
1544
1545=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h'
1546--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 1970-01-01 00:00:00 +0000
1547+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2015-10-10 12:15:25 +0000
1548@@ -0,0 +1,70 @@
1549+/*
1550+ * Copyright (C) 2015 Canonical Ltd.
1551+ *
1552+ * This program is free software: you can redistribute it and/or modify it
1553+ * under the terms of the GNU General Public License version 3, as published
1554+ * by the Free Software Foundation.
1555+ *
1556+ * This program is distributed in the hope that it will be useful, but
1557+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1558+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1559+ * PURPOSE. See the GNU General Public License for more details.
1560+ *
1561+ * You should have received a copy of the GNU General Public License along
1562+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1563+ *
1564+ */
1565+
1566+#ifndef LOPARTSMODEL_H
1567+#define LOPARTSMODEL_H
1568+
1569+#include <QAbstractListModel>
1570+
1571+class LODocument;
1572+
1573+class LOPartEntry
1574+{
1575+public:
1576+ QString name;
1577+ int index = 0;
1578+};
1579+
1580+class LOPartsModel : public QAbstractListModel
1581+{
1582+ Q_OBJECT
1583+ Q_DISABLE_COPY(LOPartsModel)
1584+ Q_PROPERTY(LODocument* document READ document WRITE setDocument NOTIFY documentChanged)
1585+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
1586+
1587+public:
1588+ enum Roles {
1589+ NameRole,
1590+ IndexRole
1591+ };
1592+
1593+ explicit LOPartsModel(QAbstractListModel *parent = 0);
1594+ ~LOPartsModel();
1595+
1596+ LODocument* document() { return m_document; }
1597+ void setDocument(LODocument* document);
1598+
1599+ QHash<int, QByteArray> roleNames() const;
1600+
1601+ int rowCount(const QModelIndex & parent = QModelIndex()) const;
1602+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
1603+
1604+ Q_INVOKABLE QVariantMap get(int index) const;
1605+
1606+Q_SIGNALS:
1607+ void documentChanged();
1608+ void countChanged();
1609+
1610+private slots:
1611+ void fillModel();
1612+
1613+private:
1614+ LODocument* m_document;
1615+ QList<LOPartEntry> m_entries;
1616+};
1617+
1618+#endif // LOPARTSMODEL_H
1619
1620=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
1621--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-09-19 13:31:19 +0000
1622+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-10-10 12:15:25 +0000
1623@@ -25,6 +25,13 @@
1624 #include <QTimer>
1625 #include <QtCore/qmath.h>
1626
1627+static qreal zoomValueToFitWidth;
1628+
1629+static qreal getZoomToFitWidth(const qreal &width, int documentWidth)
1630+{
1631+ return qreal(width / Twips::convertTwipsToPixels(documentWidth, 1.0));
1632+}
1633+
1634 LOView::LOView(QQuickItem *parent)
1635 : QQuickItem(parent)
1636 , m_parentFlickable(nullptr)
1637@@ -72,8 +79,14 @@
1638
1639 void LOView::initializeDocument(const QString &path)
1640 {
1641+ if (m_document.data())
1642+ m_document.data()->disconnect(this);
1643+
1644 m_document = QSharedPointer<LODocument>(new LODocument());
1645 m_document->setPath(path);
1646+
1647+ connect(m_document.data(), SIGNAL(currentPartChanged()), this, SLOT(invalidateAllTiles()));
1648+
1649 Q_EMIT documentChanged();
1650 }
1651
1652@@ -83,22 +96,38 @@
1653 return m_document.data();
1654 }
1655
1656-// Not used yet.
1657 qreal LOView::zoomFactor() const
1658 {
1659 return m_zoomFactor;
1660 }
1661
1662-// Not used yet.
1663-void LOView::setZoomFactor(qreal zoom)
1664+void LOView::setZoomFactor(const qreal zoom)
1665 {
1666 if (m_zoomFactor == zoom)
1667 return;
1668
1669 m_zoomFactor = zoom;
1670+
1671+ if (m_zoomFactor != zoomValueToFitWidth)
1672+ setZoomMode(LOView::Manual);
1673+
1674 Q_EMIT zoomFactorChanged();
1675 }
1676
1677+LOView::ZoomMode LOView::zoomMode() const
1678+{
1679+ return m_zoomMode;
1680+}
1681+
1682+void LOView::setZoomMode(const ZoomMode zoomMode)
1683+{
1684+ if (m_zoomMode == zoomMode)
1685+ return;
1686+
1687+ m_zoomMode = zoomMode;
1688+ Q_EMIT zoomModeChanged();
1689+}
1690+
1691 int LOView::cacheBuffer() const
1692 {
1693 return m_cacheBuffer;
1694@@ -113,6 +142,37 @@
1695 Q_EMIT cacheBufferChanged();
1696 }
1697
1698+void LOView::adjustZoomToWidth()
1699+ {
1700+ setZoomMode(LOView::FitToWidth);
1701+
1702+ zoomValueToFitWidth = getZoomToFitWidth(m_parentFlickable->width(),
1703+ m_document->documentSize().width());
1704+
1705+ setZoomFactor(zoomValueToFitWidth);
1706+ qDebug() << "Adjust zoom to width - value:" << zoomValueToFitWidth;
1707+ }
1708+
1709+bool LOView::updateZoomIfAutomatic()
1710+{
1711+ // This function is only used in LOView::updateVisibleRect()
1712+ // It returns a bool, so that we can stop the execution of that function,
1713+ // which will be triggered again when we'll automatically update the zoom value.
1714+ if (m_zoomMode == LOView::FitToWidth) {
1715+ zoomValueToFitWidth = getZoomToFitWidth(m_parentFlickable->width(),
1716+ m_document->documentSize().width());
1717+
1718+ if (m_zoomFactor != zoomValueToFitWidth) {
1719+ setZoomFactor(zoomValueToFitWidth);
1720+
1721+ qDebug() << "Adjust automatic zoom to width - value:" << zoomValueToFitWidth;
1722+ return true;
1723+ }
1724+ }
1725+
1726+ return false;
1727+}
1728+
1729 // Update the size of LOView, according to the size of the loaded document.
1730 void LOView::updateViewSize()
1731 {
1732@@ -121,9 +181,8 @@
1733
1734 QSize docSize = m_document->documentSize();
1735
1736- // FIXME: Area may become too large, resulting in a black texture.
1737- this->setWidth(Twips::convertTwipsToPixels(docSize.width()) * m_zoomFactor);
1738- this->setHeight(Twips::convertTwipsToPixels(docSize.height()) * m_zoomFactor);
1739+ this->setWidth(Twips::convertTwipsToPixels(docSize.width(), m_zoomFactor));
1740+ this->setHeight(Twips::convertTwipsToPixels(docSize.height(), m_zoomFactor));
1741
1742 // TODO: Consider to use connections to widthChanged and heightChanged
1743 this->updateVisibleRect();
1744@@ -137,6 +196,31 @@
1745 if (!m_parentFlickable)
1746 return;
1747
1748+ // Changes in parentFlickable width/height trigger directly LOView::updateVisibleRect(),
1749+ // since they don't imply a change in the zoom factor - i.e. LOView::updateViewSize().
1750+ // Anyway, this class also handle an automatic zoom when the parentFlickable has been
1751+ // resized, so we need to take care of it.
1752+ // updateZoomIfAutomatic() returns a bool, which is true when the zoomFactor is
1753+ // set to a new value.
1754+ // If that happens, stop the execution of this function, since the change of
1755+ // zoomFactor will trigger the updateViewSize() function, which triggers this
1756+ // function again.
1757+ if (this->updateZoomIfAutomatic())
1758+ return;
1759+
1760+ // Check if current tiles have a different zoom value
1761+ if (!m_tiles.isEmpty()) {
1762+ SGTileItem* tile = m_tiles.first();
1763+
1764+ if (tile->zoomFactor() != m_zoomFactor) {
1765+ clearView();
1766+
1767+#ifdef DEBUG_VERBOSE
1768+ qDebug() << "Zoom value of tiles is different than the current zoom value. Erasing cache...";
1769+#endif
1770+ }
1771+ }
1772+
1773 // Update information about the visible area
1774 m_visibleArea.setRect(m_parentFlickable->property("contentX").toInt(),
1775 m_parentFlickable->property("contentY").toInt(),
1776@@ -216,6 +300,13 @@
1777 }
1778 }
1779
1780+// FIXME: Just for the moment. In zoom branch we have all we need :)
1781+void LOView::invalidateAllTiles()
1782+{
1783+ clearView();
1784+ updateViewSize();
1785+}
1786+
1787 void LOView::createTile(int index, QRect rect)
1788 {
1789 if (!m_tiles.contains(index)) {
1790@@ -223,13 +314,13 @@
1791 qDebug() << "Creating tile indexed as" << index;
1792 #endif
1793
1794- auto tile = new SGTileItem(rect, this);
1795+ auto tile = new SGTileItem(rect, m_zoomFactor, this);
1796 m_tiles.insert(index, tile);
1797- RenderEngine::instance()->enqueueTask(m_document, rect, tile->id());
1798+ RenderEngine::instance()->enqueueTask(m_document, rect, m_zoomFactor, tile->id());
1799 }
1800 #ifdef DEBUG_VERBOSE
1801 else {
1802- qDebug() << "tile" << x << "x" << y << "already exists";
1803+ qDebug() << "tile" << index << "already exists";
1804 }
1805 #endif
1806 }
1807@@ -251,6 +342,14 @@
1808 }
1809 }
1810
1811+void LOView::clearView()
1812+{
1813+ for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i)
1814+ RenderEngine::instance()->dequeueTask(i.value()->id());
1815+
1816+ m_tiles.clear();
1817+}
1818+
1819 LOView::~LOView()
1820 {
1821 disconnect(RenderEngine::instance(), SIGNAL(renderFinished(int,QImage)), this, SLOT(renderResultReceived(int,QImage)));
1822
1823=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
1824--- src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-09-19 14:00:41 +0000
1825+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-10-10 12:15:25 +0000
1826@@ -30,17 +30,22 @@
1827 class LOView : public QQuickItem
1828 {
1829 Q_OBJECT
1830+ Q_ENUMS(ZoomMode)
1831 Q_PROPERTY(QQuickItem* parentFlickable READ parentFlickable WRITE setParentFlickable NOTIFY parentFlickableChanged)
1832 Q_PROPERTY(LODocument* document READ document /*WRITE setDocument*/ NOTIFY documentChanged)
1833-
1834- // TODO: Implement zoom!
1835 Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
1836+ Q_PROPERTY(ZoomMode zoomMode READ zoomMode NOTIFY zoomModeChanged)
1837 Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
1838
1839 public:
1840 LOView(QQuickItem *parent = 0);
1841 ~LOView();
1842
1843+ enum ZoomMode {
1844+ FitToWidth,
1845+ Manual
1846+ };
1847+
1848 QQuickItem* parentFlickable() const;
1849 void setParentFlickable(QQuickItem* flickable);
1850
1851@@ -49,28 +54,36 @@
1852 LODocument* document() const;
1853
1854 qreal zoomFactor() const;
1855- void setZoomFactor(qreal zoom);
1856+ void setZoomFactor(const qreal zoom);
1857+
1858+ ZoomMode zoomMode() const;
1859
1860 int cacheBuffer() const;
1861 void setCacheBuffer(int cacheBuffer);
1862
1863+ Q_INVOKABLE void adjustZoomToWidth();
1864+
1865 Q_SIGNALS:
1866 void parentFlickableChanged();
1867 void documentChanged();
1868 void zoomFactorChanged();
1869+ void zoomModeChanged();
1870 void cacheBufferChanged();
1871
1872 private Q_SLOTS:
1873 void updateViewSize();
1874 void updateVisibleRect();
1875 void scheduleVisibleRectUpdate();
1876+ void invalidateAllTiles();
1877 void renderResultReceived(int id, QImage img);
1878
1879 private:
1880+
1881 QQuickItem* m_parentFlickable;
1882 QSharedPointer<LODocument> m_document;
1883
1884 qreal m_zoomFactor;
1885+ ZoomMode m_zoomMode;
1886 int m_cacheBuffer;
1887
1888 QRect m_visibleArea;
1889@@ -82,6 +95,9 @@
1890
1891 void generateTiles(int x1, int y1, int x2, int y2, int tilesPerWidth);
1892 void createTile(int index, QRect rect);
1893+ void setZoomMode(const ZoomMode zoomMode);
1894+ bool updateZoomIfAutomatic();
1895+ void clearView();
1896 };
1897
1898 #endif // LOVIEW_H
1899
1900=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp'
1901--- src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp 2015-07-04 16:00:33 +0000
1902+++ src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp 2015-10-10 12:15:25 +0000
1903@@ -21,6 +21,7 @@
1904 #include "plugin.h"
1905 #include "lodocument.h"
1906 #include "loview.h"
1907+#include "lopartsmodel.h"
1908
1909 void LOPlugin::registerTypes(const char *uri)
1910 {
1911@@ -29,6 +30,7 @@
1912 //@uri DocumentViewer.LibreOffice
1913 qmlRegisterType<LODocument>(uri, 1, 0, "Document");
1914 qmlRegisterType<LOView>(uri, 1, 0, "View");
1915+ qmlRegisterType<LOPartsModel>(uri, 1, 0, "PartsModel");
1916 }
1917
1918 void LOPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
1919
1920=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml'
1921--- src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml 2015-09-18 11:18:17 +0000
1922+++ src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml 2015-10-10 12:15:25 +0000
1923@@ -24,18 +24,28 @@
1924 property alias zoomFactor: view.zoomFactor
1925 property alias cacheBuffer: view.cacheBuffer
1926
1927+ property alias zoomMode: view.zoomMode
1928 property string documentPath: ""
1929
1930+ function adjustZoomToWidth()
1931+ {
1932+ view.adjustZoomToWidth();
1933+ }
1934+
1935 onDocumentPathChanged: {
1936 if (documentPath)
1937 view.initializeDocument(documentPath)
1938 }
1939
1940- contentHeight: view.height * view.zoomFactor
1941- contentWidth: view.width * view.zoomFactor
1942+ // zoomFactor is not used here to set contentSize, since it's all managed
1943+ // internally, in the LibreOffice.View component.
1944+ contentHeight: view.height
1945+ contentWidth: view.width
1946
1947 boundsBehavior: Flickable.StopAtBounds
1948
1949+ Component.onCompleted: adjustZoomToWidth()
1950+
1951 LibreOffice.View {
1952 id: view
1953
1954
1955=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp'
1956--- src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp 2015-09-18 13:00:43 +0000
1957+++ src/plugin/libreofficetoolkit-qml-plugin/renderengine.cpp 2015-10-10 12:15:25 +0000
1958@@ -12,11 +12,11 @@
1959 m_idealThreadCount = itc == -1 ? DefaultIdealThreadCount : itc;
1960 }
1961
1962-void RenderEngine::enqueueTask(const QSharedPointer<LODocument>& doc, const QRect& area, int id)
1963+void RenderEngine::enqueueTask(const QSharedPointer<LODocument>& doc, const QRect& area, const qreal &zoom, int id)
1964 {
1965 Q_ASSERT(doc != nullptr);
1966
1967- m_queue.enqueue(EngineTask(doc, area, id));
1968+ m_queue.enqueue(EngineTask(doc, area, zoom, id));
1969
1970 doNextTask();
1971 }
1972@@ -50,7 +50,7 @@
1973 auto task = m_queue.dequeue();
1974
1975 QtConcurrent::run( [=] {
1976- QImage img = task.document->paintTile(task.area.size(), task.area);
1977+ QImage img = task.document->paintTile(task.area.size(), task.area, task.zoom);
1978 QMetaObject::invokeMethod(this, "internalRenderCallback", Q_ARG(int, task.id), Q_ARG(QImage, img));
1979 });
1980 }
1981
1982=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/renderengine.h'
1983--- src/plugin/libreofficetoolkit-qml-plugin/renderengine.h 2015-09-18 13:00:43 +0000
1984+++ src/plugin/libreofficetoolkit-qml-plugin/renderengine.h 2015-10-10 12:15:25 +0000
1985@@ -13,12 +13,14 @@
1986 {
1987 int id;
1988 QRect area;
1989+ qreal zoom;
1990 QSharedPointer<LODocument> document;
1991
1992 public:
1993- EngineTask(const QSharedPointer<LODocument>& d, const QRect& a, int i):
1994+ EngineTask(const QSharedPointer<LODocument>& d, const QRect& a, const qreal& z, int i):
1995 id(i),
1996 area(a),
1997+ zoom(z),
1998 document(d)
1999 { }
2000 };
2001@@ -34,7 +36,7 @@
2002 const int DefaultIdealThreadCount = 2;
2003
2004 public:
2005- void enqueueTask(const QSharedPointer<LODocument>& doc, const QRect& area, int id);
2006+ void enqueueTask(const QSharedPointer<LODocument>& doc, const QRect& area, const qreal& zoom, int id);
2007 void dequeueTask(int id);
2008
2009 static RenderEngine* instance() {
2010
2011=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp'
2012--- src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp 2015-09-19 13:31:19 +0000
2013+++ src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp 2015-10-10 12:15:25 +0000
2014@@ -10,9 +10,10 @@
2015
2016 int SGTileItem::s_idCounter = 0xDEAD0000;
2017
2018-SGTileItem::SGTileItem(const QRect& area, QQuickItem *parent)
2019+SGTileItem::SGTileItem(const QRect& area, const qreal &zoom, QQuickItem *parent)
2020 : QQuickItem(parent)
2021 , m_area(area)
2022+ , m_zoomFactor(zoom)
2023 , m_id (s_idCounter++)
2024 {
2025 setFlag(ItemHasContents, true);
2026
2027=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h'
2028--- src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h 2015-09-18 12:02:42 +0000
2029+++ src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h 2015-10-10 12:15:25 +0000
2030@@ -14,12 +14,15 @@
2031 {
2032 Q_OBJECT
2033 public:
2034- SGTileItem(const QRect& area, QQuickItem *parent = 0);
2035+ SGTileItem(const QRect& area, const qreal &zoom = 1.0, QQuickItem *parent = 0);
2036 ~SGTileItem();
2037
2038 inline const QRect& area() { return m_area; }
2039 inline void setArea(const QRect& rect) { m_area = rect; }
2040
2041+ inline const qreal& zoomFactor() const { return m_zoomFactor; }
2042+ inline void setZoomFactor(const qreal &zoom) { m_zoomFactor = zoom; }
2043+
2044 inline int id() { return m_id; }
2045 inline void setId(int id) { m_id = id; }
2046
2047@@ -37,6 +40,7 @@
2048
2049 private:
2050 QRect m_area;
2051+ qreal m_zoomFactor;
2052 QImage m_data;
2053 int m_id;
2054

Subscribers

People subscribed via source and target branches