diff --git a/src/contentmanager.cpp b/src/contentmanager.cpp index 9517957..6b3eedf 100644 --- a/src/contentmanager.cpp +++ b/src/contentmanager.cpp @@ -107,8 +107,8 @@ void ContentManager::onCustomContextMenu(const QPoint &point) QAction menuCancelBook(gt("cancel-download"), this); QAction menuOpenFolder(gt("open-folder"), this); - if (bookNode->isDownloading()) { - if (bookNode->getDownloadInfo().paused) { + if (DownloadState* download = bookNode->getDownloadState()) { + if (download->getDownloadInfo().paused) { contextMenu.addAction(&menuResumeBook); } else { contextMenu.addAction(&menuPauseBook); diff --git a/src/contentmanagerdelegate.cpp b/src/contentmanagerdelegate.cpp index 4d7583a..6b1b415 100644 --- a/src/contentmanagerdelegate.cpp +++ b/src/contentmanagerdelegate.cpp @@ -177,8 +177,8 @@ void ContentManagerDelegate::paint(QPainter *painter, const QStyleOptionViewItem } QStyleOptionViewItem eOpt = option; if (index.column() == 5) { - if (node->isDownloading()) { - auto downloadInfo = node->getDownloadInfo(); + if (DownloadState* downloadState = node->getDownloadState()) { + auto downloadInfo = downloadState->getDownloadInfo(); showDownloadProgress(painter, r, downloadInfo); } else { @@ -244,8 +244,8 @@ void ContentManagerDelegate::handleLastColumnClicked(const QModelIndex& index, Q int x = r.left(); int w = r.width(); - if (node->isDownloading()) { - if (node->getDownloadInfo().paused) { + if (DownloadState* downloadState = node->getDownloadState()) { + if (downloadState->getDownloadInfo().paused) { if (clickX < (x + w/2)) { KiwixApp::instance()->getContentManager()->cancelBook(id, index); } else { diff --git a/src/contentmanagermodel.cpp b/src/contentmanagermodel.cpp index bab8244..4612a53 100644 --- a/src/contentmanagermodel.cpp +++ b/src/contentmanagermodel.cpp @@ -239,10 +239,10 @@ std::shared_ptr getSharedPointer(RowNode* ptr) void ContentManagerModel::startDownload(QModelIndex index) { auto node = getSharedPointer(static_cast(index.internalPointer())); - node->setIsDownloading(true); // this starts the internal timer - QTimer *timer = node->getDownloadUpdateTimer(); + node->setDownloadState(new DownloadState); + QTimer *timer = node->getDownloadState()->getDownloadUpdateTimer(); connect(timer, &QTimer::timeout, this, [=]() { - node->updateDownloadStatus(node->getBookId()); + node->getDownloadState()->updateDownloadStatus(node->getBookId()); emit dataChanged(index, index); }); } @@ -250,21 +250,21 @@ void ContentManagerModel::startDownload(QModelIndex index) void ContentManagerModel::pauseDownload(QModelIndex index) { auto node = static_cast(index.internalPointer()); - node->pauseDownload(); + node->getDownloadState()->pauseDownload(); emit dataChanged(index, index); } void ContentManagerModel::resumeDownload(QModelIndex index) { auto node = static_cast(index.internalPointer()); - node->resumeDownload(); + node->getDownloadState()->resumeDownload(); emit dataChanged(index, index); } void ContentManagerModel::cancelDownload(QModelIndex index) { auto node = static_cast(index.internalPointer()); - node->setIsDownloading(false); // this stops & deletes the timer + node->setDownloadState(nullptr); emit dataChanged(index, index); } diff --git a/src/rownode.cpp b/src/rownode.cpp index 39374fb..e11a104 100644 --- a/src/rownode.cpp +++ b/src/rownode.cpp @@ -10,24 +10,8 @@ DownloadState::DownloadState() : m_downloadInfo({0, "", "", false}) { -} - -void DownloadState::setIsDownloading(bool val) -{ - assert(val != isDownloading()); - if ( val ) { - m_downloadUpdateTimer.reset(new QTimer); - m_downloadUpdateTimer->start(1000); - } else { - m_downloadUpdateTimer->stop(); - - // Deleting the timer object immediately instead of via - // QObject::deleteLater() seems to be safe since it is not a recipient - // of any events that may be in the process of being delivered to it - // from another thread. - m_downloadUpdateTimer.reset(); - m_downloadInfo = {0, "", "", false}; - } + m_downloadUpdateTimer.reset(new QTimer); + m_downloadUpdateTimer->start(1000); } namespace @@ -59,7 +43,14 @@ void DownloadState::updateDownloadStatus(QString id) auto downloadSpeed = convertToUnits(downloadInfos["downloadSpeed"].toString()) + "/s"; m_downloadInfo = {percent, completedLength, downloadSpeed, false}; if (!downloadInfos["status"].isValid()) { - setIsDownloading(false); // this stops & deletes the timer + m_downloadUpdateTimer->stop(); + + // Deleting the timer object immediately instead of via + // QObject::deleteLater() seems to be safe since it is not a recipient + // of any events that may be in the process of being delivered to it + // from another thread. + m_downloadUpdateTimer.reset(); + m_downloadInfo = {0, "", "", false}; } } @@ -150,3 +141,8 @@ bool RowNode::isChild(Node *candidate) } return false; } + +void RowNode::setDownloadState(DownloadState* ds) +{ + m_downloadState.reset(ds); +} diff --git a/src/rownode.h b/src/rownode.h index c07a4c8..defbc2e 100644 --- a/src/rownode.h +++ b/src/rownode.h @@ -22,7 +22,6 @@ public: bool isDownloading() const { return m_downloadUpdateTimer.get() != nullptr; } DownloadInfo getDownloadInfo() const { return m_downloadInfo; } QTimer* getDownloadUpdateTimer() const { return m_downloadUpdateTimer.get(); } - void setIsDownloading(bool val); void pauseDownload(); void resumeDownload(); void updateDownloadStatus(QString id); @@ -34,7 +33,7 @@ protected: DownloadInfo m_downloadInfo; }; -class RowNode : public Node, public DownloadState +class RowNode : public Node { public: explicit RowNode(QList itemData, QString bookId, std::weak_ptr parentItem); @@ -50,11 +49,16 @@ public: void setIconData(QByteArray iconData) { m_itemData[0] = iconData; } bool isChild(Node* candidate); + + void setDownloadState(DownloadState* ds); + DownloadState* getDownloadState() { return m_downloadState.get(); } + private: QList m_itemData; QList> m_childItems; std::weak_ptr m_parentItem; QString m_bookId; + std::unique_ptr m_downloadState; };