Merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-qml-async-imageprovider into lp:ubuntu-docviewer-app

Proposed by Stefano Verzegnassi
Status: Merged
Approved by: Stefano Verzegnassi
Approved revision: 256
Merged at revision: 294
Proposed branch: lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-qml-async-imageprovider
Merge into: lp:ubuntu-docviewer-app
Prerequisite: lp:~ubuntu-docviewer-dev/ubuntu-docviewer-app/ubuntu-docviewer-app-re-fix
Diff against target: 602 lines (+162/-120)
17 files modified
po/com.ubuntu.docviewer.pot (+9/-9)
src/app/qml/loView/PartsView.qml (+4/-4)
src/app/qml/pdfView/PdfPresentation.qml (+1/-1)
src/app/qml/ubuntu-docviewer-app.qml (+2/-2)
src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt (+1/-0)
src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp (+5/-5)
src/plugin/libreofficetoolkit-qml-plugin/lodocument.h (+1/-1)
src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp (+23/-31)
src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h (+8/-12)
src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp (+54/-0)
src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h (+41/-0)
src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp (+0/-20)
src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h (+0/-7)
src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp (+1/-1)
src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h (+3/-3)
src/plugin/libreofficetoolkit-qml-plugin/loview.cpp (+9/-22)
src/plugin/libreofficetoolkit-qml-plugin/loview.h (+0/-2)
To merge this branch: bzr merge lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-qml-async-imageprovider
Reviewer Review Type Date Requested Status
Jenkins Bot continuous-integration Approve
Roman Shchekin Approve
Nicholas Skaggs (community) Needs Fixing
Review via email: mp+282878@code.launchpad.net

Commit message

Use QQuickAsyncImageProvider in LOPartsImageProvider class.
This is backported on Ubuntu/Ubuntu Touch since Qt 5.4.1-1ubuntu7.
On any other distro/OS it works only with Qt 5.6 (or later).

Description of the change

Use QQuickAsyncImageProvider in LOPartsImageProvider class.

This is backported on Ubuntu/Ubuntu Touch since Qt 5.4.1-1ubuntu7.
On any other distro/OS it works only with Qt 5.6 (or later).

To post a comment you must log in.
Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

@Roman, we still have to discuss about the line 398 of the diff... :)

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Roman Shchekin (mrqtros) wrote :

Just remove it and manage memory yourself (in "slotTaskRenderFinished" and "cancel").

Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

By doing so, the app crashes any time a document is loaded.

It does not crash always at the same point, but it may occur at two different points:

1) In the internalRenderCallback, when it calls "doNextTask()", it crashes at line 84 of the renderengine.cpp

    if (m_activeTaskCount && !task->canBeRunInParallel(m_lastTask))
        return;

2) In lopartsimageresponse.cpp, when deleting m_task. (No other info is visible on the debugger)

void LOPartsImageResponse::cancel()
{
    disconnect(RenderEngine::instance(), &RenderEngine::taskRenderFinished,
               this, &LOPartsImageResponse::slotTaskRenderFinished);

    if (m_task) {
        QMetaObject::invokeMethod(RenderEngine::instance(), "dequeueTask",
                                  Qt::QueuedConnection,
                                  Q_ARG(int, m_task->id()));

        delete m_task;
    }
}

With the current code, I really think we should give the ownership of the task to the RenderEngine.

As we discussed earlier, the code I wrote is not so good because the ImageResponse gets the ownership and then it gives that ownership away in a asymmetrical/strange/ugly way.

Supposed that we should try to make RenderEngine work properly with different threads, could we revert to the code I wrote earlier (RenderEngine takes ownership of the tasks, and we connect to it using a BlockingQueueConnection)?
It used to work with no issue when we tried it.

Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

I had a further look at the issue.
It seems that QQuickPixmapCache calls QQuickImageResponse::cancel() several times when the LOK viewer is loaded.

We properly synchronize the threads when we queue/dequeue the task from the engine but, if the task is currently being processed, it gets deleted during its execution.

We need to ensure that the GUI thread (where RenderEngine lives) and the LOImageResponse are in sync when we delete the task.
I guess we'd be better not to give ownership of the task to a class that lives in another thread, and let RenderEngine handles its tasks at its best.

We only need to subscribe to the RenderEngine's signals, using a Qt::BlockingQueuedConnection.

