diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index a6436ec34..f9ad2c697 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1953,3 +1953,24 @@ void TorrentHandle::prioritizeFiles(const QVector &priorities) updateStatus(); } + +QVector TorrentHandle::availableFileFractions() const +{ + QVector piecesAvailability = pieceAvailability(); + const auto filesCount = this->filesCount(); + // libtorrent returns empty array for seeding only torrents + if (piecesAvailability.empty()) return QVector(filesCount, -1.); + + QVector res; + res.reserve(filesCount); + TorrentInfo info = this->info(); + for (int file = 0; file < filesCount; ++file) { + TorrentInfo::PieceRange filePieces = info.filePieces(file); + int availablePieces = 0; + for (int piece = filePieces.first(); piece <= filePieces.last(); ++piece) { + availablePieces += piecesAvailability[piece] > 0 ? 1 : 0; + } + res.push_back(static_cast(availablePieces) / filePieces.size()); + } + return res; +} diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 8cdcfe02e..cb0c183cc 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -361,6 +361,14 @@ namespace BitTorrent void handleAppendExtensionToggled(); void saveResumeData(bool updateStatus = false); + /** + * @brief fraction of file pieces that are available at least from one peer + * + * This is not the same as torrrent availability, it is just a fraction of pieces + * that can be downloaded right now. It varies between 0 to 1. + */ + QVector availableFileFractions() const; + private: typedef boost::function EventTrigger; diff --git a/src/base/unicodestrings.h b/src/base/unicodestrings.h index 33e164ddb..88ffe7782 100644 --- a/src/base/unicodestrings.h +++ b/src/base/unicodestrings.h @@ -39,6 +39,7 @@ const char C_NON_BREAKING_SPACE[] = " "; const char C_UP[] = "▲"; const char C_DOWN[] = "▼"; const char C_COPYRIGHT[] = "©"; +const char C_THIN_SPACE[] = " "; const char C_UTP[] = "μTP"; const char C_LOCALE_ENGLISH[] = "English"; const char C_LOCALE_ENGLISH_AUSTRALIA[] = "English(Australia)"; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 5bbac7bb4..bbdb6901c 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -737,6 +737,7 @@ void AddNewTorrentDialog::setupTreeview() // Hide useless columns after loading the header state ui->contentTreeView->hideColumn(PROGRESS); ui->contentTreeView->hideColumn(REMAINING); + ui->contentTreeView->hideColumn(AVAILABILITY); // Expand root folder ui->contentTreeView->setExpanded(m_contentModel->index(0, 0), true); diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 77466c748..5df08d842 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -493,6 +493,7 @@ void PropertiesWidget::loadDynamicData() qDebug("Updating priorities in files tab"); m_ui->filesList->setUpdatesEnabled(false); PropListModel->model()->updateFilesProgress(m_torrent->filesProgress()); + PropListModel->model()->updateFilesAvailability(m_torrent->availableFileFractions()); // XXX: We don't update file priorities regularly for performance // reasons. This means that priorities will not be updated if // set from the Web UI. diff --git a/src/gui/properties/proplistdelegate.cpp b/src/gui/properties/proplistdelegate.cpp index 2c845ba6f..b1b1b3645 100644 --- a/src/gui/properties/proplistdelegate.cpp +++ b/src/gui/properties/proplistdelegate.cpp @@ -42,6 +42,7 @@ #include #endif +#include "base/unicodestrings.h" #include "base/utils/misc.h" #include "base/utils/string.h" #include "propertieswidget.h" @@ -131,6 +132,19 @@ void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti QItemDelegate::drawDisplay(painter, opt, option.rect, text); } break; + case AVAILABILITY: { + const qreal availability = index.data().toDouble(); + if (availability < 0) { + QItemDelegate::drawDisplay(painter, opt, option.rect, tr("N/A")); + } + else { + const QString value = (availability >= 1.0) + ? QLatin1String("100") + : Utils::String::fromDouble(availability * 100., 1); + QItemDelegate::drawDisplay(painter, opt, option.rect, value + C_THIN_SPACE + QLatin1Char('%')); + } + } + break; default: QItemDelegate::paint(painter, option, index); break; diff --git a/src/gui/properties/proplistdelegate.h b/src/gui/properties/proplistdelegate.h index 2d5e41335..ed9035349 100644 --- a/src/gui/properties/proplistdelegate.h +++ b/src/gui/properties/proplistdelegate.h @@ -46,7 +46,8 @@ enum PropColumn PCSIZE, PROGRESS, PRIORITY, - REMAINING + REMAINING, + AVAILABILITY }; class PropListDelegate: public QItemDelegate @@ -72,3 +73,4 @@ private: }; #endif + diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 528e7a7d1..ace9868a8 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -56,7 +56,7 @@ namespace TorrentContentModel::TorrentContentModel(QObject *parent) : QAbstractItemModel(parent) - , m_rootItem(new TorrentContentModelFolder(QList({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining") }))) + , m_rootItem(new TorrentContentModelFolder(QList({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") }))) { } @@ -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 547c85cfb..8fa9ac565 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -41,40 +41,42 @@ class TorrentContentModelFile; -class TorrentContentModel: public QAbstractItemModel { - Q_OBJECT +class TorrentContentModel: public QAbstractItemModel +{ + Q_OBJECT public: - TorrentContentModel(QObject *parent = 0); - ~TorrentContentModel(); + TorrentContentModel(QObject *parent = 0); + ~TorrentContentModel(); - void updateFilesProgress(const QVector &fp); - void updateFilesPriorities(const QVector &fprio); - QVector getFilePriorities() const; - bool allFiltered() const; - virtual int columnCount(const QModelIndex &parent=QModelIndex()) const; - virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); - TorrentContentModelItem::ItemType itemType(const QModelIndex& index) const; - int getFileIndex(const QModelIndex& index); - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; - virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex& index) const; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; - void clear(); - void setupModelData(const BitTorrent::TorrentInfo &info); + 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; + virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + TorrentContentModelItem::ItemType itemType(const QModelIndex& index) const; + int getFileIndex(const QModelIndex& index); + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + virtual Qt::ItemFlags flags(const QModelIndex& index) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex& index) const; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; + void clear(); + void setupModelData(const BitTorrent::TorrentInfo &info); signals: - void filteredFilesChanged(); + void filteredFilesChanged(); public slots: - void selectAll(); - void selectNone(); + void selectAll(); + void selectNone(); private: - TorrentContentModelFolder* m_rootItem; - QVector m_filesIndex; + TorrentContentModelFolder *m_rootItem; + QVector m_filesIndex; }; #endif // TORRENTCONTENTMODEL_H diff --git a/src/gui/torrentcontentmodelfile.cpp b/src/gui/torrentcontentmodelfile.cpp index cabd8ed5c..df66cb9fc 100644 --- a/src/gui/torrentcontentmodelfile.cpp +++ b/src/gui/torrentcontentmodelfile.cpp @@ -32,43 +32,54 @@ #include "torrentcontentmodelfolder.h" TorrentContentModelFile::TorrentContentModelFile(const QString &fileName, qulonglong fileSize, - TorrentContentModelFolder* parent, int file_index) - : TorrentContentModelItem(parent) - , m_fileIndex(file_index) + TorrentContentModelFolder *parent, int fileIndex) + : TorrentContentModelItem(parent) + , m_fileIndex(fileIndex) { - Q_ASSERT(parent); + Q_ASSERT(parent); - m_name = fileName; + m_name = fileName; - // Do not display incomplete extensions - if (m_name.endsWith(".!qB")) - m_name.chop(4); + // Do not display incomplete extensions + if (m_name.endsWith(".!qB")) + m_name.chop(4); - m_size = fileSize; + m_size = fileSize; } int TorrentContentModelFile::fileIndex() const { - return m_fileIndex; + return m_fileIndex; } -void TorrentContentModelFile::setPriority(int new_prio, bool update_parent) +void TorrentContentModelFile::setPriority(int newPriority, bool updateParent) { - Q_ASSERT(new_prio != prio::MIXED); + Q_ASSERT(newPriority != prio::MIXED); - if (m_priority == new_prio) - return; + if (m_priority == newPriority) + return; - m_priority = new_prio; + m_priority = newPriority; - // Update parent - if (update_parent) - m_parentItem->updatePriority(); + // Update parent + if (updateParent) + m_parentItem->updatePriority(); } void TorrentContentModelFile::setProgress(qreal progress) { - m_progress = progress; - m_remaining = (qulonglong)(m_size * (1.0 - m_progress)); - Q_ASSERT(m_progress <= 1.); + m_progress = progress; + m_remaining = static_cast(m_size * (1.0 - m_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 d3861b717..f6d73e51a 100644 --- a/src/gui/torrentcontentmodelfile.h +++ b/src/gui/torrentcontentmodelfile.h @@ -33,19 +33,20 @@ #include "torrentcontentmodelitem.h" -class TorrentContentModelFile : public TorrentContentModelItem +class TorrentContentModelFile: public TorrentContentModelItem { public: - TorrentContentModelFile(const QString &fileName, qulonglong fileSize, - TorrentContentModelFolder* parent, int file_index); + TorrentContentModelFile(const QString &fileName, qulonglong fileSize, + TorrentContentModelFolder *parent, int fileIndex); - int fileIndex() const; - void setPriority(int new_prio, bool update_parent = true); - void setProgress(qreal progress); - ItemType itemType() const { return FileType; } + int fileIndex() const; + void setPriority(int newPriority, bool updateParent = true) override; + void setProgress(qreal progress); + void setAvailability(qreal availability); + ItemType itemType() const override; private: - int m_fileIndex; + int m_fileIndex; }; #endif // TORRENTCONTENTMODELFILE_H diff --git a/src/gui/torrentcontentmodelfolder.cpp b/src/gui/torrentcontentmodelfolder.cpp index 6695dbab9..09df1e671 100644 --- a/src/gui/torrentcontentmodelfolder.cpp +++ b/src/gui/torrentcontentmodelfolder.cpp @@ -31,136 +31,167 @@ #include #include "torrentcontentmodelfolder.h" -TorrentContentModelFolder::TorrentContentModelFolder(const QString& name, TorrentContentModelFolder* parent) - : TorrentContentModelItem(parent) +TorrentContentModelFolder::TorrentContentModelFolder(const QString &name, TorrentContentModelFolder *parent) + : TorrentContentModelItem(parent) { - Q_ASSERT(parent); - m_name = name; - // Do not display incomplete extensions - if (m_name.endsWith(".!qB")) - m_name.chop(4); + Q_ASSERT(parent); + m_name = name; + // Do not display incomplete extensions + if (m_name.endsWith(".!qB")) + m_name.chop(4); } -TorrentContentModelFolder::TorrentContentModelFolder(const QList& data) - : TorrentContentModelItem(0) +TorrentContentModelFolder::TorrentContentModelFolder(const QList &data) + : TorrentContentModelItem(0) { - Q_ASSERT(data.size() == NB_COL); - m_itemData = data; + Q_ASSERT(data.size() == NB_COL); + m_itemData = data; } TorrentContentModelFolder::~TorrentContentModelFolder() { - qDeleteAll(m_childItems); + qDeleteAll(m_childItems); +} + +TorrentContentModelItem::ItemType TorrentContentModelFolder::itemType() const +{ + return FolderType; } void TorrentContentModelFolder::deleteAllChildren() { - Q_ASSERT(isRootItem()); - qDeleteAll(m_childItems); - m_childItems.clear(); + Q_ASSERT(isRootItem()); + qDeleteAll(m_childItems); + m_childItems.clear(); } -const QList& TorrentContentModelFolder::children() const +const QList &TorrentContentModelFolder::children() const { - return m_childItems; + return m_childItems; } -void TorrentContentModelFolder::appendChild(TorrentContentModelItem* item) +void TorrentContentModelFolder::appendChild(TorrentContentModelItem *item) { - Q_ASSERT(item); - m_childItems.append(item); - // Update own size - if (item->itemType() == FileType) - increaseSize(item->size()); + Q_ASSERT(item); + m_childItems.append(item); + // Update own size + if (item->itemType() == FileType) + increaseSize(item->size()); } -TorrentContentModelItem* TorrentContentModelFolder::child(int row) const +TorrentContentModelItem *TorrentContentModelFolder::child(int row) const { - return m_childItems.value(row, 0); + return m_childItems.value(row, 0); } -TorrentContentModelFolder* TorrentContentModelFolder::childFolderWithName(const QString& name) const +TorrentContentModelFolder *TorrentContentModelFolder::childFolderWithName(const QString &name) const { - foreach (TorrentContentModelItem* child, m_childItems) { - if (child->itemType() == FolderType && child->name() == name) - return static_cast(child); - } - return 0; + foreach (TorrentContentModelItem *child, m_childItems) + if ((child->itemType() == FolderType) && (child->name() == name)) + return static_cast(child); + return 0; } int TorrentContentModelFolder::childCount() const { - return m_childItems.count(); + return m_childItems.count(); } // Only non-root folders use this function void TorrentContentModelFolder::updatePriority() { - if (isRootItem()) - return; - - Q_ASSERT(!m_childItems.isEmpty()); - - // If all children have the same priority - // then the folder should have the same - // priority - const int prio = m_childItems.first()->priority(); - for (int i=1; ipriority() != prio) { - setPriority(prio::MIXED); - return; + if (isRootItem()) + return; + + Q_ASSERT(!m_childItems.isEmpty()); + + // If all children have the same priority + // then the folder should have the same + // priority + const int prio = m_childItems.first()->priority(); + for (int i = 1; i < m_childItems.size(); ++i) { + if (m_childItems.at(i)->priority() != prio) { + setPriority(prio::MIXED); + return; + } } - } - // All child items have the same priority - // Update own if necessary - setPriority(prio); + // All child items have the same priority + // Update own if necessary + setPriority(prio); } -void TorrentContentModelFolder::setPriority(int new_prio, bool update_parent) +void TorrentContentModelFolder::setPriority(int newPriority, bool updateParent) { - if (m_priority == new_prio) - return; + if (m_priority == newPriority) + return; - m_priority = new_prio; + m_priority = newPriority; - // Update parent priority - if (update_parent) - m_parentItem->updatePriority(); + // Update parent priority + if (updateParent) + m_parentItem->updatePriority(); - // Update children - if (m_priority != prio::MIXED) { - foreach (TorrentContentModelItem* child, m_childItems) - child->setPriority(m_priority, false); - } + // Update children + if (m_priority != prio::MIXED) + foreach (TorrentContentModelItem *child, m_childItems) + child->setPriority(m_priority, false); } void TorrentContentModelFolder::recalculateProgress() { - qreal tProgress = 0; - qulonglong tSize = 0; - qulonglong tRemaining = 0; - foreach (TorrentContentModelItem* child, m_childItems) { - if (child->priority() != prio::IGNORED) { - if (child->itemType() == FolderType) - static_cast(child)->recalculateProgress(); - tProgress += child->progress() * child->size(); - tSize += child->size(); - tRemaining += child->remaining(); + qreal tProgress = 0; + qulonglong tSize = 0; + qulonglong tRemaining = 0; + foreach (TorrentContentModelItem *child, m_childItems) { + if (child->priority() != prio::IGNORED) { + if (child->itemType() == FolderType) + static_cast(child)->recalculateProgress(); + tProgress += child->progress() * child->size(); + tSize += child->size(); + tRemaining += child->remaining(); + } } - } - if (!isRootItem() && tSize > 0) { - m_progress = tProgress / tSize; - m_remaining = tRemaining; - Q_ASSERT(m_progress <= 1.); - } + if (!isRootItem() && (tSize > 0)) { + m_progress = tProgress / tSize; + m_remaining = tRemaining; + Q_ASSERT(m_progress <= 1.); + } +} + +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()) - return; + if (isRootItem()) + return; - m_size += delta; - m_parentItem->increaseSize(delta); + m_size += delta; + m_parentItem->increaseSize(delta); } diff --git a/src/gui/torrentcontentmodelfolder.h b/src/gui/torrentcontentmodelfolder.h index ead57acd7..e136c9a2e 100644 --- a/src/gui/torrentcontentmodelfolder.h +++ b/src/gui/torrentcontentmodelfolder.h @@ -33,34 +33,35 @@ #include "torrentcontentmodelitem.h" -class TorrentContentModelFolder : public TorrentContentModelItem +class TorrentContentModelFolder: public TorrentContentModelItem { public: - // Folder constructor - TorrentContentModelFolder(const QString& name, TorrentContentModelFolder* parent); + // Folder constructor + TorrentContentModelFolder(const QString& name, TorrentContentModelFolder* parent); - // Invisible root item constructor - TorrentContentModelFolder(const QList& data); + // Invisible root item constructor + TorrentContentModelFolder(const QList& data); - ~TorrentContentModelFolder(); + ~TorrentContentModelFolder(); - ItemType itemType() const { return FolderType; } + ItemType itemType() const override; - void increaseSize(qulonglong delta); - void recalculateProgress(); - void updatePriority(); + void increaseSize(qulonglong delta); + void recalculateProgress(); + void recalculateAvailability(); + void updatePriority(); - void setPriority(int new_prio, bool update_parent = true); + void setPriority(int newPriority, bool updateParent = true) override; - void deleteAllChildren(); - const QList& children() const; - void appendChild(TorrentContentModelItem* item); - TorrentContentModelItem* child(int row) const; - TorrentContentModelFolder* childFolderWithName(const QString& name) const; - int childCount() const; + void deleteAllChildren(); + const QList& children() const; + void appendChild(TorrentContentModelItem* item); + TorrentContentModelItem* child(int row) const; + TorrentContentModelFolder* childFolderWithName(const QString& name) const; + int childCount() const; private: - QList m_childItems; + QList m_childItems; }; #endif // TORRENTCONTENTMODELFOLDER_H diff --git a/src/gui/torrentcontentmodelitem.cpp b/src/gui/torrentcontentmodelitem.cpp index c841a0cb8..15a1988db 100644 --- a/src/gui/torrentcontentmodelitem.cpp +++ b/src/gui/torrentcontentmodelitem.cpp @@ -34,36 +34,40 @@ #include "torrentcontentmodelfolder.h" #include -TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder* parent) - : m_parentItem(parent) - , m_size(0) - , m_remaining(0) - , m_priority(prio::NORMAL) - , m_progress(0) +TorrentContentModelItem::TorrentContentModelItem(TorrentContentModelFolder *parent) + : m_parentItem(parent) + , m_size(0) + , m_remaining(0) + , m_priority(prio::NORMAL) + , m_progress(0) + , m_availability(-1.) { } -TorrentContentModelItem::~TorrentContentModelItem() +TorrentContentModelItem::~TorrentContentModelItem() = default; + +bool TorrentContentModelItem::isRootItem() const { + return !m_parentItem; } QString TorrentContentModelItem::name() const { - Q_ASSERT(!isRootItem()); - return m_name; + Q_ASSERT(!isRootItem()); + return m_name; } -void TorrentContentModelItem::setName(const QString& name) +void TorrentContentModelItem::setName(const QString &name) { - Q_ASSERT(!isRootItem()); - m_name = name; + Q_ASSERT(!isRootItem()); + m_name = name; } qulonglong TorrentContentModelItem::size() const { - Q_ASSERT(!isRootItem()); + Q_ASSERT(!isRootItem()); - return m_size; + return m_size; } qreal TorrentContentModelItem::progress() const @@ -81,47 +85,57 @@ 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()); - return m_priority; + Q_ASSERT(!isRootItem()); + return m_priority; } int TorrentContentModelItem::columnCount() const { - return NB_COL; + return NB_COL; } QVariant TorrentContentModelItem::data(int column) const { - if (isRootItem()) - return m_itemData.value(column); - - switch(column) { - case COL_NAME: - return m_name; - case COL_PRIO: - return m_priority; - case COL_PROGRESS: - return progress(); - case COL_SIZE: - return m_size; - case COL_REMAINING: - return remaining(); - default: - Q_ASSERT(false); - return QVariant(); - } + if (isRootItem()) + return m_itemData.value(column); + + switch (column) { + case COL_NAME: + return m_name; + case COL_PRIO: + return m_priority; + case COL_PROGRESS: + return progress(); + case COL_SIZE: + return m_size; + case COL_REMAINING: + return remaining(); + case COL_AVAILABILITY: + return availability(); + default: + Q_ASSERT(false); + return QVariant(); + } } int TorrentContentModelItem::row() const { - if (m_parentItem) - return m_parentItem->children().indexOf(const_cast(this)); - return 0; + if (m_parentItem) + return m_parentItem->children().indexOf(const_cast(this)); + return 0; } -TorrentContentModelFolder* TorrentContentModelItem::parent() const +TorrentContentModelFolder *TorrentContentModelItem::parent() const { - return m_parentItem; + return m_parentItem; } + diff --git a/src/gui/torrentcontentmodelitem.h b/src/gui/torrentcontentmodelitem.h index a21398f80..115dd76c2 100644 --- a/src/gui/torrentcontentmodelitem.h +++ b/src/gui/torrentcontentmodelitem.h @@ -34,48 +34,74 @@ #include #include -namespace prio { -enum FilePriority {IGNORED=0, NORMAL=1, HIGH=6, MAXIMUM=7, MIXED=-1}; +namespace prio +{ + enum FilePriority + { + IGNORED=0, + NORMAL=1, + HIGH=6, + MAXIMUM=7, + MIXED=-1 + }; } class TorrentContentModelFolder; -class TorrentContentModelItem { +class TorrentContentModelItem +{ public: - enum TreeItemColumns {COL_NAME, COL_SIZE, COL_PROGRESS, COL_PRIO, COL_REMAINING, NB_COL}; - enum ItemType { FileType, FolderType }; + enum TreeItemColumns + { + COL_NAME, + COL_SIZE, + COL_PROGRESS, + COL_PRIO, + COL_REMAINING, + COL_AVAILABILITY, + NB_COL + }; - TorrentContentModelItem(TorrentContentModelFolder* parent); - virtual ~TorrentContentModelItem(); + enum ItemType + { + FileType, + FolderType + }; - inline bool isRootItem() const { return !m_parentItem; } - TorrentContentModelFolder* parent() const; - virtual ItemType itemType() const = 0; + TorrentContentModelItem(TorrentContentModelFolder *parent); + virtual ~TorrentContentModelItem(); - QString name() const; - void setName(const QString& name); + bool isRootItem() const; + TorrentContentModelFolder *parent() const; + virtual ItemType itemType() const = 0; - qulonglong size() const; - qreal progress() const; - qulonglong remaining() const; + QString name() const; + void setName(const QString &name); - int priority() const; - virtual void setPriority(int new_prio, bool update_parent = true) = 0; + qulonglong size() const; + qreal progress() const; + qulonglong remaining() const; - int columnCount() const; - QVariant data(int column) const; - int row() const; + qreal availability() const; + + int priority() const; + virtual void setPriority(int newPriority, bool updateParent = true) = 0; + + int columnCount() const; + QVariant data(int column) const; + int row() const; protected: - TorrentContentModelFolder* m_parentItem; - // Root item members - QList m_itemData; - // Non-root item members - QString m_name; - qulonglong m_size; - qulonglong m_remaining; - int m_priority; - qreal m_progress; + TorrentContentModelFolder *m_parentItem; + // Root item members + QList m_itemData; + // Non-root item members + QString m_name; + qulonglong m_size; + qulonglong m_remaining; + int m_priority; + qreal m_progress; + qreal m_availability; }; #endif // TORRENTCONTENTMODELITEM_H