Merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-lok-qsg-zoom into lp:ubuntu-docviewer-app
- reboot-lok-qsg-zoom
- Merge into lo-viewer
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 |
Related bugs: |
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 : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
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 |
PASSED: Continuous integration, rev:175 91.189. 93.70:8080/ job/ubuntu- docviewer- app-reboot- ci/39/ 91.189. 93.70:8080/ job/ubuntu- docviewer- app-reboot- vivid-amd64- ci/39
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/ubuntu- docviewer- app-reboot- ci/39/rebuild
http://