2-stage asynchronous cancelling of downloads

This commit is contained in:
Veloman Yunkan 2024-06-07 17:08:54 +04:00 committed by Kelson
parent 262428e637
commit d0a8f2519b
4 changed files with 19 additions and 15 deletions

View File

@ -101,6 +101,9 @@ ContentManager::ContentManager(Library* library, kiwix::Downloader* downloader)
connect(this, &DownloadManager::downloadUpdated, connect(this, &DownloadManager::downloadUpdated,
this, &ContentManager::updateDownload); this, &ContentManager::updateDownload);
connect(this, &DownloadManager::downloadCancelled,
this, &ContentManager::downloadWasCancelled);
connect(this, &DownloadManager::downloadDisappeared, connect(this, &DownloadManager::downloadDisappeared,
this, &ContentManager::downloadDisappeared); this, &ContentManager::downloadDisappeared);
@ -641,15 +644,12 @@ void ContentManager::cancelBook(const QString& id)
auto text = gt("cancel-download-text"); auto text = gt("cancel-download-text");
text = text.replace("{{ZIM}}", QString::fromStdString(mp_library->getBookById(id).getTitle())); text = text.replace("{{ZIM}}", QString::fromStdString(mp_library->getBookById(id).getTitle()));
showConfirmBox(gt("cancel-download"), text, mp_view, [=]() { showConfirmBox(gt("cancel-download"), text, mp_view, [=]() {
reallyCancelBook(id); DownloadManager::addRequest(DownloadState::CANCEL, id);
}); });
} }
void ContentManager::reallyCancelBook(const QString& id) void ContentManager::downloadWasCancelled(const QString& id)
{ {
if ( !DownloadManager::cancelDownload(id) )
return;
removeDownload(id); removeDownload(id);
// incompleted downloaded file should be perma deleted // incompleted downloaded file should be perma deleted

View File

@ -98,16 +98,14 @@ public slots:
void updateCategories(const QString& content); void updateCategories(const QString& content);
void pauseBook(const QString& id, QModelIndex index); void pauseBook(const QString& id, QModelIndex index);
void resumeBook(const QString& id, QModelIndex index); void resumeBook(const QString& id, QModelIndex index);
// cancelBook() asks for confirmation (reallyCancelBook() doesn't)
void cancelBook(const QString& id); void cancelBook(const QString& id);
void onCustomContextMenu(const QPoint &point); void onCustomContextMenu(const QPoint &point);
void openBookWithIndex(const QModelIndex& index); void openBookWithIndex(const QModelIndex& index);
void updateDownload(QString bookId, const DownloadInfo& downloadInfo); void updateDownload(QString bookId, const DownloadInfo& downloadInfo);
void downloadWasCancelled(const QString& id);
private: // functions private: // functions
QStringList getBookIds(); QStringList getBookIds();
// reallyCancelBook() doesn't ask for confirmation (unlike cancelBook())
void reallyCancelBook(const QString& id);
// reallyEraseBook() doesn't ask for confirmation (unlike eraseBook()) // reallyEraseBook() doesn't ask for confirmation (unlike eraseBook())
void reallyEraseBook(const QString& id, bool moveToTrash); void reallyEraseBook(const QString& id, bool moveToTrash);
void eraseBookFilesFromComputer(const std::string& bookPath, bool moveToTrash); void eraseBookFilesFromComputer(const std::string& bookPath, bool moveToTrash);

View File

@ -84,6 +84,10 @@ void DownloadState::changeState(Action action)
if ( status == PAUSED ) { if ( status == PAUSED ) {
status = RESUME_REQUESTED; status = RESUME_REQUESTED;
} }
} else if ( action == CANCEL ) {
if ( status == DOWNLOADING || status == PAUSED ) {
status = CANCEL_REQUESTED;
}
} }
if ( status != oldStatus ) { if ( status != oldStatus ) {
@ -130,7 +134,7 @@ void DownloadManager::processDownloadActions()
case DownloadState::START: /* startDownload(req.bookId); */ break; // API problem case DownloadState::START: /* startDownload(req.bookId); */ break; // API problem
case DownloadState::PAUSE: pauseDownload(req.bookId); break; case DownloadState::PAUSE: pauseDownload(req.bookId); break;
case DownloadState::RESUME: resumeDownload(req.bookId); break; case DownloadState::RESUME: resumeDownload(req.bookId); break;
case DownloadState::CANCEL: /* cancelDownload(req.bookId); */ break; // API problem case DownloadState::CANCEL: cancelDownload(req.bookId); break;
case DownloadState::UPDATE: updateDownload(req.bookId); break; case DownloadState::UPDATE: updateDownload(req.bookId); break;
} }
} }
@ -322,19 +326,18 @@ void DownloadManager::resumeDownload(const QString& bookId)
} }
} }
bool DownloadManager::cancelDownload(const QString& bookId) void DownloadManager::cancelDownload(const QString& bookId)
{ {
const auto downloadId = mp_library->getBookById(bookId).getDownloadId(); const auto downloadId = mp_library->getBookById(bookId).getDownloadId();
if ( downloadId.empty() ) { if ( downloadId.empty() ) {
// Completion of the download has been detected (and its id was reset) // Completion of the download has been detected (and its id was reset)
// before the confirmation to cancel the download was granted. // before the confirmation to cancel the download was granted.
return false; return;
} }
auto download = mp_downloader->getDownload(downloadId); auto download = mp_downloader->getDownload(downloadId);
try { try {
download->cancelDownload(); download->cancelDownload();
return true;
} catch (const kiwix::AriaError&) { } catch (const kiwix::AriaError&) {
// Download has completed before the cancel request was handled. // Download has completed before the cancel request was handled.
// Most likely the download was already complete at the time // Most likely the download was already complete at the time
@ -342,8 +345,9 @@ bool DownloadManager::cancelDownload(const QString& bookId)
// its completion was not yet detected (and/or handled) by the // its completion was not yet detected (and/or handled) by the
// download updater thread (letting the code pass past the empty // download updater thread (letting the code pass past the empty
// downloadId check above). // downloadId check above).
return false; return;
} }
emit downloadCancelled(bookId);
} }
void DownloadManager::removeDownload(QString bookId) void DownloadManager::removeDownload(QString bookId)

