fix(export): cancel QFuture on exit

This commit is contained in:
uncor3
2026-04-04 18:52:41 +03:00
parent 09a483aefa
commit 19b1cc56bd
2 changed files with 57 additions and 34 deletions
+50 -34
View File
@@ -75,48 +75,54 @@ ExportAlbum::ExportAlbum(const std::shared_ptr<iDescriptorDevice> device,
void ExportAlbum::getTotalPhotoCount(const QStringList &paths)
{
QFutureWatcher<std::pair<bool, size_t>> *watcher =
new QFutureWatcher<std::pair<bool, size_t>>(this);
connect(watcher, &QFutureWatcher<std::pair<bool, size_t>>::finished, this,
[this, watcher]() {
std::pair<bool, size_t> result = watcher->result();
qDebug() << "Total photo count:" << result.second << "with"
<< (result.first ? 0 : 1) << "errors";
m_watcher = new QFutureWatcher<ScanResult>(this);
if (result.first) {
updateInfoLabel(result.second);
calculateTotalExportSize();
m_loadingWidget->stop();
} else {
QMessageBox::warning(
nullptr, "Error",
"Failed to read directory: cannot export album(s)");
reject();
}
});
connect(m_watcher, &QFutureWatcher<ScanResult>::finished, this, [this]() {
ScanResult result = m_watcher->result();
qDebug() << "Total photo count:" << result.count << "with"
<< (result.ok ? 0 : 1) << "errors";
if (result.ok) {
m_exportItems = std::move(result.items);
updateInfoLabel(result.count);
calculateTotalExportSize();
m_loadingWidget->stop();
} else {
QMessageBox::warning(
nullptr, "Error",
"Failed to read directory: cannot export album(s)");
reject();
}
m_watcher->deleteLater();
m_watcher = nullptr;
});
// FIXME: if a dir returns empty, it could be an error or just an empty
// dir, we should check that
m_watcher->setFuture(QtConcurrent::run([device = m_device,
paths]() -> ScanResult {
ScanResult res{true, 0, {}};
watcher->setFuture(QtConcurrent::run([this, paths]() {
size_t count = 0;
bool errorOccurred = false;
// FIXME: if a dir returns empty, it could be an error or just an empty
// dir, we should check that
for (const QString &path : paths) {
QList<QString> items = m_device->afc_backend->list_files_flat(path);
QList<QString> items = device->afc_backend->list_files_flat(path);
if (items.isEmpty()) {
errorOccurred = true;
} else {
for (const QString &item : items) {
if (item.isEmpty()) {
continue;
}
m_exportItems.append(item);
}
count += items.size();
res.ok = false;
continue;
}
for (const QString &item : items) {
if (item.isEmpty())
continue;
res.items.append(item);
}
res.count += items.size();
}
return std::make_pair(!errorOccurred, count);
qDebug() << "[m_watcher] Finished scanning albums, total items found:"
<< res.count;
return res;
}));
}
@@ -178,4 +184,14 @@ void ExportAlbum::calculateTotalExportSize()
},
Qt::QueuedConnection);
});
}
ExportAlbum::~ExportAlbum()
{
if (m_watcher) {
qDebug() << "Cancelling ongoing scan in ExportAlbum destructor";
m_watcher->cancel();
// m_watcher->waitForFinished();
m_watcher->deleteLater();
}
}
+7
View File
@@ -14,14 +14,21 @@
#include <QtConcurrent>
#include <atomic>
struct ScanResult {
bool ok;
size_t count;
QStringList items;
};
class ExportAlbum : public QDialog
{
Q_OBJECT
public:
explicit ExportAlbum(const std::shared_ptr<iDescriptorDevice> device,
const QStringList &paths, QWidget *parent = nullptr);
~ExportAlbum();
private:
QFutureWatcher<ScanResult> *m_watcher = nullptr;
ZLoadingWidget *m_loadingWidget;
const std::shared_ptr<iDescriptorDevice> m_device;
QLabel *m_infoLabel;