TaskTree: Introduce DoneWith enum

This makes it possible to recognize the cancel state
when the task was automatically stopped because of task's
parent group workflow policy or when the user called TaskTree::stop().

This addresses the 2nd point in the master task below.

Task-number: QTCREATORBUG-28741
Task-number: QTCREATORBUG-29834
Change-Id: I2798b9ec1d2f1d667aff51ee0271a5a15a525dc1
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2023-11-03 09:42:55 +01:00
parent 84edd54699
commit dda75153fe
22 changed files with 104 additions and 94 deletions

View File

@@ -1088,7 +1088,7 @@ public:
// in order to unwind properly.
SetupResult start();
void stop();
bool invokeDoneHandler(bool success);
bool invokeDoneHandler(DoneWith result);
bool isRunning() const { return m_task || m_container.isRunning(); }
bool isTask() const { return bool(m_taskHandler.m_createHandler); }
int taskCount() const { return isTask() ? 1 : m_container.m_constData.m_taskCount; }
@@ -1450,7 +1450,7 @@ SetupResult TaskNode::start()
const std::shared_ptr<SetupResult> unwindAction
= std::make_shared<SetupResult>(SetupResult::Continue);
QObject::connect(m_task.get(), &TaskInterface::done, taskTree(), [=](bool success) {
const bool result = invokeDoneHandler(success);
const bool result = invokeDoneHandler(success ? DoneWith::Success : DoneWith::Error);
QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr);
m_task.release()->deleteLater();
QTC_ASSERT(parentContainer() && parentContainer()->isRunning(), return);
@@ -1478,24 +1478,24 @@ void TaskNode::stop()
// TODO: cancelHandler?
// TODO: call TaskInterface::stop() ?
invokeDoneHandler(false);
invokeDoneHandler(DoneWith::Cancel);
m_task.reset();
}
static bool shouldCall(CallDoneIf callDoneIf, bool success)
static bool shouldCall(CallDoneIf callDoneIf, DoneWith result)
{
if (success)
if (result == DoneWith::Success)
return callDoneIf != CallDoneIf::Error;
return callDoneIf != CallDoneIf::Success;
}
bool TaskNode::invokeDoneHandler(bool success)
bool TaskNode::invokeDoneHandler(DoneWith result)
{
bool result = success;
if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, success))
result = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), success);
bool success = result == DoneWith::Success;
if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, result))
success = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), result);
m_container.m_constData.m_taskTreePrivate->advanceProgress(1);
return result;
return success;
}
/*!

View File

@@ -132,6 +132,14 @@ enum class SetupResult
};
Q_ENUM_NS(SetupResult);
enum class DoneWith
{
Success,
Error,
Cancel
};
Q_ENUM_NS(DoneWith);
enum class CallDoneIf
{
SuccessOrError,
@@ -148,7 +156,7 @@ public:
// Called prior to task start, just after createHandler
using TaskSetupHandler = std::function<SetupResult(TaskInterface &)>;
// Called on task done, just before deleteLater
using TaskDoneHandler = std::function<bool(const TaskInterface &, bool)>;
using TaskDoneHandler = std::function<bool(const TaskInterface &, DoneWith)>;
// Called when group entered
using GroupSetupHandler = std::function<SetupResult()>;
// Called when group done / error
@@ -335,7 +343,7 @@ public:
"The Adapter type for the CustomTask<Adapter> needs to be derived from "
"TaskAdapter<Task>.");
using SetupFunction = std::function<void(const Task &)>;
using DoneFunction = std::function<bool(const Task &, bool)>;
using DoneFunction = std::function<bool(const Task &, DoneWith)>;
static Adapter *createAdapter() { return new Adapter; }
template <typename SetupHandler = SetupFunction, typename DoneHandler = DoneFunction>
@@ -376,37 +384,38 @@ private:
if constexpr (std::is_same_v<Handler, DoneFunction>)
return {}; // When user passed {} for the done handler.
static constexpr bool is2ArgDynamic
= std::is_invocable_r_v<bool, std::decay_t<Handler>, const Task &, bool>;
= std::is_invocable_r_v<bool, std::decay_t<Handler>, const Task &, DoneWith>;
static constexpr bool is1ArgDynamic
= std::is_invocable_r_v<bool, std::decay_t<Handler>, const Task &>;
static constexpr bool is0ArgDynamic
= std::is_invocable_r_v<bool, std::decay_t<Handler>>;
static constexpr bool is2ArgVoid
= std::is_invocable_r_v<void, std::decay_t<Handler>, const Task &, bool>;
= std::is_invocable_r_v<void, std::decay_t<Handler>, const Task &, DoneWith>;
static constexpr bool is1ArgVoid
= std::is_invocable_r_v<void, std::decay_t<Handler>, const Task &>;
static constexpr bool is0ArgVoid
= std::is_invocable_r_v<void, std::decay_t<Handler>>;
static constexpr bool isInvocable = is2ArgDynamic || is1ArgDynamic || is0ArgDynamic
|| is2ArgVoid || is1ArgVoid || is0ArgVoid;
static constexpr bool isInvocable = is2ArgDynamic || is2ArgVoid
|| is1ArgDynamic || is1ArgVoid
|| is0ArgDynamic || is0ArgVoid;
static_assert(isInvocable,
"Task done handler needs to take (const Task &, bool) as arguments (optionally) and "
"has to return void or bool. The passed handler doesn't fulfill these requirements.");
return [=](const TaskInterface &taskInterface, bool success) {
return [=](const TaskInterface &taskInterface, DoneWith result) {
const Adapter &adapter = static_cast<const Adapter &>(taskInterface);
if constexpr (is2ArgDynamic)
return std::invoke(handler, *adapter.task(), success);
return std::invoke(handler, *adapter.task(), result);
if constexpr (is1ArgDynamic)
return std::invoke(handler, *adapter.task());
if constexpr (is0ArgDynamic)
return std::invoke(handler);
if constexpr (is2ArgVoid)
std::invoke(handler, *adapter.task(), success);
std::invoke(handler, *adapter.task(), result);
else if constexpr (is1ArgVoid)
std::invoke(handler, *adapter.task());
else if constexpr (is0ArgVoid)
std::invoke(handler);
return success;
return result == DoneWith::Success;
};
};
};

View File

@@ -130,11 +130,11 @@ void AndroidSdkDownloader::downloadAndExtractSdk()
#endif
});
};
const auto onQueryDone = [this, storage](const NetworkQuery &query, bool success) {
const auto onQueryDone = [this, storage](const NetworkQuery &query, DoneWith result) {
QNetworkReply *reply = query.reply();
QTC_ASSERT(reply, return);
const QUrl url = reply->url();
if (!success) {
if (result != DoneWith::Success) {
logError(Tr::tr("Downloading Android SDK Tools from URL %1 has failed: %2.")
.arg(url.toString(), reply->errorString()));
return;
@@ -171,8 +171,8 @@ void AndroidSdkDownloader::downloadAndExtractSdk()
unarchiver.setDestDir(sdkFileName.parentDir());
return SetupResult::Continue;
};
const auto onUnarchiverDone = [this, storage](const Unarchiver &, bool success) {
if (!success) {
const auto onUnarchiverDone = [this, storage](const Unarchiver &, DoneWith result) {
if (result != DoneWith::Success) {
logError(Tr::tr("Unarchiving error."));
return;
}

View File

@@ -55,8 +55,8 @@ private:
handleStdErrData(proc->readAllStandardError());
});
};
const auto onDone = [this](const Process &process, bool success) {
if (!success)
const auto onDone = [this](const Process &process, DoneWith result) {
if (result != DoneWith::Success)
addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString()));
else if (selection() == 0)
addProgressMessage(Tr::tr("Application set as the default one."));

View File

@@ -54,8 +54,8 @@ GroupItem QdbStopApplicationStep::deployRecipe()
});
return SetupResult::Continue;
};
const auto onDone = [this](const Process &process, bool success) {
if (success) {
const auto onDone = [this](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
addProgressMessage(Tr::tr("Stopped the running application."));
return;
}

View File

@@ -163,12 +163,12 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
qCDebug(LOG).noquote() << "Starting" << commandLine.toUserOutput();
process.setCommand(commandLine);
};
const auto onProcessDone = [=](const Process &process, bool success) {
const auto onProcessDone = [=](const Process &process, DoneWith result) {
qCDebug(LOG).noquote() << "Output:\n" << process.cleanedStdOut();
if (!outputHandler)
return;
if (success) {
if (result == DoneWith::Success) {
const QString stdErr = process.cleanedStdErr();
if (stdErr.isEmpty())
return;
@@ -198,17 +198,17 @@ GroupItem clangToolTask(const AnalyzeInputData &input,
input.diagnosticsFilter);
data.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
};
const auto onReadDone = [=](const Async<expected_str<Diagnostics>> &data, bool success) {
const auto onReadDone = [=](const Async<expected_str<Diagnostics>> &data, DoneWith result) {
if (!outputHandler)
return;
const expected_str<Diagnostics> result = data.result();
const bool ok = success && result.has_value();
const expected_str<Diagnostics> diagnosticsResult = data.result();
const bool ok = result == DoneWith::Success && diagnosticsResult.has_value();
Diagnostics diagnostics;
QString error;
if (ok)
diagnostics = *result;
diagnostics = *diagnosticsResult;
else
error = result.error();
error = diagnosticsResult.error();
outputHandler({ok,
input.unit.file,
storage->outputFilePath,

View File

@@ -394,8 +394,8 @@ LocatorMatcherTasks JavaScriptFilter::matchers()
request.setEngine(engine);
request.setEvaluateData(storage->input());
};
const auto onJavaScriptDone = [storage](const JavaScriptRequest &request, bool success) {
if (!success) {
const auto onJavaScriptDone = [storage](const JavaScriptRequest &request, DoneWith result) {
if (result != DoneWith::Success) {
LocatorFilterEntry entry;
entry.displayName = request.output().m_output;
storage->reportOutput({entry});
@@ -408,15 +408,15 @@ LocatorMatcherTasks JavaScriptFilter::matchers()
};
};
const QString input = storage->input();
const QString result = request.output().m_output;
const QString expression = input + " = " + result;
const QString output = request.output().m_output;
const QString expression = input + " = " + output;
LocatorFilterEntry entry;
entry.displayName = expression;
LocatorFilterEntry copyResultEntry;
copyResultEntry.displayName = Tr::tr("Copy to clipboard: %1").arg(result);
copyResultEntry.acceptor = acceptor(result);
copyResultEntry.displayName = Tr::tr("Copy to clipboard: %1").arg(output);
copyResultEntry.acceptor = acceptor(output);
LocatorFilterEntry copyExpressionEntry;
copyExpressionEntry.displayName = Tr::tr("Copy to clipboard: %1").arg(expression);

View File

@@ -429,8 +429,8 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError)
};
const auto onForEachRefDone = [this, workingDirectory, showError](const Process &process,
bool success) {
if (!success) {
DoneWith result) {
if (result != DoneWith::Success) {
if (showError == ShowError::No)
return;
const QString message = Tr::tr("Cannot run \"%1\" in \"%2\": %3")

View File

@@ -423,10 +423,10 @@ ShowController::ShowController(IDocument *document, const QString &id)
setupCommand(process, {"branch", noColorOption, "-a", "--contains", storage->m_commit});
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
};
const auto onBranchesDone = [storage, updateDescription](const Process &process, bool success) {
const auto onBranchesDone = [storage, updateDescription](const Process &process, DoneWith result) {
ReloadStorage *data = storage.activeStorage();
data->m_branches.clear();
if (success) {
if (result == DoneWith::Success) {
const QString remotePrefix = "remotes/";
const QString localPrefix = "<Local>";
const int prefixLength = remotePrefix.length();
@@ -469,10 +469,10 @@ ShowController::ShowController(IDocument *document, const QString &id)
storage->m_precedes = busyMessage;
setupCommand(process, {"describe", "--contains", storage->m_commit});
};
const auto onPrecedesDone = [storage, updateDescription](const Process &process, bool success) {
const auto onPrecedesDone = [storage, updateDescription](const Process &process, DoneWith result) {
ReloadStorage *data = storage.activeStorage();
data->m_precedes.clear();
if (success) {
if (result == DoneWith::Success) {
data->m_precedes = process.cleanedStdOut().trimmed();
const int tilde = data->m_precedes.indexOf('~');
if (tilde != -1)

View File

@@ -52,8 +52,8 @@ private:
streamer.setDestination(m_target);
return SetupResult::Continue;
};
const auto onDone = [this](const FileStreamer &, bool success) {
if (success)
const auto onDone = [this](const FileStreamer &, DoneWith result) {
if (result == DoneWith::Success)
addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage);
else
addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage);

View File

@@ -124,8 +124,8 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask()
.arg(fullRemoteDirectory()));
process.setCommand({m_device->filePath("test"), {"-d", fullRemoteDirectory()}});
};
const auto onDone = [this](const Process &process, bool success) {
if (!success) {
const auto onDone = [this](const Process &process, DoneWith result) {
if (result != DoneWith::Success) {
if (process.result() != ProcessResult::FinishedWithError) {
m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1")
.arg(process.errorString()));

View File

@@ -51,8 +51,8 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device)
{"-c", QLatin1String("rm %1 > /dev/null 2>&1; echo ABC > %1 && rm %1").arg(pidFile)});
process.setCommand(cmd);
};
auto onDone = [this](const Process &process, bool success) {
if (success) {
auto onDone = [this](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n');
return;
}

View File

@@ -37,8 +37,8 @@ void Slog2InfoRunner::start()
const auto onTestSetup = [this](Process &process) {
process.setCommand({device()->filePath("slog2info"), {}});
};
const auto onTestDone = [this](const Process &, bool success) {
if (success) {
const auto onTestDone = [this](const Process &, DoneWith result) {
if (result == DoneWith::Success) {
m_found = true;
return;
}

View File

@@ -65,8 +65,8 @@ GroupItem CustomCommandDeployStep::deployRecipe()
handleStdErrData(proc->readAllStandardError());
});
};
const auto onDone = [this](const Process &process, bool success) {
if (success) {
const auto onDone = [this](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
addProgressMessage(Tr::tr("Remote command finished successfully."));
} else if (process.error() != QProcess::UnknownError
|| process.exitStatus() != QProcess::NormalExit) {

View File

@@ -55,10 +55,9 @@ GroupItem KillAppStep::deployRecipe()
.arg(m_remoteExecutable.path()));
return SetupResult::Continue;
};
const auto onDone = [this](const DeviceProcessKiller &, bool success) {
const QString message = success ? Tr::tr("Remote application killed.")
: Tr::tr("Failed to kill remote application. "
"Assuming it was not running.");
const auto onDone = [this](const DeviceProcessKiller &, DoneWith result) {
const QString message = result == DoneWith::Success ? Tr::tr("Remote application killed.")
: Tr::tr("Failed to kill remote application. Assuming it was not running.");
addProgressMessage(message);
};
return DeviceProcessKillerTask(onSetup, onDone);

View File

@@ -96,8 +96,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::echoTask(const QString &contents) con
emit q->progressMessage(Tr::tr("Sending echo to device..."));
process.setCommand({m_device->filePath("echo"), {contents}});
};
const auto onDone = [this, contents](const Process &process, bool success) {
if (!success) {
const auto onDone = [this, contents](const Process &process, DoneWith result) {
if (result != DoneWith::Success) {
const QString stdErrOutput = process.cleanedStdErr();
if (!stdErrOutput.isEmpty())
emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n');
@@ -123,8 +123,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const
emit q->progressMessage(Tr::tr("Checking kernel version..."));
process.setCommand({m_device->filePath("uname"), {"-rsm"}});
};
const auto onDone = [this](const Process &process, bool success) {
if (success) {
const auto onDone = [this](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
emit q->progressMessage(process.cleanedStdOut());
return;
}
@@ -146,8 +146,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const
emit q->progressMessage(Tr::tr("Checking if specified ports are available..."));
gatherer.setDevice(m_device);
};
const auto onDone = [this](const DeviceUsedPortsGatherer &gatherer, bool success) {
if (!success) {
const auto onDone = [this](const DeviceUsedPortsGatherer &gatherer, DoneWith result) {
if (result != DoneWith::Success) {
emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n'
+ Tr::tr("Some tools will not work out of the box.\n"));
} else if (gatherer.usedPorts().isEmpty()) {
@@ -176,9 +176,9 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho
transfer.setTransferMethod(method);
transfer.setTestDevice(m_device);
};
const auto onDone = [this, method, storage](const FileTransfer &transfer, bool success) {
const auto onDone = [this, method, storage](const FileTransfer &transfer, DoneWith result) {
const QString methodName = FileTransfer::transferMethodName(method);
if (success) {
if (result == DoneWith::Success) {
emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName));
if (method == FileTransferMethod::Rsync)
m_device->setExtraData(Constants::SUPPORTS_RSYNC, true);
@@ -247,8 +247,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandNam
command.addArgs(QLatin1String("\"command -v %1\"").arg(commandName), CommandLine::Raw);
process.setCommand(command);
};
const auto onDone = [this, commandName](const Process &process, bool success) {
if (success) {
const auto onDone = [this, commandName](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
emit q->progressMessage(Tr::tr("%1 found.").arg(commandName));
return;
}

View File

@@ -153,8 +153,8 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe()
async.setFutureSynchronizer(&m_synchronizer);
return SetupResult::Continue;
};
const auto onDone = [this](const Async<void> &, bool success) {
if (!success) {
const auto onDone = [this](const Async<void> &, DoneWith result) {
if (result != DoneWith::Success) {
emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage);
return;
}

View File

@@ -74,8 +74,8 @@ GroupItem TarPackageDeployStep::uploadTask()
connect(&transfer, &FileTransfer::progress, this, &TarPackageDeployStep::addProgressMessage);
addProgressMessage(Tr::tr("Uploading package to device..."));
};
const auto onDone = [this](const FileTransfer &transfer, bool success) {
if (success)
const auto onDone = [this](const FileTransfer &transfer, DoneWith result) {
if (result == DoneWith::Success)
addProgressMessage(Tr::tr("Successfully uploaded package file."));
else
addErrorMessage(transfer.resultData().m_errorString);
@@ -98,8 +98,8 @@ GroupItem TarPackageDeployStep::installTask()
});
addProgressMessage(Tr::tr("Installing package to device..."));
};
const auto onDone = [this](const Process &process, bool success) {
if (success) {
const auto onDone = [this](const Process &process, DoneWith result) {
if (result == DoneWith::Success) {
saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {});
addProgressMessage(Tr::tr("Successfully installed package file."));
return;

View File

@@ -175,8 +175,8 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume
setDescription(Tr::tr("Waiting for data..."));
return SetupResult::Continue;
};
const auto onDescriptionDone = [this](const Process &process, bool success) {
setDescription(success ? process.cleanedStdOut() : QString());
const auto onDescriptionDone = [this](const Process &process, DoneWith result) {
setDescription(result == DoneWith::Success ? process.cleanedStdOut() : QString());
};
const auto onDiffSetup = [this](Process &process) {

View File

@@ -44,8 +44,9 @@ GroupItem VcsBaseDiffEditorController::postProcessTask(const TreeStorage<QString
async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
async.setConcurrentCallData(&DiffUtils::readPatchWithPromise, *inputStorage);
};
const auto onDone = [this](const Async<QList<FileData>> &async, bool success) {
setDiffFiles(success && async.isResultAvailable() ? async.result() : QList<FileData>());
const auto onDone = [this](const Async<QList<FileData>> &async, DoneWith result) {
setDiffFiles(result == DoneWith::Success && async.isResultAvailable()
? async.result() : QList<FileData>());
// TODO: We should set the right starting line here
};
return AsyncTask<QList<FileData>>(onSetup, onDone);

View File

@@ -77,12 +77,12 @@ void tst_Tasking::validConstructs()
{
const Group task {
parallel,
TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}),
TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}),
TestTask([](TaskObject &) {}, [](const TaskObject &) {}),
TestTask([](TaskObject &) {}, [] {}),
TestTask([](TaskObject &) {}, {}),
TestTask([](TaskObject &) {}),
TestTask({}, [](const TaskObject &, bool) {}),
TestTask({}, [](const TaskObject &, DoneWith) {}),
TestTask({}, [](const TaskObject &) {}),
TestTask({}, [] {}),
TestTask({}, {}),
@@ -97,7 +97,7 @@ void tst_Tasking::validConstructs()
parallel,
Group {
parallel,
TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}),
TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}),
Group {
parallel,
TestTask([](TaskObject &) {}, [](const TaskObject &) {}),
@@ -108,7 +108,7 @@ void tst_Tasking::validConstructs()
},
Group {
parallel,
TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}),
TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}),
onGroupDone([] {})
}
},
@@ -120,7 +120,7 @@ void tst_Tasking::validConstructs()
const auto setupHandler = [](TaskObject &) {};
const auto finishHandler = [](const TaskObject &) {};
const auto errorHandler = [](const TaskObject &) {};
const auto doneHandler = [](const TaskObject &, bool) {};
const auto doneHandler = [](const TaskObject &, DoneWith) {};
const Group task2 {
parallel,
@@ -230,10 +230,11 @@ void tst_Tasking::testTree_data()
};
};
const auto setupDone = [storage](int taskId, bool successTask = true) {
return [storage, taskId, successTask](const TaskObject &, bool success) {
storage->m_log.append({taskId, successTask && success ? Handler::Done : Handler::Error});
return successTask && success;
const auto setupDone = [storage](int taskId, bool success = true) {
return [storage, taskId, success](const TaskObject &, DoneWith result) {
const bool done = success && result != DoneWith::Cancel;
storage->m_log.append({taskId, done ? Handler::Done : Handler::Error});
return done;
};
};

View File

@@ -79,8 +79,8 @@ void Images::process()
query.setNetworkAccessManager(&qnam);
query.setRequest(QNetworkRequest(url));
};
const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, bool success) {
if (success)
const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, DoneWith result) {
if (result == DoneWith::Success)
*storage = query.reply()->readAll();
else
labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error()));
@@ -89,8 +89,8 @@ void Images::process()
const auto onScalingSetup = [storage](ConcurrentCall<QImage> &data) {
data.setConcurrentCallData(&scale, *storage);
};
const auto onScalingDone = [this, i](const ConcurrentCall<QImage> &data, bool success) {
if (success)
const auto onScalingDone = [this, i](const ConcurrentCall<QImage> &data, DoneWith result) {
if (result == DoneWith::Success)
labels[i]->setPixmap(QPixmap::fromImage(data.result()));
else
labels[i]->setText(tr("Image\nData\nError."));