Merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/uitk13-lok-page into lp:ubuntu-docviewer-app
- uitk13-lok-page
- Merge into lo-viewer
Status: | Merged |
---|---|
Approved by: | Roman Shchekin |
Approved revision: | 321 |
Merged at revision: | 326 |
Proposed branch: | lp:~verzegnassi-stefano/ubuntu-docviewer-app/uitk13-lok-page |
Merge into: | lp:ubuntu-docviewer-app |
Diff against target: |
548 lines (+207/-204) 4 files modified
src/app/qml/common/ViewerPage.qml (+32/-3) src/app/qml/loView/KeybHelper.js (+23/-47) src/app/qml/loView/LOViewDefaultHeader.qml (+41/-55) src/app/qml/loView/LOViewPage.qml (+111/-99) |
To merge this branch: | bzr merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/uitk13-lok-page |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jenkins Bot | continuous-integration | Approve | |
Roman Shchekin | Needs Information | ||
Review via email: mp+290048@code.launchpad.net |
Commit message
* WORKAROUND: make the lok-viewer header static (avoid unpredictable binding)
* Use new PageHeader and ScrollView components
* UI: Show an empty header when loading LibreOffice
Description of the change
* WORKAROUND: make the lok-viewer header static (avoid unpredictable binding)
* Use new PageHeader and ScrollView components
* UI: Show an empty header when loading LibreOffice
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
Roman Shchekin (mrqtros) wrote : | # |
See inline comments!
Stefano Verzegnassi (verzegnassi-stefano) wrote : | # |
> Haha, are you enjoyed deleting this code? ;)
Ahah, you can be sure of it! :)
> Why did you switch it [PageHeader.
I was having trouble in setting the anchors for the content of the ViewerPage[1], and the LibreOffice Viewer had strange bindings that were causing a continuous flickering and reloading of the document content, every time the header was changing its status (i.e. visible/hidden).
I spent some time on it again (after you review), and now it seems to behave correctly. Pushing the new commit...
[1] We load LOViewPage asynchronously, but the loading logic is placed in a different file.
- 321. By Stefano Verzegnassi
-
Fixed flickable
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:321
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'src/app/qml/common/ViewerPage.qml' |
2 | --- src/app/qml/common/ViewerPage.qml 2015-11-30 12:12:10 +0000 |
3 | +++ src/app/qml/common/ViewerPage.qml 2016-03-30 11:10:56 +0000 |
4 | @@ -1,5 +1,5 @@ |
5 | /* |
6 | - * Copyright (C) 2015 Stefano Verzegnassi <verzegnassi.stefano@gmail.com> |
7 | + * Copyright (C) 2015, 2016 Stefano Verzegnassi <verzegnassi.stefano@gmail.com> |
8 | * |
9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by |
11 | @@ -35,7 +35,21 @@ |
12 | |
13 | Loader { |
14 | id: contentLoader |
15 | - anchors.fill: parent |
16 | + anchors { |
17 | + left: parent.left |
18 | + right: parent.right |
19 | + bottom: parent.bottom |
20 | + |
21 | + top: { |
22 | + if (!viewerPage.header) |
23 | + return parent.top |
24 | + |
25 | + if (!viewerPage.header.flickable) |
26 | + return viewerPage.header.bottom |
27 | + else |
28 | + return parent.top |
29 | + } |
30 | + } |
31 | |
32 | asynchronous: true |
33 | sourceComponent: viewerPage.contents |
34 | @@ -45,7 +59,22 @@ |
35 | |
36 | Item { |
37 | id: splashScreenItem |
38 | - anchors.fill: parent |
39 | + |
40 | + anchors { |
41 | + left: parent.left |
42 | + right: parent.right |
43 | + bottom: parent.bottom |
44 | + |
45 | + top: { |
46 | + if (!viewerPage.header) |
47 | + return parent.top |
48 | + |
49 | + if (!viewerPage.header.flickable) |
50 | + return viewerPage.header.bottom |
51 | + else |
52 | + return parent.top |
53 | + } |
54 | + } |
55 | |
56 | visible: contentLoader.status != Loader.Ready |
57 | enabled: visible |
58 | |
59 | === modified file 'src/app/qml/loView/KeybHelper.js' |
60 | --- src/app/qml/loView/KeybHelper.js 2015-12-14 00:40:55 +0000 |
61 | +++ src/app/qml/loView/KeybHelper.js 2016-03-30 11:10:56 +0000 |
62 | @@ -1,5 +1,5 @@ |
63 | /* |
64 | - * Copyright (C) 2015 Stefano Verzegnassi |
65 | + * Copyright (C) 2015, 2016 Stefano Verzegnassi |
66 | * |
67 | * This program is free software; you can redistribute it and/or modify |
68 | * it under the terms of the GNU General Public License as published by |
69 | @@ -14,83 +14,59 @@ |
70 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
71 | */ |
72 | |
73 | +// Here we handle all the key events that are not |
74 | +// recognised by UITK ScrollView |
75 | + |
76 | function parseEvent(event) { |
77 | - var pixelDiff = 5; |
78 | - |
79 | var view = loPage.contentItem.loView |
80 | var isPresentation = view.document.documentType === LibreOffice.Document.PresentationDocument |
81 | |
82 | if (event.key == Qt.Key_PageUp) { |
83 | - if (isPresentation) |
84 | + if (isPresentation) { |
85 | view.currentPart -= 1 |
86 | - else |
87 | - view.moveView("vertical", -view.height) |
88 | - |
89 | + event.accepted = true |
90 | + } |
91 | return; |
92 | } |
93 | |
94 | if (event.key == Qt.Key_PageDown) { |
95 | - if (isPresentation) |
96 | + if (isPresentation) { |
97 | view.currentPart += 1 |
98 | - else |
99 | - view.moveView("vertical", view.height) |
100 | - |
101 | + event.accepted = true |
102 | + } |
103 | return; |
104 | } |
105 | |
106 | if (event.key == Qt.Key_Home) { |
107 | - if (event.modifiers & Qt.ControlModifier) { |
108 | - view.contentX = 0 |
109 | - view.contentY = 0 |
110 | + if (event.modifiers & Qt.ControlModifier) |
111 | view.currentPart = 0 |
112 | - } else { |
113 | - view.contentX = 0 |
114 | - view.contentY = 0 |
115 | - } |
116 | + |
117 | + event.accepted = false |
118 | + return |
119 | } |
120 | |
121 | if (event.key == Qt.Key_End) { |
122 | - if (event.modifiers & Qt.ControlModifier) { |
123 | - view.contentX = view.contentWidth - view.width |
124 | - view.contentY = view.contentHeight - view.height |
125 | - console.log(view.currentPart, view.document.partsCount - 1) |
126 | + if (event.modifiers & Qt.ControlModifier) |
127 | view.currentPart = view.document.partsCount - 1 |
128 | - } else { |
129 | - view.contentX = view.contentWidth - view.width |
130 | - view.contentY = view.contentHeight - view.height |
131 | - } |
132 | - } |
133 | |
134 | - if (event.key == Qt.Key_Up) { |
135 | - view.moveView("vertical", -pixelDiff) |
136 | - return; |
137 | - } |
138 | - |
139 | - if (event.key == Qt.Key_Down) { |
140 | - view.moveView("vertical", pixelDiff) |
141 | - return; |
142 | - } |
143 | - |
144 | - if (event.key == Qt.Key_Left) { |
145 | - view.moveView("horizontal", -pixelDiff) |
146 | - return; |
147 | - } |
148 | - |
149 | - if (event.key == Qt.Key_Right) { |
150 | - view.moveView("horizontal", pixelDiff) |
151 | - return; |
152 | + event.accepted = false |
153 | + return |
154 | } |
155 | |
156 | if (event.key == Qt.Key_Plus) { |
157 | if (event.modifiers & Qt.ControlModifier) { |
158 | - view.zoomFactor = Math.max(4.0, view.zoomFactor + 0.25) |
159 | + view.setZoom(Math.min(view.zoomSettings.maximumZoom, view.zoomSettings.zoomFactor + 0.25)) |
160 | } |
161 | + |
162 | + return |
163 | } |
164 | |
165 | if (event.key == Qt.Key_Minus) { |
166 | if (event.modifiers & Qt.ControlModifier) { |
167 | - view.zoomFactor = Math.min(0.5, view.zoomFactor - 0.25) |
168 | + view.setZoom(Math.max(view.zoomSettings.minimumZoom, view.zoomSettings.zoomFactor - 0.25)) |
169 | } |
170 | + |
171 | + return |
172 | } |
173 | |
174 | |
175 | |
176 | === modified file 'src/app/qml/loView/LOViewDefaultHeader.qml' |
177 | --- src/app/qml/loView/LOViewDefaultHeader.qml 2015-11-30 12:12:10 +0000 |
178 | +++ src/app/qml/loView/LOViewDefaultHeader.qml 2016-03-30 11:10:56 +0000 |
179 | @@ -1,5 +1,5 @@ |
180 | /* |
181 | - * Copyright (C) 2014-2015 Canonical, Ltd. |
182 | + * Copyright (C) 2014-2016 Canonical, Ltd. |
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 | @@ -16,68 +16,55 @@ |
187 | |
188 | import QtQuick 2.4 |
189 | import Ubuntu.Components 1.3 |
190 | -import QtQuick.Layouts 1.1 |
191 | import Ubuntu.Components.Popups 1.3 |
192 | import DocumentViewer.LibreOffice 1.0 as LibreOffice |
193 | import DocumentViewer 1.0 |
194 | |
195 | -PageHeadState { |
196 | - id: rootItem |
197 | - |
198 | - property Page targetPage |
199 | - head: targetPage.head |
200 | - |
201 | - contents: RowLayout { |
202 | - anchors.fill: parent |
203 | - anchors.rightMargin: units.gu(2) |
204 | - spacing: units.gu(1) |
205 | - |
206 | - Column { |
207 | - id: layout |
208 | - Layout.fillWidth: true |
209 | - |
210 | - Label { |
211 | - anchors { left: parent.left; right: parent.right } |
212 | - elide: Text.ElideMiddle |
213 | - font.weight: Font.DemiBold |
214 | - text: targetPage.title |
215 | - } |
216 | - Label { |
217 | - anchors { left: parent.left; right: parent.right } |
218 | - elide: Text.ElideMiddle |
219 | - textSize: Label.Small |
220 | - text: { |
221 | - if (!targetPage.contentItem) |
222 | - return i18n.tr("Loading...") |
223 | - |
224 | - switch(targetPage.contentItem.loDocument.documentType) { |
225 | - case 0: |
226 | - return i18n.tr("LibreOffice text document") |
227 | - case 1: |
228 | - return i18n.tr("LibreOffice spread sheet") |
229 | - case 2: |
230 | - return i18n.tr("LibreOffice presentation") |
231 | - case 3: |
232 | - return i18n.tr("LibreOffice Draw document") |
233 | - case 4: |
234 | - return i18n.tr("Unknown LibreOffice document") |
235 | - default: |
236 | - return i18n.tr("Unknown type document") |
237 | - } |
238 | +PageHeader { |
239 | + id: defaultHeader |
240 | + |
241 | + property var targetPage |
242 | + |
243 | + contents: ListItemLayout { |
244 | + anchors.centerIn: parent |
245 | + |
246 | + title { |
247 | + elide: Text.ElideMiddle |
248 | + font.weight: Font.DemiBold |
249 | + text: defaultHeader.title |
250 | + } |
251 | + |
252 | + subtitle { |
253 | + textSize: Label.Small |
254 | + text: { |
255 | + if (!targetPage.contentItem) |
256 | + return i18n.tr("Loading...") |
257 | + |
258 | + switch(targetPage.contentItem.loDocument.documentType) { |
259 | + case LibreOffice.Document.TextDocument: |
260 | + return i18n.tr("LibreOffice text document") |
261 | + case LibreOffice.Document.SpreadsheetDocument: |
262 | + return i18n.tr("LibreOffice spread sheet") |
263 | + case LibreOffice.Document.PresentationDocument: |
264 | + return i18n.tr("LibreOffice presentation") |
265 | + case LibreOffice.Document.DrawingDocument: |
266 | + return i18n.tr("LibreOffice Draw document") |
267 | + case LibreOffice.Document.OtherDocument: |
268 | + return i18n.tr("Unknown LibreOffice document") |
269 | + default: |
270 | + return i18n.tr("Unknown type document") |
271 | } |
272 | } |
273 | } |
274 | |
275 | ZoomSelector { |
276 | - Layout.preferredWidth: units.gu(12) |
277 | - Layout.preferredHeight: units.gu(4) |
278 | - |
279 | + SlotsLayout.position: SlotsLayout.Trailing |
280 | view: targetPage.contentItem.loView |
281 | visible: targetPage.contentItem && (DocumentViewer.desktopMode || mainView.wideWindow) |
282 | } |
283 | } |
284 | |
285 | - actions: [ |
286 | + trailingActionBar.actions: [ |
287 | Action { |
288 | // FIXME: Autopilot test broken... seems not to detect we're now using an ActionBar since the switch to UITK 1.3 |
289 | objectName: "gotopage" |
290 | @@ -86,12 +73,11 @@ |
291 | visible: targetPage.contentItem.loDocument.documentType == LibreOffice.Document.TextDocument |
292 | |
293 | onTriggered: { |
294 | - PopupUtils.open( |
295 | - Qt.resolvedUrl("LOViewGotoDialog.qml"), |
296 | - targetPage, |
297 | - { |
298 | - view: targetPage.contentItem.loView |
299 | - }) |
300 | + var popupSettings = { |
301 | + view: targetPage.contentItem.loView |
302 | + } |
303 | + |
304 | + PopupUtils.open(Qt.resolvedUrl("LOViewGotoDialog.qml"), targetPage, popupSettings) |
305 | } |
306 | }, |
307 | |
308 | |
309 | === modified file 'src/app/qml/loView/LOViewPage.qml' |
310 | --- src/app/qml/loView/LOViewPage.qml 2016-02-03 21:35:53 +0000 |
311 | +++ src/app/qml/loView/LOViewPage.qml 2016-03-30 11:10:56 +0000 |
312 | @@ -1,5 +1,5 @@ |
313 | /* |
314 | - * Copyright (C) 2013-2015 Canonical, Ltd. |
315 | + * Copyright (C) 2013-2016 Canonical, Ltd. |
316 | * |
317 | * This program is free software; you can redistribute it and/or modify |
318 | * it under the terms of the GNU General Public License as published by |
319 | @@ -32,9 +32,7 @@ |
320 | property bool isTextDocument: loPage.contentItem && (loPage.contentItem.loDocument.documentType === LibreOffice.Document.TextDocument) |
321 | property bool isSpreadsheet: loPage.contentItem && (loPage.contentItem.loDocument.documentType === LibreOffice.Document.SpreadsheetDocument) |
322 | |
323 | - title: DocumentViewer.getFileBaseNameFromPath(file.path); |
324 | - flickable: isTextDocument ? loPage.contentItem.loView : null |
325 | - |
326 | + header: defaultHeader |
327 | splashScreen: Splashscreen { } |
328 | |
329 | content: FocusScope { |
330 | @@ -137,96 +135,102 @@ |
331 | color: "#f5f5f5" |
332 | } |
333 | |
334 | - LibreOffice.Viewer { |
335 | - id: loView |
336 | - objectName: "loView" |
337 | + ScrollView { |
338 | anchors.fill: parent |
339 | |
340 | - documentPath: file.path |
341 | - |
342 | - function updateContentSize(tgtScale) { |
343 | - zoomSettings.zoomFactor = tgtScale |
344 | - } |
345 | - |
346 | - // Keyboard events |
347 | - focus: true |
348 | - Keys.onPressed: KeybHelper.parseEvent(event) |
349 | - |
350 | - Component.onCompleted: { |
351 | - // WORKAROUND: Fix for wrong grid unit size |
352 | - flickDeceleration = 1500 * units.gridUnit / 8 |
353 | - maximumFlickVelocity = 2500 * units.gridUnit / 8 |
354 | - loPageContent.forceActiveFocus() |
355 | - } |
356 | - |
357 | - onErrorChanged: { |
358 | - var errorString; |
359 | - |
360 | - switch(error) { |
361 | - case LibreOffice.Error.LibreOfficeNotFound: |
362 | - errorString = i18n.tr("LibreOffice binaries not found.") |
363 | - break; |
364 | - case LibreOffice.Error.LibreOfficeNotInitialized: |
365 | - errorString = i18n.tr("Error while loading LibreOffice.") |
366 | - break; |
367 | - case LibreOffice.Error.DocumentNotLoaded: |
368 | - errorString = i18n.tr("Document not loaded.\nThe requested document may be corrupt or protected by a password.") |
369 | - break; |
370 | - } |
371 | - |
372 | - if (errorString) { |
373 | - loPage.pageStack.pop() |
374 | - |
375 | - // We create the dialog in the MainView, so that it isn't |
376 | - // initialized by 'loPage' and keep on working after the |
377 | - // page is destroyed. |
378 | - mainView.showErrorDialog(errorString); |
379 | - } |
380 | - } |
381 | - |
382 | - ScalingMouseArea { |
383 | - id: mouseArea |
384 | + // We need to set some custom event handler. |
385 | + // Forward the key events to the Viewer and |
386 | + // fallback to the ScrollView handlers if the |
387 | + // event hasn't been accepted. |
388 | + Keys.forwardTo: loView |
389 | + Keys.priority: Keys.AfterItem |
390 | + |
391 | + LibreOffice.Viewer { |
392 | + id: loView |
393 | + objectName: "loView" |
394 | anchors.fill: parent |
395 | - targetFlickable: loView |
396 | - onTotalScaleChanged: targetFlickable.updateContentSize(totalScale) |
397 | - |
398 | - thresholdZoom: minimumZoom + (maximumZoom - minimumZoom) * 0.75 |
399 | - maximumZoom: { |
400 | - if (DocumentViewer.desktopMode || mainView.wideWindow) |
401 | - return 3.0 |
402 | - |
403 | - return minimumZoom * 3 |
404 | - } |
405 | - minimumZoom: { |
406 | - if (DocumentViewer.desktopMode || mainView.wideWindow) |
407 | - return loView.zoomSettings.minimumZoom |
408 | - |
409 | - switch(loView.document.documentType) { |
410 | - case LibreOffice.Document.TextDocument: |
411 | - return loView.zoomSettings.valueFitToWidthZoom |
412 | - case LibreOffice.Document.PresentationDocument: |
413 | - return loView.zoomSettings.valueAutomaticZoom |
414 | - default: |
415 | - return loView.zoomSettings.minimumZoom |
416 | - } |
417 | - } |
418 | - |
419 | - Binding { |
420 | - target: mouseArea |
421 | - property: "zoomValue" |
422 | - value: loView.zoomSettings.zoomFactor |
423 | - } |
424 | - } |
425 | - |
426 | - Scrollbar { flickableItem: loView; parent: loView.parent } |
427 | - Scrollbar { flickableItem: loView; parent: loView.parent; align: Qt.AlignBottom } |
428 | - |
429 | - Label { |
430 | - anchors.centerIn: parent |
431 | - parent: loPage |
432 | - textSize: Label.Large |
433 | - text: i18n.tr("This sheet has no content.") |
434 | - visible: loPage.isSpreadsheet && loView.contentWidth <= 0 && loView.contentHeight <= 0 |
435 | + |
436 | + documentPath: file.path |
437 | + |
438 | + Keys.onPressed: KeybHelper.parseEvent(event) |
439 | + |
440 | + function updateContentSize(tgtScale) { |
441 | + zoomSettings.zoomFactor = tgtScale |
442 | + } |
443 | + |
444 | + Component.onCompleted: { |
445 | + // WORKAROUND: Fix for wrong grid unit size |
446 | + flickDeceleration = 1500 * units.gridUnit / 8 |
447 | + maximumFlickVelocity = 2500 * units.gridUnit / 8 |
448 | + loPageContent.forceActiveFocus() |
449 | + } |
450 | + |
451 | + onErrorChanged: { |
452 | + var errorString; |
453 | + |
454 | + switch(error) { |
455 | + case LibreOffice.Error.LibreOfficeNotFound: |
456 | + errorString = i18n.tr("LibreOffice binaries not found.") |
457 | + break; |
458 | + case LibreOffice.Error.LibreOfficeNotInitialized: |
459 | + errorString = i18n.tr("Error while loading LibreOffice.") |
460 | + break; |
461 | + case LibreOffice.Error.DocumentNotLoaded: |
462 | + errorString = i18n.tr("Document not loaded.\nThe requested document may be corrupt or protected by a password.") |
463 | + break; |
464 | + } |
465 | + |
466 | + if (errorString) { |
467 | + loPage.pageStack.pop() |
468 | + |
469 | + // We create the dialog in the MainView, so that it isn't |
470 | + // initialized by 'loPage' and keep on working after the |
471 | + // page is destroyed. |
472 | + mainView.showErrorDialog(errorString); |
473 | + } |
474 | + } |
475 | + |
476 | + ScalingMouseArea { |
477 | + id: mouseArea |
478 | + anchors.fill: parent |
479 | + targetFlickable: loView |
480 | + onTotalScaleChanged: targetFlickable.updateContentSize(totalScale) |
481 | + |
482 | + thresholdZoom: minimumZoom + (maximumZoom - minimumZoom) * 0.75 |
483 | + maximumZoom: { |
484 | + if (DocumentViewer.desktopMode || mainView.wideWindow) |
485 | + return 3.0 |
486 | + |
487 | + return minimumZoom * 3 |
488 | + } |
489 | + minimumZoom: { |
490 | + if (DocumentViewer.desktopMode || mainView.wideWindow) |
491 | + return loView.zoomSettings.minimumZoom |
492 | + |
493 | + switch(loView.document.documentType) { |
494 | + case LibreOffice.Document.TextDocument: |
495 | + return loView.zoomSettings.valueFitToWidthZoom |
496 | + case LibreOffice.Document.PresentationDocument: |
497 | + return loView.zoomSettings.valueAutomaticZoom |
498 | + default: |
499 | + return loView.zoomSettings.minimumZoom |
500 | + } |
501 | + } |
502 | + |
503 | + Binding { |
504 | + target: mouseArea |
505 | + property: "zoomValue" |
506 | + value: loView.zoomSettings.zoomFactor |
507 | + } |
508 | + } |
509 | + |
510 | + Label { |
511 | + anchors.centerIn: parent |
512 | + parent: loPage |
513 | + textSize: Label.Large |
514 | + text: i18n.tr("This sheet has no content.") |
515 | + visible: loPage.isSpreadsheet && loView.contentWidth <= 0 && loView.contentHeight <= 0 |
516 | + } |
517 | } |
518 | } |
519 | } |
520 | @@ -265,12 +269,20 @@ |
521 | } |
522 | } |
523 | |
524 | - // *** HEADER *** |
525 | - state: "default" |
526 | - states: [ |
527 | - LOViewDefaultHeader { |
528 | - name: "default" |
529 | - targetPage: loPage |
530 | - } |
531 | - ] |
532 | + |
533 | + /*** Headers ***/ |
534 | + |
535 | + LOViewDefaultHeader { |
536 | + id: defaultHeader |
537 | + visible: loPage.loaded |
538 | + title: DocumentViewer.getFileBaseNameFromPath(file.path); |
539 | + flickable: isTextDocument ? loPage.contentItem.loView : null |
540 | + targetPage: loPage |
541 | + } |
542 | + |
543 | + PageHeader { |
544 | + id: loadingHeader |
545 | + visible: !loPage.loaded |
546 | + // When we're still loading LibreOffice, show an empty header |
547 | + } |
548 | } |
PASSED: Continuous integration, rev:320 /core-apps- jenkins. ubuntu. com/job/ docviewer- app-ci/ 261/ /core-apps- jenkins. ubuntu. com/job/ generic- update- mp/811/ console
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild: /core-apps- jenkins. ubuntu. com/job/ docviewer- app-ci/ 261/rebuild
https:/