2023-06-02 22:56:30 +02:00
|
|
|
// Copyright (C) 2023 The Qt Company Ltd.
|
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
|
|
|
|
|
|
#include "imagescaling.h"
|
|
|
|
|
#include "downloaddialog.h"
|
2023-06-03 01:34:32 +02:00
|
|
|
#include <tasking/concurrentcall.h>
|
|
|
|
|
#include <tasking/networkquery.h>
|
2023-06-02 22:56:30 +02:00
|
|
|
|
2023-06-03 01:34:32 +02:00
|
|
|
using namespace Tasking;
|
2023-06-02 22:56:30 +02:00
|
|
|
|
|
|
|
|
Images::Images(QWidget *parent) : QWidget(parent), downloadDialog(new DownloadDialog(this))
|
|
|
|
|
{
|
|
|
|
|
resize(800, 600);
|
|
|
|
|
|
2023-06-03 01:34:32 +02:00
|
|
|
QPushButton *addUrlsButton = new QPushButton(tr("Add URLs"));
|
2023-06-02 22:56:30 +02:00
|
|
|
connect(addUrlsButton, &QPushButton::clicked, this, &Images::process);
|
|
|
|
|
|
|
|
|
|
cancelButton = new QPushButton(tr("Cancel"));
|
|
|
|
|
cancelButton->setEnabled(false);
|
2023-06-03 01:34:32 +02:00
|
|
|
connect(cancelButton, &QPushButton::clicked, this, [this] {
|
|
|
|
|
statusBar->showMessage(tr("Canceled."));
|
2024-01-13 20:10:30 +01:00
|
|
|
taskTreeRunner.reset();
|
2023-06-03 01:34:32 +02:00
|
|
|
});
|
2023-06-02 22:56:30 +02:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 01:34:32 +02:00
|
|
|
static void scale(QPromise<QImage> &promise, const QByteArray &data)
|
2023-06-02 22:56:30 +02:00
|
|
|
{
|
2023-06-03 01:34:32 +02:00
|
|
|
const auto image = QImage::fromData(data);
|
|
|
|
|
if (image.isNull())
|
|
|
|
|
promise.future().cancel();
|
|
|
|
|
else
|
|
|
|
|
promise.addResult(image.scaled(100, 100, Qt::KeepAspectRatio));
|
2023-06-02 22:56:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Images::process()
|
|
|
|
|
{
|
2023-06-03 01:34:32 +02:00
|
|
|
if (downloadDialog->exec() != QDialog::Accepted)
|
|
|
|
|
return;
|
2023-06-02 22:56:30 +02:00
|
|
|
|
2023-06-03 01:34:32 +02:00
|
|
|
const auto urls = downloadDialog->getUrls();
|
|
|
|
|
initLayout(urls.size());
|
2023-06-02 22:56:30 +02:00
|
|
|
|
2024-01-10 20:27:33 +01:00
|
|
|
const LoopRepeat repeater(urls.size());
|
2024-01-10 21:48:27 +01:00
|
|
|
const Storage<QByteArray> storage;
|
2024-01-10 00:46:56 +01:00
|
|
|
|
2023-06-03 01:34:32 +02:00
|
|
|
const auto onRootSetup = [this] {
|
|
|
|
|
statusBar->showMessage(tr("Downloading and Scaling..."));
|
2023-06-02 22:56:30 +02:00
|
|
|
cancelButton->setEnabled(true);
|
2023-06-03 01:34:32 +02:00
|
|
|
};
|
|
|
|
|
const auto onRootDone = [this] {
|
|
|
|
|
statusBar->showMessage(tr("Finished."));
|
|
|
|
|
cancelButton->setEnabled(false);
|
|
|
|
|
};
|
2024-01-10 00:46:56 +01:00
|
|
|
|
2024-01-10 21:48:27 +01:00
|
|
|
const auto onDownloadSetup = [this, urls, repeater](NetworkQuery &query) {
|
2024-01-10 00:46:56 +01:00
|
|
|
query.setNetworkAccessManager(&qnam);
|
2024-01-10 21:48:27 +01:00
|
|
|
query.setRequest(QNetworkRequest(urls.at(repeater.iteration())));
|
2024-01-10 00:46:56 +01:00
|
|
|
};
|
2024-01-10 21:48:27 +01:00
|
|
|
const auto onDownloadDone = [this, storage, repeater](const NetworkQuery &query,
|
2024-01-10 00:46:56 +01:00
|
|
|
DoneWith result) {
|
|
|
|
|
const int it = repeater.iteration();
|
|
|
|
|
if (result == DoneWith::Success)
|
2024-01-10 21:48:27 +01:00
|
|
|
*storage = query.reply()->readAll();
|
2024-01-10 00:46:56 +01:00
|
|
|
else
|
|
|
|
|
labels[it]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error()));
|
|
|
|
|
};
|
|
|
|
|
|
2024-01-10 21:48:27 +01:00
|
|
|
const auto onScalingSetup = [storage](ConcurrentCall<QImage> &data) {
|
|
|
|
|
data.setConcurrentCallData(&scale, *storage);
|
2024-01-10 00:46:56 +01:00
|
|
|
};
|
|
|
|
|
const auto onScalingDone = [this, repeater](const ConcurrentCall<QImage> &data,
|
|
|
|
|
DoneWith result) {
|
|
|
|
|
const int it = repeater.iteration();
|
|
|
|
|
if (result == DoneWith::Success)
|
|
|
|
|
labels[it]->setPixmap(QPixmap::fromImage(data.result()));
|
|
|
|
|
else
|
|
|
|
|
labels[it]->setText(tr("Image\nData\nError."));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const QList<GroupItem> tasks {
|
2023-11-04 12:44:19 +01:00
|
|
|
finishAllAndSuccess,
|
2023-06-03 01:34:32 +02:00
|
|
|
parallel,
|
2024-01-10 00:46:56 +01:00
|
|
|
repeater,
|
2023-06-03 01:34:32 +02:00
|
|
|
onGroupSetup(onRootSetup),
|
2024-01-10 00:46:56 +01:00
|
|
|
Group {
|
2024-01-10 21:48:27 +01:00
|
|
|
storage,
|
2023-11-02 16:14:50 +01:00
|
|
|
NetworkQueryTask(onDownloadSetup, onDownloadDone),
|
|
|
|
|
ConcurrentCallTask<QImage>(onScalingSetup, onScalingDone)
|
2024-01-10 00:46:56 +01:00
|
|
|
},
|
|
|
|
|
onGroupDone(onRootDone, CallDoneIf::Success)
|
|
|
|
|
};
|
2023-06-02 22:56:30 +02:00
|
|
|
|
2024-01-13 20:10:30 +01:00
|
|
|
taskTreeRunner.start(tasks);
|
2023-06-02 22:56:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
2023-06-03 01:34:32 +02:00
|
|
|
imageLabel->setAlignment(Qt::AlignCenter);
|
2023-06-02 22:56:30 +02:00
|
|
|
imagesLayout->addWidget(imageLabel, i, j);
|
|
|
|
|
labels.append(imageLabel);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|