Roman, I remember that the usage of a blocking connection was okay for you before you updated the RenderEngine.
What do you think?

249. By Stefano Verzegnassi

Moved all the RenderEngine code in LOPartsImageResponse to LOPartsImageProvider

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
250. By Stefano Verzegnassi

Merged trunk. Updated translation template.

251. By Stefano Verzegnassi

Restored 'cache:false' so that we don't display a thumbnail from a different document

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
252. By Stefano Verzegnassi

Debugging Jenkins issue with QQuickAsyncImageProvider

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
253. By Stefano Verzegnassi

Merged trunk, updated .pot

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

Still building the project against OTA-4 (May, 2014)...

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

Text conflict in po/com.ubuntu.docviewer.pot
1 conflicts encountered.

Everytime something lands, you get this lovely conflict. Not sure if there's a better way for you to avoid this :-)

review: Needs Fixing
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

In other news, jenkins should build and run this cleanly now.

Revision history for this message
Roman Shchekin (mrqtros) wrote :

So, blockig connection solved all issues?
Just for inromation - you decided do not use render tasks separately from RenderEngine?

Revision history for this message
Stefano Verzegnassi (verzegnassi-stefano) wrote :

- So it seems. We've discussed about it some week ago, and it seems to keep everything in sync since it waits for the ImageResponse to complete its work on the returned image.

- I moved the code that calls the RenderEngine to the image provider. This way it is used from the GUI thread and there is no problem with ownership, etc...

Revision history for this message
Roman Shchekin (mrqtros) wrote :

Ok, let's merge then!

review: Approve
254. By Stefano Verzegnassi

Merged trunk + fixed .pot conflict

255. By Stefano Verzegnassi

Fixed LOK viewer going full-screen with a .odp/.ppt(x) document.
Both PDF full-screen presentation mode and LOK viewer were using a 'isPresentation' property with two different meaning. My fault, sorry! :/

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
256. By Stefano Verzegnassi

