From 92af2922c73252f95f21b574b0a5e807a7597302 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (glassez)" Date: Sat, 19 Nov 2022 21:44:15 +0300 Subject: [PATCH] Revert "Use another workaround to update files tree view" This reverts commit 0f82c169362cd2e26c053725d3b8fae3889f1655. --- src/gui/torrentcontentmodel.cpp | 87 ++++++++++++++++++++++++++++++--- src/gui/torrentcontentmodel.h | 4 ++ 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 9357fdc8e..21bbff55d 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -221,7 +221,11 @@ void TorrentContentModel::updateFilesProgress(const QVector &fp) m_rootItem->recalculateProgress(); m_rootItem->recalculateAvailability(); - emit layoutChanged(); + const QVector columns = + { + {TorrentContentModelItem::COL_PROGRESS, TorrentContentModelItem::COL_PROGRESS} + }; + notifySubtreeUpdated(index(0, 0), columns); } void TorrentContentModel::updateFilesPriorities(const QVector &fprio) @@ -235,7 +239,12 @@ void TorrentContentModel::updateFilesPriorities(const QVectorsetPriority(static_cast(fprio[i])); - emit layoutChanged(); + const QVector columns = + { + {TorrentContentModelItem::COL_NAME, TorrentContentModelItem::COL_NAME}, + {TorrentContentModelItem::COL_PRIO, TorrentContentModelItem::COL_PRIO} + }; + notifySubtreeUpdated(index(0, 0), columns); } void TorrentContentModel::updateFilesAvailability(const QVector &fa) @@ -250,7 +259,11 @@ void TorrentContentModel::updateFilesAvailability(const QVector &fa) // Update folders progress in the tree m_rootItem->recalculateProgress(); - emit layoutChanged(); + const QVector columns = + { + {TorrentContentModelItem::COL_AVAILABILITY, TorrentContentModelItem::COL_AVAILABILITY} + }; + notifySubtreeUpdated(index(0, 0), columns); } QVector TorrentContentModel::getFilePriorities() const @@ -295,13 +308,17 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu if (currentPrio != newPrio) { - emit layoutAboutToBeChanged(); item->setPriority(newPrio); // Update folders progress in the tree m_rootItem->recalculateProgress(); m_rootItem->recalculateAvailability(); - emit layoutChanged(); + const QVector columns = + { + {TorrentContentModelItem::COL_NAME, TorrentContentModelItem::COL_NAME}, + {TorrentContentModelItem::COL_PRIO, TorrentContentModelItem::COL_PRIO} + }; + notifySubtreeUpdated(index, columns); emit filteredFilesChanged(); return true; @@ -333,9 +350,14 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu const auto newPrio = static_cast(value.toInt()); if (currentPrio != newPrio) { - emit layoutAboutToBeChanged(); item->setPriority(newPrio); - emit layoutChanged(); + + const QVector columns = + { + {TorrentContentModelItem::COL_NAME, TorrentContentModelItem::COL_NAME}, + {TorrentContentModelItem::COL_PRIO, TorrentContentModelItem::COL_PRIO} + }; + notifySubtreeUpdated(index, columns); if ((newPrio == BitTorrent::DownloadPriority::Ignored) || (currentPrio == BitTorrent::DownloadPriority::Ignored)) @@ -570,3 +592,54 @@ void TorrentContentModel::setupModelData(const BitTorrent::AbstractFileStorage & endResetModel(); } + +void TorrentContentModel::notifySubtreeUpdated(const QModelIndex &index, const QVector &columns) +{ + // For best performance, `columns` entries should be arranged from left to right + + Q_ASSERT(index.isValid()); + + // emit itself + for (const ColumnInterval &column : columns) + emit dataChanged(index.siblingAtColumn(column.first()), index.siblingAtColumn(column.last())); + + // propagate up the model + QModelIndex parentIndex = parent(index); + while (parentIndex.isValid()) + { + for (const ColumnInterval &column : columns) + emit dataChanged(parentIndex.siblingAtColumn(column.first()), parentIndex.siblingAtColumn(column.last())); + parentIndex = parent(parentIndex); + } + + // propagate down the model + QVector parentIndexes; + + if (hasChildren(index)) + parentIndexes.push_back(index); + + while (!parentIndexes.isEmpty()) + { + const QModelIndex parent = parentIndexes.takeLast(); + + const int childCount = rowCount(parent); + const QModelIndex child = this->index(0, 0, parent); + + // emit this generation + for (const ColumnInterval &column : columns) + { + const QModelIndex childTopLeft = child.siblingAtColumn(column.first()); + const QModelIndex childBottomRight = child.sibling((childCount - 1), column.last()); + emit dataChanged(childTopLeft, childBottomRight); + } + + // check generations further down + parentIndexes.reserve(childCount); + for (int i = 0; i < childCount; ++i) + { + const QModelIndex sibling = child.siblingAtRow(i); + if (hasChildren(sibling)) + parentIndexes.push_back(sibling); + } + } +} diff --git a/src/gui/torrentcontentmodel.h b/src/gui/torrentcontentmodel.h index 84f00976a..481cf2ead 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -81,6 +81,10 @@ signals: void filteredFilesChanged(); private: + using ColumnInterval = IndexInterval; + + void notifySubtreeUpdated(const QModelIndex &index, const QVector &columns); + TorrentContentModelFolder *m_rootItem = nullptr; QVector m_filesIndex; QFileIconProvider *m_fileIconProvider = nullptr;