on xenial help sign in
Async CroppedImageSizer
b60e2fcAlbert Astals
CMakeLists.txt+1
@@ -53,6 +53,7 @@ find_package(Qt5Qml 5.2 REQUIRED)
53find_package(Qt5Quick 5.2 REQUIRED)
53find_package(Qt5Quick 5.2 REQUIRED)
54find_package(Qt5Gui 5.2 REQUIRED)
54find_package(Qt5Gui 5.2 REQUIRED)
55find_package(Qt5DBus 5.2 REQUIRED)
55find_package(Qt5DBus 5.2 REQUIRED)
56+find_package(Qt5Concurrent 5.2 REQUIRED)
56
57
57# Standard install paths
58# Standard install paths
58include(GNUInstallDirs)
59include(GNUInstallDirs)
plugins/Dash/CMakeLists.txt+2
@@ -14,6 +14,7 @@ include_directories(
14 ${Qt5Quick_INCLUDE_DIRS}
14 ${Qt5Quick_INCLUDE_DIRS}
15 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
15 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
16 ${Qt5V8_PRIVATE_INCLUDE_DIR}
16 ${Qt5V8_PRIVATE_INCLUDE_DIR}
17+ ${Qt5Concurrent_INCLUDE_DIRS}
17)
18)
18
19
19remove_definitions(-DQT_NO_KEYWORDS)
20remove_definitions(-DQT_NO_KEYWORDS)
@@ -26,6 +27,7 @@ set(QMLPLUGIN_SRC
26 horizontaljournal.cpp
27 horizontaljournal.cpp
27 organicgrid.cpp
28 organicgrid.cpp
28 croppedimagesizer.cpp
29 croppedimagesizer.cpp
30+ croppedimagesizerasyncworker.cpp
29 )
31 )
30
32
31add_library(Dash-qml MODULE
33add_library(Dash-qml MODULE
plugins/Dash/croppedimagesizer.cpp+20−35
@@ -16,25 +16,26 @@
16
16
17#include "croppedimagesizer.h"
17#include "croppedimagesizer.h"
18
18
19−#include <QDebug>
19+#include "croppedimagesizerasyncworker.h"
20−#include <QNetworkReply>
20+
21+#include <QNetworkAccessManager>
21#include <QNetworkRequest>
22#include <QNetworkRequest>
22#include <QQmlEngine>
23#include <QQmlEngine>
23#include <QQuickItem>
24#include <QQuickItem>
24−#include <QQuickView>
25
25
26CroppedImageSizer::CroppedImageSizer()
26CroppedImageSizer::CroppedImageSizer()
27 : m_width(0),
27 : m_width(0),
28 m_height(0),
28 m_height(0),
29− m_sourceSize(QSize(-1, -1))
29+ m_sourceSize(QSize(-1, -1)),
30+ m_worker(nullptr)
30{
31{
31 connect(this, &CroppedImageSizer::inputParamsChanged, this, &CroppedImageSizer::calculateSourceSize);
32 connect(this, &CroppedImageSizer::inputParamsChanged, this, &CroppedImageSizer::calculateSourceSize);
32}
33}
33
34
34CroppedImageSizer::~CroppedImageSizer()
35CroppedImageSizer::~CroppedImageSizer()
35{
36{
36− if (m_reply) {
37+ if (m_worker) {
37− m_reply->deleteLater();
38+ m_worker->abort();
38 }
39 }
39}
40}
40
41
@@ -82,42 +83,26 @@ QSize CroppedImageSizer::sourceSize() const
82 return m_sourceSize;
83 return m_sourceSize;
83}
84}
84
85
86+void CroppedImageSizer::setSourceSize(const QSize &size)
87+{
88+ if (size != m_sourceSize) {
89+ m_sourceSize = size;
90+ Q_EMIT sourceSizeChanged();
91+ }
92+}
93+
85void CroppedImageSizer::calculateSourceSize()
94void CroppedImageSizer::calculateSourceSize()
86{
95{
87 if (m_source.isValid() && m_width > 0 && m_height > 0 && qmlEngine(this) && qmlEngine(this)->networkAccessManager()) {
96 if (m_source.isValid() && m_width > 0 && m_height > 0 && qmlEngine(this) && qmlEngine(this)->networkAccessManager()) {
88− if (m_reply) {
97+ if (m_worker) {
89− m_reply->abort();
98+ m_worker->abort();
90− m_reply->deleteLater();
91 }
99 }
100+
92 QNetworkRequest request(m_source);
101 QNetworkRequest request(m_source);
93− m_reply = qmlEngine(this)->networkAccessManager()->get(request);
102+ QNetworkReply *reply = qmlEngine(this)->networkAccessManager()->get(request);
94− connect(m_reply, &QNetworkReply::finished, this, &CroppedImageSizer::requestFinished);
103+ m_worker = new CroppedImageSizerAsyncWorker(this, reply);
95 } else if (m_sourceSize != QSize(-1, -1)) {
104 } else if (m_sourceSize != QSize(-1, -1)) {
96 m_sourceSize = QSize(-1, -1);
105 m_sourceSize = QSize(-1, -1);
97 sourceSizeChanged();
106 sourceSizeChanged();
98 }
107 }
99}
108}
100−
101−void CroppedImageSizer::requestFinished()
102−{
103− QImageReader m_reader(m_reply);
104− const QSize imageSize = m_reader.size();
105− if (imageSize.isValid()) {
106− if (m_height > 0 && imageSize.height() > 0) {
107− const qreal ar = m_width / m_height;
108− const qreal ssar = imageSize.width() / (qreal)imageSize.height();
109− if (ar > ssar) {
110− m_sourceSize = QSize(m_width, 0);
111− } else {
112− m_sourceSize = QSize(0, m_height);
113− }
114− }
115− } else {
116− qWarning() << "Could not find size of" << m_source;
117− m_sourceSize = QSize(0, 0);
118− }
119− sourceSizeChanged();
120−
121− m_reply->deleteLater();
122− m_reply = nullptr;
123−}
plugins/Dash/croppedimagesizer.h+3−3
@@ -22,7 +22,7 @@
22#include <QSize>
22#include <QSize>
23#include <QUrl>
23#include <QUrl>
24
24
25−class QNetworkReply;
25+class CroppedImageSizerAsyncWorker;
26
26
27class CroppedImageSizer : public QObject
27class CroppedImageSizer : public QObject
28{
28{
@@ -47,6 +47,7 @@ public:
47 void setHeight(qreal height);
47 void setHeight(qreal height);
48
48
49 QSize sourceSize() const;
49 QSize sourceSize() const;
50+ void setSourceSize(const QSize &sourceSize);
50
51
51Q_SIGNALS:
52Q_SIGNALS:
52 void inputParamsChanged();
53 void inputParamsChanged();
@@ -54,14 +55,13 @@ Q_SIGNALS:
54
55
55private Q_SLOT:
56private Q_SLOT:
56 void calculateSourceSize();
57 void calculateSourceSize();
57− void requestFinished();
58
58
59private:
59private:
60 QUrl m_source;
60 QUrl m_source;
61 qreal m_width;
61 qreal m_width;
62 qreal m_height;
62 qreal m_height;
63 QSize m_sourceSize;
63 QSize m_sourceSize;
64− QNetworkReply *m_reply = nullptr;
64+ QPointer<CroppedImageSizerAsyncWorker> m_worker;
65};
65};
66
66
67#endif
67#endif
plugins/Dash/croppedimagesizerasyncworker.cppnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "croppedimagesizerasyncworker.h"
18+
19+#include "croppedimagesizer.h"
20+
21+#include <QNetworkReply>
22+#include <QtConcurrentRun>
23+
24+CroppedImageSizerAsyncWorker::CroppedImageSizerAsyncWorker(CroppedImageSizer *sizer, QNetworkReply *reply)
25+ : m_sizer(sizer),
26+ m_reply(reply),
27+ m_ignoreAbort(false)
28+{
29+ connect(m_reply, &QNetworkReply::finished, this, &CroppedImageSizerAsyncWorker::requestFinished);
30+}
31+
32+void CroppedImageSizerAsyncWorker::abort()
33+{
34+ QMutexLocker locker(&m_mutex);
35+ m_sizer = nullptr;
36+ // If we already started the future run we can't abort the reply
37+ // since we don't know at which stage the future is, just let it finish
38+ if (!m_ignoreAbort) {
39+ m_reply->abort();
40+ }
41+}
42+
43+void CroppedImageSizerAsyncWorker::requestFinished()
44+{
45+ QMutexLocker locker(&m_mutex);
46+ if (m_sizer) {
47+ m_ignoreAbort = true;
48+ QtConcurrent::run(processRequestFinished, m_sizer->width(), m_sizer->height(), m_sizer->source(), this);
49+ } else {
50+ // We were aborted delete ourselves
51+ m_reply->deleteLater();
52+ deleteLater();
53+ }
54+}
55+
56+void CroppedImageSizerAsyncWorker::processRequestFinished(qreal width, qreal height, QUrl source, CroppedImageSizerAsyncWorker *worker)
57+{
58+ QImageReader reader(worker->m_reply);
59+ const QSize imageSize = reader.size();
60+ QSize sourceSize = QSize(0, 0);
61+ if (imageSize.isValid()) {
62+ if (height > 0 && imageSize.height() > 0) {
63+ const qreal ar = width / height;
64+ const qreal ssar = imageSize.width() / (qreal)imageSize.height();
65+ if (ar > ssar) {
66+ sourceSize = QSize(width, 0);
67+ } else {
68+ sourceSize = QSize(0, height);
69+ }
70+ }
71+ } else {
72+ qWarning() << "Could not find size of" << source << worker;
73+ }
74+
75+ worker->m_mutex.lock();
76+ if (worker->m_sizer) {
77+ worker->m_sizer->setSourceSize(sourceSize);
78+ }
79+ worker->m_mutex.unlock();
80+
81+ // All work is done, delete ourselves
82+ worker->m_reply->deleteLater();
83+ worker->deleteLater();
84+}
plugins/Dash/croppedimagesizerasyncworker.hnew file+47
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef CROPPEDIMAGESIZERASYNCWORKER_H
18+#define CROPPEDIMAGESIZERASYNCWORKER_H
19+
20+#include <QMutex>
21+#include <QObject>
22+
23+class CroppedImageSizer;
24+
25+class QNetworkReply;
26+
27+class CroppedImageSizerAsyncWorker : public QObject
28+{
29+ Q_OBJECT
30+public:
31+ CroppedImageSizerAsyncWorker(CroppedImageSizer *sizer, QNetworkReply *reply);
32+
33+ void abort();
34+
35+private Q_SLOTS:
36+ void requestFinished();
37+
38+private:
39+ static void processRequestFinished(qreal width, qreal height, QUrl source, CroppedImageSizerAsyncWorker *worker);
40+
41+ QMutex m_mutex;
42+ CroppedImageSizer *m_sizer;
43+ QNetworkReply *m_reply;
44+ bool m_ignoreAbort;
45+};
46+
47+#endif