diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 528e7a7d1..53a0a4705 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -76,6 +76,7 @@ void TorrentContentModel::updateFilesProgress(const QVector &fp) m_filesIndex[i]->setProgress(fp[i]); // Update folders progress in the tree m_rootItem->recalculateProgress(); + m_rootItem->recalculateAvailability(); emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } @@ -92,6 +93,20 @@ void TorrentContentModel::updateFilesPriorities(const QVector &fprio) emit dataChanged(index(0, 0), index(rowCount(), columnCount())); } +void TorrentContentModel::updateFilesAvailability(const QVector &fa) +{ + Q_ASSERT(m_filesIndex.size() == fa.size()); + // XXX: Why is this necessary? + if (m_filesIndex.size() != fa.size()) return; + + emit layoutAboutToBeChanged(); + for (int i = 0; i < fa.size(); ++i) + m_filesIndex[i]->setAvailability(fa[i]); + // Update folders progress in the tree + m_rootItem->recalculateProgress(); + emit dataChanged(index(0, 0), index(rowCount(), columnCount())); +} + QVector TorrentContentModel::getFilePriorities() const { QVector prio; @@ -134,6 +149,7 @@ bool TorrentContentModel::setData(const QModelIndex& index, const QVariant& valu item->setPriority(prio::NORMAL); // Update folders progress in the tree m_rootItem->recalculateProgress(); + m_rootItem->recalculateAvailability(); emit dataChanged(this->index(0, 0), this->index(rowCount() - 1, columnCount() - 1)); emit filteredFilesChanged(); } diff --git a/src/gui/torrentcontentmodel.h b/src/gui/torrentcontentmodel.h index e7c2f8395..8fa9ac565 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -51,6 +51,7 @@ public: void updateFilesProgress(const QVector &fp); void updateFilesPriorities(const QVector &fprio); + void updateFilesAvailability(const QVector &fa); QVector getFilePriorities() const; bool allFiltered() const; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/src/gui/torrentcontentmodelfile.cpp b/src/gui/torrentcontentmodelfile.cpp index 20d3c2586..df66cb9fc 100644 --- a/src/gui/torrentcontentmodelfile.cpp +++ b/src/gui/torrentcontentmodelfile.cpp @@ -73,6 +73,12 @@ void TorrentContentModelFile::setProgress(qreal progress) Q_ASSERT(m_progress <= 1.); } +void TorrentContentModelFile::setAvailability(qreal availability) +{ + m_availability = availability; + Q_ASSERT(m_availability <= 1.); +} + TorrentContentModelItem::ItemType TorrentContentModelFile::itemType() const { return FileType; diff --git a/src/gui/torrentcontentmodelfile.h b/src/gui/torrentcontentmodelfile.h index 234908e8d..f6d73e51a 100644 --- a/src/gui/torrentcontentmodelfile.h +++ b/src/gui/torrentcontentmodelfile.h @@ -42,6 +42,7 @@ public: int fileIndex() const; void setPriority(int newPriority, bool updateParent = true) override; void setProgress(qreal progress); + void setAvailability(qreal availability); ItemType itemType() const override; private: diff --git a/src/gui/torrentcontentmodelfolder.cpp b/src/gui/torrentcontentmodelfolder.cpp index ea250876a..09df1e671 100644 --- a/src/gui/torrentcontentmodelfolder.cpp +++ b/src/gui/torrentcontentmodelfolder.cpp @@ -159,6 +159,34 @@ void TorrentContentModelFolder::recalculateProgress() } } +void TorrentContentModelFolder::recalculateAvailability() +{ + qreal tAvailability = 0; + qulonglong tSize = 0; + bool foundAnyData = false; + foreach (TorrentContentModelItem* child, m_childItems) { + if (child->priority() == prio::IGNORED) + continue; + + if (child->itemType() == FolderType) + static_cast(child)->recalculateAvailability(); + const qreal childAvailability = child->availability(); + if (childAvailability >= 0) { // -1 means "no data" + tAvailability += childAvailability * child->size(); + foundAnyData = true; + } + tSize += child->size(); + } + + if (!isRootItem() && (tSize > 0) && foundAnyData) { + m_availability = tAvailability / tSize; + Q_ASSERT(m_availability <= 1.); + } + else { + m_availability = -1.; + } +} + void TorrentContentModelFolder::increaseSize(qulonglong delta) { if (isRootItem()) diff --git a/src/gui/torrentcontentmodelfolder.h b/src/gui/torrentcontentmodelfolder.h index 5b12ddfb5..e136c9a2e 100644 --- a/src/gui/torrentcontentmodelfolder.h +++ b/src/gui/torrentcontentmodelfolder.h @@ -48,6 +48,7 @@ public: void increaseSize(qulonglong delta); void recalculateProgress(); + void recalculateAvailability(); void updatePriority(); void setPriority(int newPriority, bool updateParent = true) override; diff --git a/src/gui/torrentcontentmodelitem.cpp b/src/gui/torrentcontentmodelitem.cpp index 58765efba..15a1988db 100644 --- a/src/gui/torrentcontentmodelitem.cpp +++ b/src/gui/torrentcontentmodelitem.cpp @@ -40,6 +40,7 @@ TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *pare , m_remaining(0) , m_priority(prio::NORMAL) , m_progress(0) + , m_availability(-1.) { } @@ -84,6 +85,13 @@ qulonglong TorrentContentModelItem::remaining() const return m_remaining; } +qreal TorrentContentModelItem::availability() const +{ + Q_ASSERT(!isRootItem()); + + return m_size > 0 ? m_availability : 0.; +} + int TorrentContentModelItem::priority() const { Q_ASSERT(!isRootItem()); @@ -111,6 +119,8 @@ QVariant TorrentContentModelItem::data(int column) const return m_size; case COL_REMAINING: return remaining(); + case COL_AVAILABILITY: + return availability(); default: Q_ASSERT(false); return QVariant(); @@ -128,3 +138,4 @@ TorrentContentModelFolder *TorrentContentModelItem::parent() const { return m_parentItem; } + diff --git a/src/gui/torrentcontentmodelitem.h b/src/gui/torrentcontentmodelitem.h index f67ec5a44..115dd76c2 100644 --- a/src/gui/torrentcontentmodelitem.h +++ b/src/gui/torrentcontentmodelitem.h @@ -58,6 +58,7 @@ public: COL_PROGRESS, COL_PRIO, COL_REMAINING, + COL_AVAILABILITY, NB_COL }; @@ -81,6 +82,8 @@ public: qreal progress() const; qulonglong remaining() const; + qreal availability() const; + int priority() const; virtual void setPriority(int newPriority, bool updateParent = true) = 0; @@ -98,6 +101,7 @@ protected: qulonglong m_remaining; int m_priority; qreal m_progress; + qreal m_availability; }; #endif // TORRENTCONTENTMODELITEM_H