aboutsummaryrefslogtreecommitdiffstats
path: root/tests/manual/tasking/imagescaling/imagescaling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/tasking/imagescaling/imagescaling.cpp')
-rw-r--r--tests/manual/tasking/imagescaling/imagescaling.cpp135
1 files changed, 135 insertions, 0 deletions
diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp
new file mode 100644
index 0000000000..e3acda749b
--- /dev/null
+++ b/tests/manual/tasking/imagescaling/imagescaling.cpp
@@ -0,0 +1,135 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "imagescaling.h"
+#include "downloaddialog.h"
+#include <tasking/concurrentcall.h>
+#include <tasking/networkquery.h>
+
+using namespace Tasking;
+
+Images::Images(QWidget *parent) : QWidget(parent), downloadDialog(new DownloadDialog(this))
+{
+ resize(800, 600);
+
+ QPushButton *addUrlsButton = new QPushButton(tr("Add URLs"));
+ connect(addUrlsButton, &QPushButton::clicked, this, &Images::process);
+
+ cancelButton = new QPushButton(tr("Cancel"));
+ cancelButton->setEnabled(false);
+ connect(cancelButton, &QPushButton::clicked, this, [this] {
+ statusBar->showMessage(tr("Canceled."));
+ taskTree.reset();
+ });
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->addWidget(addUrlsButton);
+ buttonLayout->addWidget(cancelButton);
+ buttonLayout->addStretch();
+
+ statusBar = new QStatusBar();
+
+ imagesLayout = new QGridLayout();
+
+ mainLayout = new QVBoxLayout();
+ mainLayout->addLayout(buttonLayout);
+ mainLayout->addLayout(imagesLayout);
+ mainLayout->addStretch();
+ mainLayout->addWidget(statusBar);
+ setLayout(mainLayout);
+}
+
+static void scale(QPromise<QImage> &promise, const QByteArray &data)
+{
+ const auto image = QImage::fromData(data);
+ if (image.isNull())
+ promise.future().cancel();
+ else
+ promise.addResult(image.scaled(100, 100, Qt::KeepAspectRatio));
+}
+
+void Images::process()
+{
+ if (downloadDialog->exec() != QDialog::Accepted)
+ return;
+
+ const auto urls = downloadDialog->getUrls();
+ initLayout(urls.size());
+
+ const auto onRootSetup = [this] {
+ statusBar->showMessage(tr("Downloading and Scaling..."));
+ cancelButton->setEnabled(true);
+ };
+ const auto onRootDone = [this] {
+ statusBar->showMessage(tr("Finished."));
+ cancelButton->setEnabled(false);
+ };
+ QList<GroupItem> tasks {
+ finishAllAndDone,
+ parallel,
+ onGroupSetup(onRootSetup),
+ onGroupDone(onRootDone)
+ };
+
+ int i = 0;
+ for (const QUrl &url : urls) {
+ TreeStorage<QByteArray> storage;
+
+ const auto onDownloadSetup = [this, url](NetworkQuery &query) {
+ query.setNetworkAccessManager(&qnam);
+ query.setRequest(QNetworkRequest(url));
+ };
+ const auto onDownloadDone = [storage](const NetworkQuery &query) {
+ *storage = query.reply()->readAll();
+ };
+ const auto onDownloadError = [this, i](const NetworkQuery &query) {
+ labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error()));
+ };
+
+ const auto onScalingSetup = [storage](ConcurrentCall<QImage> &data) {
+ data.setConcurrentCallData(&scale, *storage);
+ };
+ const auto onScalingDone = [this, i](const ConcurrentCall<QImage> &data) {
+ labels[i]->setPixmap(QPixmap::fromImage(data.result()));
+ };
+ const auto onScalingError = [this, i](const ConcurrentCall<QImage> &) {
+ labels[i]->setText(tr("Image\nData\nError."));
+ };
+
+ const Group group {
+ Storage(storage),
+ NetworkQueryTask(onDownloadSetup, onDownloadDone, onDownloadError),
+ ConcurrentCallTask<QImage>(onScalingSetup, onScalingDone, onScalingError)
+ };
+ tasks.append(group);
+ ++i;
+ }
+
+ taskTree.reset(new TaskTree(tasks));
+ connect(taskTree.get(), &TaskTree::done, this, [this] { taskTree.release()->deleteLater(); });
+ taskTree->start();
+}
+
+void Images::initLayout(qsizetype count)
+{
+ // Clean old images
+ QLayoutItem *child;
+ while ((child = imagesLayout->takeAt(0)) != nullptr) {
+ child->widget()->setParent(nullptr);
+ delete child->widget();
+ delete child;
+ }
+ labels.clear();
+
+ // Init the images layout for the new images
+ const auto dim = int(qSqrt(qreal(count))) + 1;
+ for (int i = 0; i < dim; ++i) {
+ for (int j = 0; j < dim; ++j) {
+ QLabel *imageLabel = new QLabel;
+ imageLabel->setFixedSize(100, 100);
+ imageLabel->setAlignment(Qt::AlignCenter);
+ imagesLayout->addWidget(imageLabel, i, j);
+ labels.append(imageLabel);
+ }
+ }
+}