View File

@ -71,7 +71,8 @@ public: // types
DOWNLOADING, DOWNLOADING,
PAUSE_REQUESTED, PAUSE_REQUESTED,
PAUSED, PAUSED,
RESUME_REQUESTED RESUME_REQUESTED,
CANCEL_REQUESTED
}; };
public: // data public: // data
@ -157,7 +158,6 @@ public: // functions
// returns the download id // returns the download id
std::string startDownload(const kiwix::Book& book, const QString& downloadDirPath); std::string startDownload(const kiwix::Book& book, const QString& downloadDirPath);
bool cancelDownload(const QString& bookId);
void removeDownload(QString bookId); void removeDownload(QString bookId);
DownloadStatePtr getDownloadState(QString bookId) const DownloadStatePtr getDownloadState(QString bookId) const
@ -167,6 +167,7 @@ public: // functions
signals: signals:
void downloadUpdated(QString bookId, const DownloadInfo& ); void downloadUpdated(QString bookId, const DownloadInfo& );
void downloadCancelled(QString bookId);
void downloadDisappeared(QString bookId); void downloadDisappeared(QString bookId);
private: // types private: // types
@ -187,6 +188,7 @@ private: // functions
void pauseDownload(const QString& bookId); void pauseDownload(const QString& bookId);
void resumeDownload(const QString& bookId); void resumeDownload(const QString& bookId);
void updateDownload(QString bookId); void updateDownload(QString bookId);
void cancelDownload(const QString& bookId);
private: // data private: // data
const Library* const mp_library; const Library* const mp_library;