Removed Jenkins debug

Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'po/com.ubuntu.docviewer.pot'
--- po/com.ubuntu.docviewer.pot 2016-02-03 13:51:11 +0000
+++ po/com.ubuntu.docviewer.pot 2016-02-05 22:57:36 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: \n"9"Project-Id-Version: \n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2016-02-03 14:48+0100\n"11"POT-Creation-Date: 2016-02-05 23:40+0100\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -216,7 +216,7 @@
216msgstr ""216msgstr ""
217217
218#: ../src/app/qml/documentPage/DocumentPage.qml:23218#: ../src/app/qml/documentPage/DocumentPage.qml:23
219#: /tmp/ubuntu-docviewer-app-build/po/com.ubuntu.docviewer.desktop.in.in.h:3219#: /tmp/lok-qml-async-imageprovider-build/po/com.ubuntu.docviewer.desktop.in.in.h:3
220msgid "Documents"220msgid "Documents"
221msgstr ""221msgstr ""
222222
@@ -367,21 +367,21 @@
367msgid "GO!"367msgid "GO!"
368msgstr ""368msgstr ""
369369
370#: ../src/app/qml/loView/LOViewPage.qml:137370#: ../src/app/qml/loView/LOViewPage.qml:167
371msgid "LibreOffice binaries not found."371msgid "LibreOffice binaries not found."
372msgstr ""372msgstr ""
373373
374#: ../src/app/qml/loView/LOViewPage.qml:140374#: ../src/app/qml/loView/LOViewPage.qml:170
375msgid "Error while loading LibreOffice."375msgid "Error while loading LibreOffice."
376msgstr ""376msgstr ""
377377
378#: ../src/app/qml/loView/LOViewPage.qml:143378#: ../src/app/qml/loView/LOViewPage.qml:173
379msgid ""379msgid ""
380"Document not loaded.\n"380"Document not loaded.\n"
381"The requested document may be corrupt or protected by a password."381"The requested document may be corrupt or protected by a password."
382msgstr ""382msgstr ""
383383
384#: ../src/app/qml/loView/LOViewPage.qml:164384#: ../src/app/qml/loView/LOViewPage.qml:228
385msgid "This sheet has no content."385msgid "This sheet has no content."
386msgstr ""386msgstr ""
387387
@@ -446,7 +446,7 @@
446msgid "Choose a page between 1 and %1"446msgid "Choose a page between 1 and %1"
447msgstr ""447msgstr ""
448448
449#: ../src/app/qml/ubuntu-docviewer-app.qml:118449#: ../src/app/qml/ubuntu-docviewer-app.qml:114
450msgid "File does not exist."450msgid "File does not exist."
451msgstr ""451msgstr ""
452452
@@ -464,10 +464,10 @@
464msgid "copy %1"464msgid "copy %1"
465msgstr ""465msgstr ""
466466
467#: /tmp/ubuntu-docviewer-app-build/po/com.ubuntu.docviewer.desktop.in.in.h:1467#: /tmp/lok-qml-async-imageprovider-build/po/com.ubuntu.docviewer.desktop.in.in.h:1
468msgid "Document Viewer"468msgid "Document Viewer"
469msgstr ""469msgstr ""
470470
471#: /tmp/ubuntu-docviewer-app-build/po/com.ubuntu.docviewer.desktop.in.in.h:2471#: /tmp/lok-qml-async-imageprovider-build/po/com.ubuntu.docviewer.desktop.in.in.h:2
472msgid "documents;viewer;pdf;reader;"472msgid "documents;viewer;pdf;reader;"
473msgstr ""473msgstr ""
474474
=== modified file 'src/app/qml/loView/PartsView.qml'
--- src/app/qml/loView/PartsView.qml 2016-01-17 12:09:58 +0000
+++ src/app/qml/loView/PartsView.qml 2016-02-05 22:57:36 +0000
@@ -103,8 +103,8 @@
103 fillMode: Image.PreserveAspectFit103 fillMode: Image.PreserveAspectFit
104 // Do not store a cache of the thumbnail, so that we don't show104 // Do not store a cache of the thumbnail, so that we don't show
105 // thumbnails of a previously loaded document.105 // thumbnails of a previously loaded document.
106 cache: true // TODO PLAY WITH IT106 cache: false
107 source: model.thumbnail107 source: "image://lok/part/%1".arg(model.index)
108 }108 }
109 }109 }
110110
@@ -172,8 +172,8 @@
172 fillMode: Image.PreserveAspectFit172 fillMode: Image.PreserveAspectFit
173 // Do not store a cache of the thumbnail, so that we don't show173 // Do not store a cache of the thumbnail, so that we don't show
174 // thumbnails of a previously loaded document.174 // thumbnails of a previously loaded document.
175 cache: true // TODO PLAY WITH IT175 cache: false
176 source: model.thumbnail176 source: "image://lok/part/%1".arg(model.index)
177 }177 }
178 }178 }
179179
180180
=== modified file 'src/app/qml/pdfView/PdfPresentation.qml'
--- src/app/qml/pdfView/PdfPresentation.qml 2016-01-23 12:34:25 +0000
+++ src/app/qml/pdfView/PdfPresentation.qml 2016-02-05 22:57:36 +0000
@@ -22,7 +22,7 @@
22Page {22Page {
23 id: pdfPage23 id: pdfPage
24 property var poppler24 property var poppler
25 property bool isPresentation: true25 property bool isPresentationMode: true
26 anchors.fill: parent26 anchors.fill: parent
27 title: DocumentViewer.getFileBaseNameFromPath(poppler.path)27 title: DocumentViewer.getFileBaseNameFromPath(poppler.path)
28 focus: true28 focus: true
2929
=== modified file 'src/app/qml/ubuntu-docviewer-app.qml'
--- src/app/qml/ubuntu-docviewer-app.qml 2016-01-23 12:48:49 +0000
+++ src/app/qml/ubuntu-docviewer-app.qml 2016-02-05 22:57:36 +0000
@@ -34,7 +34,7 @@
34 // force hiding Unity 8 indicators panel.34 // force hiding Unity 8 indicators panel.
35 property bool fullscreen: commandLineProxy.fullscreen ||35 property bool fullscreen: commandLineProxy.fullscreen ||
36 (!desktopMode && isLandscape && narrowWindow) ||36 (!desktopMode && isLandscape && narrowWindow) ||
37 pageStack.currentPage.hasOwnProperty("isPresentation")37 pageStack.currentPage.hasOwnProperty("isPresentationMode")
3838
39 readonly property bool desktopMode: DocumentViewer.desktopMode39 readonly property bool desktopMode: DocumentViewer.desktopMode
4040
@@ -200,5 +200,5 @@
200200
201 property bool nightModeEnabled: false201 property bool nightModeEnabled: false
202 layer.effect: NightModeShader {}202 layer.effect: NightModeShader {}
203 layer.enabled: nightModeEnabled && (pageStack.depth > 1) && !pageStack.currentPage.isPresentation203 layer.enabled: nightModeEnabled && (pageStack.depth > 1) && !pageStack.currentPage.isPresentationMode
204}204}
205205
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2016-01-20 21:48:21 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2016-02-05 22:57:36 +0000
@@ -23,6 +23,7 @@
23 loview.cpp23 loview.cpp
24 sgtileitem.cpp24 sgtileitem.cpp
25 lopartsimageprovider.cpp25 lopartsimageprovider.cpp
26 lopartsimageresponse.cpp
26 lopartsmodel.cpp27 lopartsmodel.cpp
27 lorendertask.cpp28 lorendertask.cpp
28 ucunits.cpp29 ucunits.cpp
2930
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2016-01-25 12:15:43 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2016-02-05 22:57:36 +0000
@@ -170,7 +170,7 @@
170 return result.rgbSwapped();170 return result.rgbSwapped();
171}171}
172172
173QImage LODocument::paintThumbnail(int part, qreal size)173QImage LODocument::paintPart(int part, const QSize &size)
174{174{
175 if (!m_lokDocument)175 if (!m_lokDocument)
176 return QImage();176 return QImage();
@@ -189,11 +189,11 @@
189 QSize resultSize;189 QSize resultSize;
190190
191 if (tWidth > tHeight) {191 if (tWidth > tHeight) {
192 resultSize.setWidth(size);192 resultSize.setWidth(size.width());
193 resultSize.setHeight(size * tHeight / tWidth);193 resultSize.setHeight(size.width() * tHeight / tWidth);
194 } else {194 } else {
195 resultSize.setHeight(size);195 resultSize.setHeight(size.height());
196 resultSize.setWidth(size * tWidth / tHeight);196 resultSize.setWidth(size.height() * tWidth / tHeight);
197 }197 }
198198
199 QImage result = QImage(resultSize.width(), resultSize.height(), QImage::Format_RGB32);199 QImage result = QImage(resultSize.width(), resultSize.height(), QImage::Format_RGB32);
200200
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2016-01-25 12:59:02 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2016-02-05 22:57:36 +0000
@@ -59,7 +59,7 @@
59 QSize documentSize(int part) const;59 QSize documentSize(int part) const;
6060
61 QImage paintTile(int part, const QSize& canvasSize, const QRect& tileSize, const qreal& zoom = 1.0);61 QImage paintTile(int part, const QSize& canvasSize, const QRect& tileSize, const qreal& zoom = 1.0);
62 QImage paintThumbnail(int part, qreal size);62 QImage paintPart(int part, const QSize &size);
6363
64 int partsCount();64 int partsCount();
65 QString getPartName(int index) const;65 QString getPartName(int index) const;
6666
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2015-12-12 10:06:55 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2016-02-05 22:57:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2015 Canonical, Ltd.2 * Copyright (C) 2015 Stefano Verzegnassi
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -15,50 +15,42 @@
15 */15 */
1616
17#include "lopartsimageprovider.h"17#include "lopartsimageprovider.h"
18#include "lopartsimageresponse.h"
19
18#include "lodocument.h"20#include "lodocument.h"
21
19#include "../../app/renderengine.h"22#include "../../app/renderengine.h"
23#include "lorendertask.h"
2024
21LOPartsImageProvider::LOPartsImageProvider(const QSharedPointer<LODocument>& d)25LOPartsImageProvider::LOPartsImageProvider(const QSharedPointer<LODocument>& d)
22 : QQuickImageProvider(QQuickImageProvider::Image),26 : QQuickAsyncImageProvider()
23 m_document(d)27 , m_document(d)
24{ }28{ }
2529
26QImage LOPartsImageProvider::requestImage(const QString & id, QSize * size, const QSize & requestedSize)30QQuickImageResponse *LOPartsImageProvider::requestImageResponse(const QString & id, const QSize & requestedSize)
27{31{
28 Q_UNUSED(size)
29
30 QString type = id.section("/", 0, 0);32 QString type = id.section("/", 0, 0);
3133 int part = id.section("/", 1, 1).toInt();
32 if (requestedSize.isNull() || type != "part" ||34 bool isValid = bool(!requestedSize.isNull() || type == "part");
33 m_document->documentType() != LODocument::PresentationDocument)35
34 return QImage();36 auto response = new LOPartsImageResponse(isValid);
3537
36 // Get info from "id".38 if (isValid) {
37 int partNumber = id.section("/", 1, 1).toInt();39 int taskId = RenderEngine::getNextId();
38 int itemId = id.section("/", 2, 2).toInt();40 response->setTaskId(taskId);
3941 RenderEngine::instance()->enqueueTask(createTask(part, requestedSize, taskId));
40 // Once rendered images can be found in hash.42 }
41 if (m_images.contains(itemId))43
42 return m_images[itemId];44 return response;
43
44 const int defaultSize = 256;
45
46 RenderEngine::instance()->enqueueTask(createTask(partNumber, defaultSize, itemId));
47
48 // Return default image (empty).
49 static QImage defaultImage;
50 if (defaultImage.isNull())
51 defaultImage = QImage(defaultSize, defaultSize, QImage::Format_ARGB32);
52
53 return defaultImage;
54}45}
5546
56ThumbnailRenderTask *LOPartsImageProvider::createTask(int part, qreal size, int id) const47ThumbnailRenderTask* LOPartsImageProvider::createTask(int part, const QSize &size, int id) const
57{48{
58 ThumbnailRenderTask* task = new ThumbnailRenderTask();49 ThumbnailRenderTask* task = new ThumbnailRenderTask();
59 task->setId(id);50 task->setId(id);
60 task->setPart(part);51 task->setPart(part);
61 task->setDocument(m_document);52 task->setDocument(m_document);
62 task->setSize(size);53 task->setSize(size.isEmpty() ? QSize(256, 256) : size);
54
63 return task;55 return task;
64}56}
6557
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2015-12-12 10:06:55 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2016-02-05 22:57:36 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2015 Canonical, Ltd.2 * Copyright (C) 2015 Stefano Verzegnassi
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -18,28 +18,24 @@
18#ifndef LOPARTSIMAGEPROVIDER_H18#ifndef LOPARTSIMAGEPROVIDER_H
19#define LOPARTSIMAGEPROVIDER_H19#define LOPARTSIMAGEPROVIDER_H
2020
21#include <QQuickImageProvider>21// For QQuickAsyncImageProvider
22#include <qquickimageprovider.h>
22#include <QSharedPointer>23#include <QSharedPointer>
23#include <QHash>
24#include <QDebug>
25
26#include "lorendertask.h"
2724
28class LODocument;25class LODocument;
26class ThumbnailRenderTask;
2927
30class LOPartsImageProvider : public QQuickImageProvider28class LOPartsImageProvider : public QQuickAsyncImageProvider
31{29{
32public:30public:
33 LOPartsImageProvider(const QSharedPointer<LODocument>& d);31 LOPartsImageProvider(const QSharedPointer<LODocument>& d);
34 QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize);32 QQuickImageResponse* requestImageResponse(const QString & id, const QSize & requestedSize);
3533
36 QHash<int, QImage> m_images;34private:
35 ThumbnailRenderTask* createTask(int part, const QSize &size, int id) const;
3736
38private:37private:
39 QSharedPointer<LODocument> m_document;38 QSharedPointer<LODocument> m_document;
40
41private:
42 ThumbnailRenderTask* createTask(int part, qreal size, int id) const;
43};39};
4440
45#endif // LOPARTSIMAGEPROVIDER_H41#endif // LOPARTSIMAGEPROVIDER_H
4642
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp 2016-02-05 22:57:36 +0000
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2015 Roman Shchekin
3 * Copyright (C) 2015 Stefano Verzegnassi
4 *
5 * This program is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 3, as published
7 * by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranties of
11 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12 * PURPOSE. See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "lopartsimageresponse.h"
19#include "lodocument.h"
20
21#include "../../app/renderengine.h"
22
23LOPartsImageResponse::LOPartsImageResponse(bool isRequestValid)
24 : m_taskId(0)
25{
26 if (!isRequestValid) {
27 m_errorString = "Requested size or id are not valid.";
28
29 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
30 return;
31 }
32
33 connect(RenderEngine::instance(), &RenderEngine::taskRenderFinished,
34 this, [&](AbstractRenderTask *task, QImage img) {
35 if (m_taskId == task->id() && task->type() == RttImpressThumbnail) {
36 m_image = img;
37 Q_EMIT finished();
38 }
39 }, Qt::BlockingQueuedConnection);
40}
41
42LOPartsImageResponse::~LOPartsImageResponse()
43{
44 disconnect(this);
45
46 QMetaObject::invokeMethod(RenderEngine::instance(), "dequeueTask",
47 Qt::QueuedConnection,
48 Q_ARG(int, m_taskId));
49}
50
51QQuickTextureFactory * LOPartsImageResponse::textureFactory() const
52{
53 return QQuickTextureFactory::textureFactoryForImage(m_image);
54}
055
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h 2016-02-05 22:57:36 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2015 Stefano Verzegnassi
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#ifndef LOPARTSIMAGERESPONSE_H
19#define LOPARTSIMAGEPROVIDER_H
20
21// For QQuickImageResponse
22#include <qquickimageprovider.h>
23
24class LOPartsImageResponse : public QQuickImageResponse
25{
26public:
27 LOPartsImageResponse(bool isRequestValid);
28 ~LOPartsImageResponse();
29
30 void setTaskId(const int id) { m_taskId = id; }
31 QString errorString() const override { return m_errorString; }
32 QQuickTextureFactory * textureFactory() const override;
33
34private:
35 QString m_errorString;
36 QImage m_image;
37 int m_taskId;
38};
39
40
41#endif // LOPARTSIMAGERESPONSE_H
042
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 2015-10-11 11:31:22 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 2016-02-05 22:57:36 +0000
@@ -33,8 +33,6 @@
33 QHash<int, QByteArray> roles;33 QHash<int, QByteArray> roles;
34 roles[IndexRole] = "index";34 roles[IndexRole] = "index";
35 roles[NameRole] = "name";35 roles[NameRole] = "name";
36 roles[IdRole] = "id";
37 roles[ThumbnailRole] = "thumbnail";
3836
39 return roles;37 return roles;
40}38}
@@ -57,10 +55,6 @@
57 return part.index;55 return part.index;
58 case NameRole:56 case NameRole:
59 return part.name;57 return part.name;
60 case IdRole:
61 return part.id;
62 case ThumbnailRole:
63 return part.thumbnail;
6458
65 default:59 default:
66 return 0;60 return 0;
@@ -79,22 +73,10 @@
79 QVariantMap map;73 QVariantMap map;
80 map["name"] = part.name;74 map["name"] = part.name;
81 map["index"] = part.index;75 map["index"] = part.index;
82 map["id"] = part.id;
83 map["thumbnail"] = part.thumbnail;
8476
85 return map;77 return map;
86}78}
8779
88void LOPartsModel::notifyAboutChanges(int id)
89{
90 for (int i = 0; i < m_entries.size(); i++)
91 if (m_entries[i].id == id) {
92 m_entries[i].thumbnail += "/cached";
93 Q_EMIT dataChanged(createIndex(i, 0), createIndex(i + 1, 0));
94 break;
95 }
96}
97
98void LOPartsModel::fillModel() {80void LOPartsModel::fillModel() {
99 if (!m_document)81 if (!m_document)
100 return;82 return;
@@ -112,8 +94,6 @@
11294
113 part.index = i;95 part.index = i;
114 part.name = m_document->getPartName(i);96 part.name = m_document->getPartName(i);
115 part.id = RenderEngine::getNextId();
116 part.thumbnail = QString("image://lok/part/%1/%2").arg(QString::number(part.index)).arg(QString::number(part.id));
11797
118 m_entries.append(part);98 m_entries.append(part);
119 }99 }
120100
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2015-12-12 10:06:55 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2016-02-05 22:57:36 +0000
@@ -30,14 +30,11 @@
30{30{
31public:31public:
32 LOPartEntry():32 LOPartEntry():
33 id(0),
34 index(0)33 index(0)
35 { }34 { }
3635
37 int id;
38 int index;36 int index;
39 QString name;37 QString name;
40 QString thumbnail;
41};38};
4239
43class LOPartsModel : public QAbstractListModel40class LOPartsModel : public QAbstractListModel
@@ -50,8 +47,6 @@
50 enum Roles {47 enum Roles {
51 NameRole = Qt::UserRole + 1,48 NameRole = Qt::UserRole + 1,
52 IndexRole,49 IndexRole,
53 IdRole,
54 ThumbnailRole
55 };50 };
5651
57 explicit LOPartsModel(const QSharedPointer<LODocument>& document, QAbstractListModel *parent = 0);52 explicit LOPartsModel(const QSharedPointer<LODocument>& document, QAbstractListModel *parent = 0);
@@ -64,8 +59,6 @@
6459
65 Q_INVOKABLE QVariantMap get(int index) const;60 Q_INVOKABLE QVariantMap get(int index) const;
6661
67 void notifyAboutChanges(int id);
68
69Q_SIGNALS:62Q_SIGNALS:
70 void countChanged();63 void countChanged();
7164
7265
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp 2016-01-07 11:23:50 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp 2016-02-05 22:57:36 +0000
@@ -21,5 +21,5 @@
2121
22QImage ThumbnailRenderTask::doWork()22QImage ThumbnailRenderTask::doWork()
23{23{
24 return m_document->paintThumbnail(m_part, m_size);24 return m_document->paintPart(m_part, m_size);
25}25}
2626
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h 2016-01-07 11:23:50 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h 2016-02-05 22:57:36 +0000
@@ -48,10 +48,10 @@
48 virtual RenderTaskType type() { return RttImpressThumbnail; }48 virtual RenderTaskType type() { return RttImpressThumbnail; }
49 virtual QImage doWork();49 virtual QImage doWork();
5050
51 qreal size() { return m_size; }51 QSize size() const { return m_size; }
52 void setSize(qreal s) { m_size = s; }52 void setSize(const QSize & s) { m_size = s; }
53protected:53protected:
54 qreal m_size;54 QSize m_size;
55};55};
5656
57#endif // LORENDERTASK_H57#endif // LORENDERTASK_H
5858
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2016-01-29 12:12:54 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2016-02-05 22:57:36 +0000
@@ -344,9 +344,15 @@
344void LOView::slotTaskRenderFinished(AbstractRenderTask* task, QImage img)344void LOView::slotTaskRenderFinished(AbstractRenderTask* task, QImage img)
345{345{
346 if (task->type() == RttTile) {346 if (task->type() == RttTile) {
347 updateTileData(task, img);347 int id = task->id();
348 } else if (task->type() == RttImpressThumbnail) {348
349 updateThumbnailModel(task, img);349 for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i) {
350 SGTileItem* sgtile = i.value();
351 if (sgtile->id() == id) {
352 sgtile->setData(img);
353 break;
354 }
355 }
350 }356 }
351}357}
352358
@@ -401,25 +407,6 @@
401 return task;407 return task;
402}408}
403409
404void LOView::updateTileData(AbstractRenderTask* task, QImage img)
405{
406 int id = task->id();
407 for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i) {
408 SGTileItem* sgtile = i.value();
409 if (sgtile->id() == id) {
410 sgtile->setData(img);
411 break;
412 }
413 }
414}
415
416void LOView::updateThumbnailModel(AbstractRenderTask* task, QImage img)
417{
418 int id = task->id();
419 if (!m_imageProvider->m_images.contains(id))
420 m_imageProvider->m_images.insert(id, img);
421 m_partsModel->notifyAboutChanges(id);
422}
423410
424void LOView::setError(const LibreOfficeError::Error &error)411void LOView::setError(const LibreOfficeError::Error &error)
425{412{
426413
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.h 2016-01-21 00:29:15 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2016-02-05 22:57:36 +0000
@@ -113,8 +113,6 @@
113 void createTile(int index, const QRect& rect);113 void createTile(int index, const QRect& rect);
114 void clearView();114 void clearView();
115 TileRenderTask* createTask(const QRect& rect, int id) const;115 TileRenderTask* createTask(const QRect& rect, int id) const;
116 void updateTileData(AbstractRenderTask* task, QImage img);
117 void updateThumbnailModel(AbstractRenderTask* task, QImage img);
118116
119 void setError(const LibreOfficeError::Error &error);117 void setError(const LibreOfficeError::Error &error);
120};118};

Subscribers

People subscribed via source and target branches