on xenial help sign in
Async CroppedImageSizer
commitb60e2fc364e56ae649d0be5cf5fe7b76dd9335e0 authorAlbert Astals <albert.astals@canonical.com> dateWed 5 Nov 2014, 11:06 (12 years ago) parentbcf198c
6 files changed+157−38
CMakeLists.txt+1 plugins/Dash/CMakeLists.txt+2 plugins/Dash/croppedimagesizer.cpp+20−35 plugins/Dash/croppedimagesizer.h+3−3 plugins/Dash/croppedimagesizerasyncworker.cpp+84 plugins/Dash/croppedimagesizerasyncworker.h+47
CMakeLists.txt+1
@@ -53,6 +53,7 @@ find_package(Qt5Qml 5.2 REQUIRED)
5353find_package(Qt5Quick 5.2 REQUIRED)
5454find_package(Qt5Gui 5.2 REQUIRED)
5555find_package(Qt5DBus 5.2 REQUIRED)
56+find_package(Qt5Concurrent 5.2 REQUIRED)
5657
5758# Standard install paths
5859include(GNUInstallDirs)
plugins/Dash/CMakeLists.txt+2
@@ -14,6 +14,7 @@ include_directories(
1414 ${Qt5Quick_INCLUDE_DIRS}
1515 ${Qt5Quick_PRIVATE_INCLUDE_DIRS}
1616 ${Qt5V8_PRIVATE_INCLUDE_DIR}
17+ ${Qt5Concurrent_INCLUDE_DIRS}
1718)
1819
1920remove_definitions(-DQT_NO_KEYWORDS)
@@ -26,6 +27,7 @@ set(QMLPLUGIN_SRC
2627 horizontaljournal.cpp
2728 organicgrid.cpp
2829 croppedimagesizer.cpp
30+ croppedimagesizerasyncworker.cpp
2931 )
3032
3133add_library(Dash-qml MODULE
plugins/Dash/croppedimagesizer.cpp+20−35
@@ -16,25 +16,26 @@
1616
1717#include "croppedimagesizer.h"
1818
19−#include <QDebug>
20−#include <QNetworkReply>
19+#include "croppedimagesizerasyncworker.h"
20+
21+#include <QNetworkAccessManager>
2122#include <QNetworkRequest>
2223#include <QQmlEngine>
2324#include <QQuickItem>
24−#include <QQuickView>
2525
2626CroppedImageSizer::CroppedImageSizer()
2727 : m_width(0),
2828 m_height(0),
29− m_sourceSize(QSize(-1, -1))
29+ m_sourceSize(QSize(-1, -1)),
30+ m_worker(nullptr)
3031{
3132 connect(this, &CroppedImageSizer::inputParamsChanged, this, &CroppedImageSizer::calculateSourceSize);
3233}
3334
3435CroppedImageSizer::~CroppedImageSizer()
3536{
36− if (m_reply) {
37− m_reply->deleteLater();
37+ if (m_worker) {
38+ m_worker->abort();
3839 }
3940}
4041
@@ -82,42 +83,26 @@ QSize CroppedImageSizer::sourceSize() const
8283 return m_sourceSize;
8384}
8485
86+void CroppedImageSizer::setSourceSize(const QSize &size)
87+{
88+ if (size != m_sourceSize) {
89+ m_sourceSize = size;
90+ Q_EMIT sourceSizeChanged();
91+ }
92+}
93+
8594void CroppedImageSizer::calculateSourceSize()
8695{
8796 if (m_source.isValid() && m_width > 0 && m_height > 0 && qmlEngine(this) && qmlEngine(this)->networkAccessManager()) {
88− if (m_reply) {
89− m_reply->abort();
90− m_reply->deleteLater();
97+ if (m_worker) {
98+ m_worker->abort();
9199 }
100+
92101 QNetworkRequest request(m_source);
93− m_reply = qmlEngine(this)->networkAccessManager()->get(request);
94− connect(m_reply, &QNetworkReply::finished, this, &CroppedImageSizer::requestFinished);
102+ QNetworkReply *reply = qmlEngine(this)->networkAccessManager()->get(request);
103+ m_worker = new CroppedImageSizerAsyncWorker(this, reply);
95104 } else if (m_sourceSize != QSize(-1, -1)) {
96105 m_sourceSize = QSize(-1, -1);
97106 sourceSizeChanged();
98107 }
99108}
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 @@
2222#include <QSize>
2323#include <QUrl>
2424
25−class QNetworkReply;
25+class CroppedImageSizerAsyncWorker;
2626
2727class CroppedImageSizer : public QObject
2828{
@@ -47,6 +47,7 @@ public:
4747 void setHeight(qreal height);
4848
4949 QSize sourceSize() const;
50+ void setSourceSize(const QSize &sourceSize);
5051
5152Q_SIGNALS:
5253 void inputParamsChanged();
@@ -54,14 +55,13 @@ Q_SIGNALS:
5455
5556private Q_SLOT:
5657 void calculateSourceSize();
57− void requestFinished();
5858
5959private:
6060 QUrl m_source;
6161 qreal m_width;
6262 qreal m_height;
6363 QSize m_sourceSize;
64− QNetworkReply *m_reply = nullptr;
64+ QPointer<CroppedImageSizerAsyncWorker> m_worker;
6565};
6666
6767#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