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

Proposed by Stefano Verzegnassi on 2016-01-17
Status: Merged
Approved by: Stefano Verzegnassi on 2016-02-05
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 on 2016-02-05
Roman Shchekin 2016-01-22 Approve on 2016-02-05
Nicholas Skaggs (community) 2016-01-17 Needs Fixing on 2016-02-02
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.

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

review: Needs Fixing (continuous-integration)
Roman Shchekin (mrqtros) wrote :

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

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.

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 on 2016-01-24

Moved all the RenderEngine code in LOPartsImageResponse to LOPartsImageProvider

review: Needs Fixing (continuous-integration)
250. By Stefano Verzegnassi on 2016-01-24

Merged trunk. Updated translation template.

251. By Stefano Verzegnassi on 2016-01-24

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

review: Needs Fixing (continuous-integration)
review: Needs Fixing (continuous-integration)
252. By Stefano Verzegnassi on 2016-01-26

Debugging Jenkins issue with QQuickAsyncImageProvider

review: Needs Fixing (continuous-integration)
review: Needs Fixing (continuous-integration)
253. By Stefano Verzegnassi on 2016-02-02

Merged trunk, updated .pot

review: Needs Fixing (continuous-integration)

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

review: Needs Fixing (continuous-integration)
review: Needs Fixing (continuous-integration)
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
Nicholas Skaggs (nskaggs) wrote :

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

Roman Shchekin (mrqtros) wrote :

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

- 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...

Roman Shchekin (mrqtros) wrote :

Ok, let's merge then!

review: Approve
254. By Stefano Verzegnassi on 2016-02-05

Merged trunk + fixed .pot conflict

255. By Stefano Verzegnassi on 2016-02-05

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! :/

review: Approve (continuous-integration)
256. By Stefano Verzegnassi on 2016-02-05

Removed Jenkins debug

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 2016-02-03 13:51:11 +0000
3+++ po/com.ubuntu.docviewer.pot 2016-02-05 22:57:36 +0000
4@@ -8,7 +8,7 @@
5 msgstr ""
6 "Project-Id-Version: \n"
7 "Report-Msgid-Bugs-To: \n"
8-"POT-Creation-Date: 2016-02-03 14:48+0100\n"
9+"POT-Creation-Date: 2016-02-05 23:40+0100\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@@ -216,7 +216,7 @@
14 msgstr ""
15
16 #: ../src/app/qml/documentPage/DocumentPage.qml:23
17-#: /tmp/ubuntu-docviewer-app-build/po/com.ubuntu.docviewer.desktop.in.in.h:3
18+#: /tmp/lok-qml-async-imageprovider-build/po/com.ubuntu.docviewer.desktop.in.in.h:3
19 msgid "Documents"
20 msgstr ""
21
22@@ -367,21 +367,21 @@
23 msgid "GO!"
24 msgstr ""
25
26-#: ../src/app/qml/loView/LOViewPage.qml:137
27+#: ../src/app/qml/loView/LOViewPage.qml:167
28 msgid "LibreOffice binaries not found."
29 msgstr ""
30
31-#: ../src/app/qml/loView/LOViewPage.qml:140
32+#: ../src/app/qml/loView/LOViewPage.qml:170
33 msgid "Error while loading LibreOffice."
34 msgstr ""
35
36-#: ../src/app/qml/loView/LOViewPage.qml:143
37+#: ../src/app/qml/loView/LOViewPage.qml:173
38 msgid ""
39 "Document not loaded.\n"
40 "The requested document may be corrupt or protected by a password."
41 msgstr ""
42
43-#: ../src/app/qml/loView/LOViewPage.qml:164
44+#: ../src/app/qml/loView/LOViewPage.qml:228
45 msgid "This sheet has no content."
46 msgstr ""
47
48@@ -446,7 +446,7 @@
49 msgid "Choose a page between 1 and %1"
50 msgstr ""
51
52-#: ../src/app/qml/ubuntu-docviewer-app.qml:118
53+#: ../src/app/qml/ubuntu-docviewer-app.qml:114
54 msgid "File does not exist."
55 msgstr ""
56
57@@ -464,10 +464,10 @@
58 msgid "copy %1"
59 msgstr ""
60
61-#: /tmp/ubuntu-docviewer-app-build/po/com.ubuntu.docviewer.desktop.in.in.h:1
62+#: /tmp/lok-qml-async-imageprovider-build/po/com.ubuntu.docviewer.desktop.in.in.h:1
63 msgid "Document Viewer"
64 msgstr ""
65
66-#: /tmp/ubuntu-docviewer-app-build/po/com.ubuntu.docviewer.desktop.in.in.h:2
67+#: /tmp/lok-qml-async-imageprovider-build/po/com.ubuntu.docviewer.desktop.in.in.h:2
68 msgid "documents;viewer;pdf;reader;"
69 msgstr ""
70
71=== modified file 'src/app/qml/loView/PartsView.qml'
72--- src/app/qml/loView/PartsView.qml 2016-01-17 12:09:58 +0000
73+++ src/app/qml/loView/PartsView.qml 2016-02-05 22:57:36 +0000
74@@ -103,8 +103,8 @@
75 fillMode: Image.PreserveAspectFit
76 // Do not store a cache of the thumbnail, so that we don't show
77 // thumbnails of a previously loaded document.
78- cache: true // TODO PLAY WITH IT
79- source: model.thumbnail
80+ cache: false
81+ source: "image://lok/part/%1".arg(model.index)
82 }
83 }
84
85@@ -172,8 +172,8 @@
86 fillMode: Image.PreserveAspectFit
87 // Do not store a cache of the thumbnail, so that we don't show
88 // thumbnails of a previously loaded document.
89- cache: true // TODO PLAY WITH IT
90- source: model.thumbnail
91+ cache: false
92+ source: "image://lok/part/%1".arg(model.index)
93 }
94 }
95
96
97=== modified file 'src/app/qml/pdfView/PdfPresentation.qml'
98--- src/app/qml/pdfView/PdfPresentation.qml 2016-01-23 12:34:25 +0000
99+++ src/app/qml/pdfView/PdfPresentation.qml 2016-02-05 22:57:36 +0000
100@@ -22,7 +22,7 @@
101 Page {
102 id: pdfPage
103 property var poppler
104- property bool isPresentation: true
105+ property bool isPresentationMode: true
106 anchors.fill: parent
107 title: DocumentViewer.getFileBaseNameFromPath(poppler.path)
108 focus: true
109
110=== modified file 'src/app/qml/ubuntu-docviewer-app.qml'
111--- src/app/qml/ubuntu-docviewer-app.qml 2016-01-23 12:48:49 +0000
112+++ src/app/qml/ubuntu-docviewer-app.qml 2016-02-05 22:57:36 +0000
113@@ -34,7 +34,7 @@
114 // force hiding Unity 8 indicators panel.
115 property bool fullscreen: commandLineProxy.fullscreen ||
116 (!desktopMode && isLandscape && narrowWindow) ||
117- pageStack.currentPage.hasOwnProperty("isPresentation")
118+ pageStack.currentPage.hasOwnProperty("isPresentationMode")
119
120 readonly property bool desktopMode: DocumentViewer.desktopMode
121
122@@ -200,5 +200,5 @@
123
124 property bool nightModeEnabled: false
125 layer.effect: NightModeShader {}
126- layer.enabled: nightModeEnabled && (pageStack.depth > 1) && !pageStack.currentPage.isPresentation
127+ layer.enabled: nightModeEnabled && (pageStack.depth > 1) && !pageStack.currentPage.isPresentationMode
128 }
129
130=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
131--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2016-01-20 21:48:21 +0000
132+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2016-02-05 22:57:36 +0000
133@@ -23,6 +23,7 @@
134 loview.cpp
135 sgtileitem.cpp
136 lopartsimageprovider.cpp
137+ lopartsimageresponse.cpp
138 lopartsmodel.cpp
139 lorendertask.cpp
140 ucunits.cpp
141
142=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
143--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2016-01-25 12:15:43 +0000
144+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2016-02-05 22:57:36 +0000
145@@ -170,7 +170,7 @@
146 return result.rgbSwapped();
147 }
148
149-QImage LODocument::paintThumbnail(int part, qreal size)
150+QImage LODocument::paintPart(int part, const QSize &size)
151 {
152 if (!m_lokDocument)
153 return QImage();
154@@ -189,11 +189,11 @@
155 QSize resultSize;
156
157 if (tWidth > tHeight) {
158- resultSize.setWidth(size);
159- resultSize.setHeight(size * tHeight / tWidth);
160+ resultSize.setWidth(size.width());
161+ resultSize.setHeight(size.width() * tHeight / tWidth);
162 } else {
163- resultSize.setHeight(size);
164- resultSize.setWidth(size * tWidth / tHeight);
165+ resultSize.setHeight(size.height());
166+ resultSize.setWidth(size.height() * tWidth / tHeight);
167 }
168
169 QImage result = QImage(resultSize.width(), resultSize.height(), QImage::Format_RGB32);
170
171=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.h'
172--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2016-01-25 12:59:02 +0000
173+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2016-02-05 22:57:36 +0000
174@@ -59,7 +59,7 @@
175 QSize documentSize(int part) const;
176
177 QImage paintTile(int part, const QSize& canvasSize, const QRect& tileSize, const qreal& zoom = 1.0);
178- QImage paintThumbnail(int part, qreal size);
179+ QImage paintPart(int part, const QSize &size);
180
181 int partsCount();
182 QString getPartName(int index) const;
183
184=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp'
185--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2015-12-12 10:06:55 +0000
186+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2016-02-05 22:57:36 +0000
187@@ -1,5 +1,5 @@
188 /*
189- * Copyright (C) 2015 Canonical, Ltd.
190+ * Copyright (C) 2015 Stefano Verzegnassi
191 *
192 * This program is free software: you can redistribute it and/or modify it
193 * under the terms of the GNU General Public License version 3, as published
194@@ -15,50 +15,42 @@
195 */
196
197 #include "lopartsimageprovider.h"
198+#include "lopartsimageresponse.h"
199+
200 #include "lodocument.h"
201+
202 #include "../../app/renderengine.h"
203+#include "lorendertask.h"
204
205 LOPartsImageProvider::LOPartsImageProvider(const QSharedPointer<LODocument>& d)
206- : QQuickImageProvider(QQuickImageProvider::Image),
207- m_document(d)
208+ : QQuickAsyncImageProvider()
209+ , m_document(d)
210 { }
211
212-QImage LOPartsImageProvider::requestImage(const QString & id, QSize * size, const QSize & requestedSize)
213+QQuickImageResponse *LOPartsImageProvider::requestImageResponse(const QString & id, const QSize & requestedSize)
214 {
215- Q_UNUSED(size)
216-
217 QString type = id.section("/", 0, 0);
218-
219- if (requestedSize.isNull() || type != "part" ||
220- m_document->documentType() != LODocument::PresentationDocument)
221- return QImage();
222-
223- // Get info from "id".
224- int partNumber = id.section("/", 1, 1).toInt();
225- int itemId = id.section("/", 2, 2).toInt();
226-
227- // Once rendered images can be found in hash.
228- if (m_images.contains(itemId))
229- return m_images[itemId];
230-
231- const int defaultSize = 256;
232-
233- RenderEngine::instance()->enqueueTask(createTask(partNumber, defaultSize, itemId));
234-
235- // Return default image (empty).
236- static QImage defaultImage;
237- if (defaultImage.isNull())
238- defaultImage = QImage(defaultSize, defaultSize, QImage::Format_ARGB32);
239-
240- return defaultImage;
241+ int part = id.section("/", 1, 1).toInt();
242+ bool isValid = bool(!requestedSize.isNull() || type == "part");
243+
244+ auto response = new LOPartsImageResponse(isValid);
245+
246+ if (isValid) {
247+ int taskId = RenderEngine::getNextId();
248+ response->setTaskId(taskId);
249+ RenderEngine::instance()->enqueueTask(createTask(part, requestedSize, taskId));
250+ }
251+
252+ return response;
253 }
254
255-ThumbnailRenderTask *LOPartsImageProvider::createTask(int part, qreal size, int id) const
256+ThumbnailRenderTask* LOPartsImageProvider::createTask(int part, const QSize &size, int id) const
257 {
258 ThumbnailRenderTask* task = new ThumbnailRenderTask();
259 task->setId(id);
260 task->setPart(part);
261 task->setDocument(m_document);
262- task->setSize(size);
263+ task->setSize(size.isEmpty() ? QSize(256, 256) : size);
264+
265 return task;
266 }
267
268=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h'
269--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2015-12-12 10:06:55 +0000
270+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2016-02-05 22:57:36 +0000
271@@ -1,5 +1,5 @@
272 /*
273- * Copyright (C) 2015 Canonical, Ltd.
274+ * Copyright (C) 2015 Stefano Verzegnassi
275 *
276 * This program is free software: you can redistribute it and/or modify it
277 * under the terms of the GNU General Public License version 3, as published
278@@ -18,28 +18,24 @@
279 #ifndef LOPARTSIMAGEPROVIDER_H
280 #define LOPARTSIMAGEPROVIDER_H
281
282-#include <QQuickImageProvider>
283+// For QQuickAsyncImageProvider
284+#include <qquickimageprovider.h>
285 #include <QSharedPointer>
286-#include <QHash>
287-#include <QDebug>
288-
289-#include "lorendertask.h"
290
291 class LODocument;
292+class ThumbnailRenderTask;
293
294-class LOPartsImageProvider : public QQuickImageProvider
295+class LOPartsImageProvider : public QQuickAsyncImageProvider
296 {
297 public:
298 LOPartsImageProvider(const QSharedPointer<LODocument>& d);
299- QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize);
300+ QQuickImageResponse* requestImageResponse(const QString & id, const QSize & requestedSize);
301
302- QHash<int, QImage> m_images;
303+private:
304+ ThumbnailRenderTask* createTask(int part, const QSize &size, int id) const;
305
306 private:
307 QSharedPointer<LODocument> m_document;
308-
309-private:
310- ThumbnailRenderTask* createTask(int part, qreal size, int id) const;
311 };
312
313 #endif // LOPARTSIMAGEPROVIDER_H
314
315=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp'
316--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp 1970-01-01 00:00:00 +0000
317+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.cpp 2016-02-05 22:57:36 +0000
318@@ -0,0 +1,54 @@
319+/*
320+ * Copyright (C) 2015 Roman Shchekin
321+ * Copyright (C) 2015 Stefano Verzegnassi
322+ *
323+ * This program is free software: you can redistribute it and/or modify it
324+ * under the terms of the GNU General Public License version 3, as published
325+ * by the Free Software Foundation.
326+ *
327+ * This program is distributed in the hope that it will be useful, but
328+ * WITHOUT ANY WARRANTY; without even the implied warranties of
329+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
330+ * PURPOSE. See the GNU General Public License for more details.
331+ *
332+ * You should have received a copy of the GNU General Public License along
333+ * with this program. If not, see <http://www.gnu.org/licenses/>.
334+ */
335+
336+#include "lopartsimageresponse.h"
337+#include "lodocument.h"
338+
339+#include "../../app/renderengine.h"
340+
341+LOPartsImageResponse::LOPartsImageResponse(bool isRequestValid)
342+ : m_taskId(0)
343+{
344+ if (!isRequestValid) {
345+ m_errorString = "Requested size or id are not valid.";
346+
347+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
348+ return;
349+ }
350+
351+ connect(RenderEngine::instance(), &RenderEngine::taskRenderFinished,
352+ this, [&](AbstractRenderTask *task, QImage img) {
353+ if (m_taskId == task->id() && task->type() == RttImpressThumbnail) {
354+ m_image = img;
355+ Q_EMIT finished();
356+ }
357+ }, Qt::BlockingQueuedConnection);
358+}
359+
360+LOPartsImageResponse::~LOPartsImageResponse()
361+{
362+ disconnect(this);
363+
364+ QMetaObject::invokeMethod(RenderEngine::instance(), "dequeueTask",
365+ Qt::QueuedConnection,
366+ Q_ARG(int, m_taskId));
367+}
368+
369+QQuickTextureFactory * LOPartsImageResponse::textureFactory() const
370+{
371+ return QQuickTextureFactory::textureFactoryForImage(m_image);
372+}
373
374=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h'
375--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h 1970-01-01 00:00:00 +0000
376+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageresponse.h 2016-02-05 22:57:36 +0000
377@@ -0,0 +1,41 @@
378+/*
379+ * Copyright (C) 2015 Stefano Verzegnassi
380+ *
381+ * This program is free software: you can redistribute it and/or modify it
382+ * under the terms of the GNU General Public License version 3, as published
383+ * by the Free Software Foundation.
384+ *
385+ * This program is distributed in the hope that it will be useful, but
386+ * WITHOUT ANY WARRANTY; without even the implied warranties of
387+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
388+ * PURPOSE. See the GNU General Public License for more details.
389+ *
390+ * You should have received a copy of the GNU General Public License along
391+ * with this program. If not, see <http://www.gnu.org/licenses/>.
392+ *
393+ */
394+
395+#ifndef LOPARTSIMAGERESPONSE_H
396+#define LOPARTSIMAGEPROVIDER_H
397+
398+// For QQuickImageResponse
399+#include <qquickimageprovider.h>
400+
401+class LOPartsImageResponse : public QQuickImageResponse
402+{
403+public:
404+ LOPartsImageResponse(bool isRequestValid);
405+ ~LOPartsImageResponse();
406+
407+ void setTaskId(const int id) { m_taskId = id; }
408+ QString errorString() const override { return m_errorString; }
409+ QQuickTextureFactory * textureFactory() const override;
410+
411+private:
412+ QString m_errorString;
413+ QImage m_image;
414+ int m_taskId;
415+};
416+
417+
418+#endif // LOPARTSIMAGERESPONSE_H
419
420=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp'
421--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 2015-10-11 11:31:22 +0000
422+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 2016-02-05 22:57:36 +0000
423@@ -33,8 +33,6 @@
424 QHash<int, QByteArray> roles;
425 roles[IndexRole] = "index";
426 roles[NameRole] = "name";
427- roles[IdRole] = "id";
428- roles[ThumbnailRole] = "thumbnail";
429
430 return roles;
431 }
432@@ -57,10 +55,6 @@
433 return part.index;
434 case NameRole:
435 return part.name;
436- case IdRole:
437- return part.id;
438- case ThumbnailRole:
439- return part.thumbnail;
440
441 default:
442 return 0;
443@@ -79,22 +73,10 @@
444 QVariantMap map;
445 map["name"] = part.name;
446 map["index"] = part.index;
447- map["id"] = part.id;
448- map["thumbnail"] = part.thumbnail;
449
450 return map;
451 }
452
453-void LOPartsModel::notifyAboutChanges(int id)
454-{
455- for (int i = 0; i < m_entries.size(); i++)
456- if (m_entries[i].id == id) {
457- m_entries[i].thumbnail += "/cached";
458- Q_EMIT dataChanged(createIndex(i, 0), createIndex(i + 1, 0));
459- break;
460- }
461-}
462-
463 void LOPartsModel::fillModel() {
464 if (!m_document)
465 return;
466@@ -112,8 +94,6 @@
467
468 part.index = i;
469 part.name = m_document->getPartName(i);
470- part.id = RenderEngine::getNextId();
471- part.thumbnail = QString("image://lok/part/%1/%2").arg(QString::number(part.index)).arg(QString::number(part.id));
472
473 m_entries.append(part);
474 }
475
476=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h'
477--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2015-12-12 10:06:55 +0000
478+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2016-02-05 22:57:36 +0000
479@@ -30,14 +30,11 @@
480 {
481 public:
482 LOPartEntry():
483- id(0),
484 index(0)
485 { }
486
487- int id;
488 int index;
489 QString name;
490- QString thumbnail;
491 };
492
493 class LOPartsModel : public QAbstractListModel
494@@ -50,8 +47,6 @@
495 enum Roles {
496 NameRole = Qt::UserRole + 1,
497 IndexRole,
498- IdRole,
499- ThumbnailRole
500 };
501
502 explicit LOPartsModel(const QSharedPointer<LODocument>& document, QAbstractListModel *parent = 0);
503@@ -64,8 +59,6 @@
504
505 Q_INVOKABLE QVariantMap get(int index) const;
506
507- void notifyAboutChanges(int id);
508-
509 Q_SIGNALS:
510 void countChanged();
511
512
513=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp'
514--- src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp 2016-01-07 11:23:50 +0000
515+++ src/plugin/libreofficetoolkit-qml-plugin/lorendertask.cpp 2016-02-05 22:57:36 +0000
516@@ -21,5 +21,5 @@
517
518 QImage ThumbnailRenderTask::doWork()
519 {
520- return m_document->paintThumbnail(m_part, m_size);
521+ return m_document->paintPart(m_part, m_size);
522 }
523
524=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h'
525--- src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h 2016-01-07 11:23:50 +0000
526+++ src/plugin/libreofficetoolkit-qml-plugin/lorendertask.h 2016-02-05 22:57:36 +0000
527@@ -48,10 +48,10 @@
528 virtual RenderTaskType type() { return RttImpressThumbnail; }
529 virtual QImage doWork();
530
531- qreal size() { return m_size; }
532- void setSize(qreal s) { m_size = s; }
533+ QSize size() const { return m_size; }
534+ void setSize(const QSize & s) { m_size = s; }
535 protected:
536- qreal m_size;
537+ QSize m_size;
538 };
539
540 #endif // LORENDERTASK_H
541
542=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
543--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2016-01-29 12:12:54 +0000
544+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2016-02-05 22:57:36 +0000
545@@ -344,9 +344,15 @@
546 void LOView::slotTaskRenderFinished(AbstractRenderTask* task, QImage img)
547 {
548 if (task->type() == RttTile) {
549- updateTileData(task, img);
550- } else if (task->type() == RttImpressThumbnail) {
551- updateThumbnailModel(task, img);
552+ int id = task->id();
553+
554+ for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i) {
555+ SGTileItem* sgtile = i.value();
556+ if (sgtile->id() == id) {
557+ sgtile->setData(img);
558+ break;
559+ }
560+ }
561 }
562 }
563
564@@ -401,25 +407,6 @@
565 return task;
566 }
567
568-void LOView::updateTileData(AbstractRenderTask* task, QImage img)
569-{
570- int id = task->id();
571- for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i) {
572- SGTileItem* sgtile = i.value();
573- if (sgtile->id() == id) {
574- sgtile->setData(img);
575- break;
576- }
577- }
578-}
579-
580-void LOView::updateThumbnailModel(AbstractRenderTask* task, QImage img)
581-{
582- int id = task->id();
583- if (!m_imageProvider->m_images.contains(id))
584- m_imageProvider->m_images.insert(id, img);
585- m_partsModel->notifyAboutChanges(id);
586-}
587
588 void LOView::setError(const LibreOfficeError::Error &error)
589 {
590
591=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
592--- src/plugin/libreofficetoolkit-qml-plugin/loview.h 2016-01-21 00:29:15 +0000
593+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2016-02-05 22:57:36 +0000
594@@ -113,8 +113,6 @@
595 void createTile(int index, const QRect& rect);
596 void clearView();
597 TileRenderTask* createTask(const QRect& rect, int id) const;
598- void updateTileData(AbstractRenderTask* task, QImage img);
599- void updateThumbnailModel(AbstractRenderTask* task, QImage img);
600
601 void setError(const LibreOfficeError::Error &error);
602 };

Subscribers

People subscribed via source and target branches