qBittorrent
TorrentContentModel Class Referencefinal

#include <torrentcontentmodel.h>

Inheritance diagram for TorrentContentModel:
Collaboration diagram for TorrentContentModel:

Public Types

enum  Roles { UnderlyingDataRole = Qt::UserRole }
 

Public Slots

void selectAll ()
 
void selectNone ()
 

Signals

void filteredFilesChanged ()
 

Public Member Functions

 TorrentContentModel (QObject *parent=nullptr)
 
 ~TorrentContentModel () override
 
void updateFilesProgress (const QVector< qreal > &fp)
 
void updateFilesPriorities (const QVector< BitTorrent::DownloadPriority > &fprio)
 
void updateFilesAvailability (const QVector< qreal > &fa)
 
QVector< BitTorrent::DownloadPrioritygetFilePriorities () const
 
bool allFiltered () const
 
int columnCount (const QModelIndex &parent={}) const override
 
bool setData (const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
 
TorrentContentModelItem::ItemType itemType (const QModelIndex &index) const
 
int getFileIndex (const QModelIndex &index)
 
QVariant data (const QModelIndex &index, int role=Qt::DisplayRole) const override
 
Qt::ItemFlags flags (const QModelIndex &index) const override
 
QVariant headerData (int section, Qt::Orientation orientation, int role) const override
 
QModelIndex index (int row, int column, const QModelIndex &parent={}) const override
 
QModelIndex parent (const QModelIndex &index) const override
 
int rowCount (const QModelIndex &parent={}) const override
 
void clear ()
 
void setupModelData (const BitTorrent::AbstractFileStorage &info)
 

Private Attributes

TorrentContentModelFolderm_rootItem
 
QVector< TorrentContentModelFile * > m_filesIndex
 
QFileIconProvider * m_fileIconProvider
 

Detailed Description

Definition at line 47 of file torrentcontentmodel.h.

Member Enumeration Documentation

◆ Roles

Enumerator
UnderlyingDataRole 

Definition at line 53 of file torrentcontentmodel.h.

54  {
55  UnderlyingDataRole = Qt::UserRole
56  };

Constructor & Destructor Documentation

◆ TorrentContentModel()

TorrentContentModel::TorrentContentModel ( QObject *  parent = nullptr)

Definition at line 191 of file torrentcontentmodel.cpp.

192  : QAbstractItemModel(parent)
193  , m_rootItem(new TorrentContentModelFolder(QVector<QString>({ tr("Name"), tr("Size"), tr("Progress"), tr("Download Priority"), tr("Remaining"), tr("Availability") })))
194 {
195 #if defined(Q_OS_WIN)
196  m_fileIconProvider = new WinShellFileIconProvider();
197 #elif defined(Q_OS_MACOS)
198  m_fileIconProvider = new MacFileIconProvider();
199 #else
200  static bool doesBuiltInProviderWork = doesQFileIconProviderWork();
201  m_fileIconProvider = doesBuiltInProviderWork ? new QFileIconProvider() : new MimeFileIconProvider();
202 #endif
203 }
TorrentContentModelFolder * m_rootItem
QFileIconProvider * m_fileIconProvider
QModelIndex parent(const QModelIndex &index) const override
bool doesQFileIconProviderWork()
Tests whether QFileIconProvider actually works.

◆ ~TorrentContentModel()

TorrentContentModel::~TorrentContentModel ( )
override

Definition at line 205 of file torrentcontentmodel.cpp.

206 {
207  delete m_fileIconProvider;
208  delete m_rootItem;
209 }

References m_fileIconProvider, and m_rootItem.

Member Function Documentation

◆ allFiltered()

bool TorrentContentModel::allFiltered ( ) const

Definition at line 262 of file torrentcontentmodel.cpp.

263 {
264  return std::all_of(m_filesIndex.cbegin(), m_filesIndex.cend(), [](const TorrentContentModelFile *fileItem)
265  {
266  return (fileItem->priority() == BitTorrent::DownloadPriority::Ignored);
267  });
268 }
QVector< TorrentContentModelFile * > m_filesIndex

References m_filesIndex.

◆ clear()

void TorrentContentModel::clear ( )

Definition at line 479 of file torrentcontentmodel.cpp.

480 {
481  qDebug("clear called");
482  beginResetModel();
483  m_filesIndex.clear();
485  endResetModel();
486 }

References TorrentContentModelFolder::deleteAllChildren(), m_filesIndex, and m_rootItem.

Referenced by PropertiesWidget::clear(), AddNewTorrentDialog::contentLayoutChanged(), and PropertiesWidget::loadTorrentInfos().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ columnCount()

int TorrentContentModel::columnCount ( const QModelIndex &  parent = {}) const
override

Definition at line 270 of file torrentcontentmodel.cpp.

271 {
272  if (parent.isValid())
273  return static_cast<TorrentContentModelItem*>(parent.internalPointer())->columnCount();
274 
275  return m_rootItem->columnCount();
276 }
int columnCount(const QModelIndex &parent={}) const override

References TorrentContentModelItem::columnCount(), m_rootItem, and parent().

Referenced by selectAll(), selectNone(), setData(), updateFilesAvailability(), updateFilesPriorities(), and updateFilesProgress().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ data()

QVariant TorrentContentModel::data ( const QModelIndex &  index,
int  role = Qt::DisplayRole 
) const
override

Definition at line 343 of file torrentcontentmodel.cpp.

344 {
345  if (!index.isValid())
346  return {};
347 
348  auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
349 
350  switch (role)
351  {
352  case Qt::DecorationRole:
353  {
355  return {};
356 
357  if (item->itemType() == TorrentContentModelItem::FolderType)
358  return m_fileIconProvider->icon(QFileIconProvider::Folder);
359  return m_fileIconProvider->icon(QFileInfo(item->name()));
360  }
361  case Qt::CheckStateRole:
362  {
364  return {};
365 
366  if (item->priority() == BitTorrent::DownloadPriority::Ignored)
367  return Qt::Unchecked;
368  if (item->priority() == BitTorrent::DownloadPriority::Mixed)
369  return Qt::PartiallyChecked;
370  return Qt::Checked;
371  }
372  case Qt::TextAlignmentRole:
373  if ((index.column() == TorrentContentModelItem::COL_SIZE)
375  return QVariant {Qt::AlignRight | Qt::AlignVCenter};
376  return {};
377 
378  case Qt::DisplayRole:
379  case Qt::ToolTipRole:
380  return item->displayData(index.column());
381 
382  case Roles::UnderlyingDataRole:
383  return item->underlyingData(index.column());
384 
385  default:
386  return {};
387  }
388 }
QModelIndex index(int row, int column, const QModelIndex &parent={}) const override

References TorrentContentModelItem::COL_NAME, TorrentContentModelItem::COL_REMAINING, TorrentContentModelItem::COL_SIZE, TorrentContentModelItem::FolderType, BitTorrent::Ignored, index(), m_fileIconProvider, and BitTorrent::Mixed.

Here is the call graph for this function:

◆ filteredFilesChanged

void TorrentContentModel::filteredFilesChanged ( )
signal

Referenced by setData(), AddNewTorrentDialog::setupTreeview(), and TorrentContentFilterModel::TorrentContentFilterModel().

Here is the caller graph for this function:

◆ flags()

Qt::ItemFlags TorrentContentModel::flags ( const QModelIndex &  index) const
override

Definition at line 390 of file torrentcontentmodel.cpp.

391 {
392  if (!index.isValid())
393  return Qt::NoItemFlags;
394 
395  Qt::ItemFlags flags {Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable};
397  flags |= Qt::ItemIsAutoTristate;
399  flags |= Qt::ItemIsEditable;
400 
401  return flags;
402 }
Qt::ItemFlags flags(const QModelIndex &index) const override
TorrentContentModelItem::ItemType itemType(const QModelIndex &index) const

References TorrentContentModelItem::COL_PRIO, TorrentContentModelItem::FolderType, index(), and itemType().

Here is the call graph for this function:

◆ getFileIndex()

int TorrentContentModel::getFileIndex ( const QModelIndex &  index)

Definition at line 333 of file torrentcontentmodel.cpp.

334 {
335  auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
336  if (item->itemType() == TorrentContentModelItem::FileType)
337  return static_cast<TorrentContentModelFile*>(item)->fileIndex();
338 
339  Q_ASSERT(item->itemType() == TorrentContentModelItem::FileType);
340  return -1;
341 }

References TorrentContentModelFile::fileIndex(), TorrentContentModelItem::FileType, and index().

Referenced by TorrentContentFilterModel::getFileIndex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getFilePriorities()

QVector< BitTorrent::DownloadPriority > TorrentContentModel::getFilePriorities ( ) const

Definition at line 253 of file torrentcontentmodel.cpp.

254 {
255  QVector<BitTorrent::DownloadPriority> prio;
256  prio.reserve(m_filesIndex.size());
258  prio.push_back(file->priority());
259  return prio;
260 }
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts") set_source_files_properties($
Definition: CMakeLists.txt:5

References asConst(), file(), and m_filesIndex.

Referenced by AddNewTorrentDialog::accept(), PropertiesWidget::applyPriorities(), AddNewTorrentDialog::contentLayoutChanged(), and AddNewTorrentDialog::updateDiskSpaceLabel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ headerData()

QVariant TorrentContentModel::headerData ( int  section,
Qt::Orientation  orientation,
int  role 
) const
override

Definition at line 404 of file torrentcontentmodel.cpp.

405 {
406  if (orientation != Qt::Horizontal)
407  return {};
408 
409  switch (role)
410  {
411  case Qt::DisplayRole:
412  return m_rootItem->displayData(section);
413 
414  case Qt::TextAlignmentRole:
415  if ((section == TorrentContentModelItem::COL_SIZE)
417  return QVariant {Qt::AlignRight | Qt::AlignVCenter};
418  return {};
419 
420  default:
421  return {};
422  }
423 }
QString displayData(int column) const

References TorrentContentModelItem::COL_REMAINING, TorrentContentModelItem::COL_SIZE, TorrentContentModelItem::displayData(), and m_rootItem.

Here is the call graph for this function:

◆ index()

QModelIndex TorrentContentModel::index ( int  row,
int  column,
const QModelIndex &  parent = {} 
) const
override

Definition at line 425 of file torrentcontentmodel.cpp.

426 {
427  if (parent.isValid() && (parent.column() != 0))
428  return {};
429 
430  if (column >= TorrentContentModelItem::NB_COL)
431  return {};
432 
433  TorrentContentModelFolder *parentItem;
434  if (!parent.isValid())
435  parentItem = m_rootItem;
436  else
437  parentItem = static_cast<TorrentContentModelFolder*>(parent.internalPointer());
438  Q_ASSERT(parentItem);
439 
440  if (row >= parentItem->childCount())
441  return {};
442 
443  TorrentContentModelItem *childItem = parentItem->child(row);
444  if (childItem)
445  return createIndex(row, column, childItem);
446  return {};
447 }
TorrentContentModelItem * child(int row) const

References TorrentContentModelFolder::child(), TorrentContentModelFolder::childCount(), m_rootItem, TorrentContentModelItem::NB_COL, and parent().

Referenced by data(), TorrentContentFilterModel::filterAcceptsRow(), flags(), getFileIndex(), TorrentContentFilterModel::hasFiltered(), itemType(), TorrentContentFilterModel::lessThan(), parent(), selectAll(), selectNone(), setData(), updateFilesAvailability(), updateFilesPriorities(), and updateFilesProgress().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ itemType()

TorrentContentModelItem::ItemType TorrentContentModel::itemType ( const QModelIndex &  index) const

Definition at line 328 of file torrentcontentmodel.cpp.

329 {
330  return static_cast<const TorrentContentModelItem*>(index.internalPointer())->itemType();
331 }

References index().

Referenced by TorrentContentFilterModel::filterAcceptsRow(), flags(), TorrentContentFilterModel::itemType(), and TorrentContentFilterModel::lessThan().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parent()

QModelIndex TorrentContentModel::parent ( const QModelIndex &  index) const
override

Definition at line 449 of file torrentcontentmodel.cpp.

450 {
451  if (!index.isValid())
452  return {};
453 
454  auto *childItem = static_cast<TorrentContentModelItem*>(index.internalPointer());
455  if (!childItem)
456  return {};
457 
458  TorrentContentModelItem *parentItem = childItem->parent();
459  if (parentItem == m_rootItem)
460  return {};
461 
462  return createIndex(parentItem->row(), 0, parentItem);
463 }
TorrentContentModelFolder * parent() const

References index(), m_rootItem, TorrentContentModelItem::parent(), and TorrentContentModelItem::row().

Referenced by columnCount(), index(), TorrentContentFilterModel::parent(), and rowCount().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rowCount()

int TorrentContentModel::rowCount ( const QModelIndex &  parent = {}) const
override

Definition at line 465 of file torrentcontentmodel.cpp.

466 {
467  if (parent.column() > 0)
468  return 0;
469 
470  TorrentContentModelFolder *parentItem;
471  if (!parent.isValid())
472  parentItem = m_rootItem;
473  else
474  parentItem = dynamic_cast<TorrentContentModelFolder*>(static_cast<TorrentContentModelItem*>(parent.internalPointer()));
475 
476  return parentItem ? parentItem->childCount() : 0;
477 }

References TorrentContentModelFolder::childCount(), m_rootItem, and parent().

Referenced by TorrentContentFilterModel::hasFiltered(), selectAll(), selectNone(), setData(), updateFilesAvailability(), updateFilesPriorities(), and updateFilesProgress().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ selectAll

void TorrentContentModel::selectAll ( )
slot

Definition at line 531 of file torrentcontentmodel.cpp.

532 {
533  for (int i = 0; i < m_rootItem->childCount(); ++i)
534  {
538  }
539  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
540 }
int rowCount(const QModelIndex &parent={}) const override
BitTorrent::DownloadPriority priority() const
virtual void setPriority(BitTorrent::DownloadPriority newPriority, bool updateParent=true)=0

References TorrentContentModelFolder::child(), TorrentContentModelFolder::childCount(), columnCount(), BitTorrent::Ignored, index(), m_rootItem, BitTorrent::Normal, TorrentContentModelItem::priority(), rowCount(), and TorrentContentModelItem::setPriority().

Here is the call graph for this function:

◆ selectNone

void TorrentContentModel::selectNone ( )
slot

Definition at line 542 of file torrentcontentmodel.cpp.

543 {
544  for (int i = 0; i < m_rootItem->childCount(); ++i)
546  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
547 }

References TorrentContentModelFolder::child(), TorrentContentModelFolder::childCount(), columnCount(), BitTorrent::Ignored, index(), m_rootItem, rowCount(), and TorrentContentModelItem::setPriority().

Here is the call graph for this function:

◆ setData()

bool TorrentContentModel::setData ( const QModelIndex &  index,
const QVariant &  value,
int  role = Qt::EditRole 
)
override

Definition at line 278 of file torrentcontentmodel.cpp.

279 {
280  if (!index.isValid())
281  return false;
282 
283  if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole))
284  {
285  auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
286  qDebug("setData(%s, %d)", qUtf8Printable(item->name()), value.toInt());
287 
289  if (value.toInt() == Qt::PartiallyChecked)
291  else if (value.toInt() == Qt::Unchecked)
293 
294  if (item->priority() != prio)
295  {
296  item->setPriority(prio);
297  // Update folders progress in the tree
300  emit dataChanged(this->index(0, 0), this->index((rowCount() - 1), (columnCount() - 1)));
301  emit filteredFilesChanged();
302  }
303  return true;
304  }
305 
306  if (role == Qt::EditRole)
307  {
308  Q_ASSERT(index.isValid());
309  auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
310  switch (index.column())
311  {
313  item->setName(value.toString());
314  break;
316  item->setPriority(static_cast<BitTorrent::DownloadPriority>(value.toInt()));
317  break;
318  default:
319  return false;
320  }
321  emit dataChanged(index, index);
322  return true;
323  }
324 
325  return false;
326 }
T value(const QString &key, const T &defaultValue={})
Definition: preferences.cpp:64

References TorrentContentModelItem::COL_NAME, TorrentContentModelItem::COL_PRIO, columnCount(), filteredFilesChanged(), BitTorrent::Ignored, index(), m_rootItem, BitTorrent::Mixed, BitTorrent::Normal, TorrentContentModelFolder::recalculateAvailability(), TorrentContentModelFolder::recalculateProgress(), rowCount(), and anonymous_namespace{preferences.cpp}::value().

Here is the call graph for this function:

◆ setupModelData()

void TorrentContentModel::setupModelData ( const BitTorrent::AbstractFileStorage info)

Definition at line 488 of file torrentcontentmodel.cpp.

489 {
490  qDebug("setup model data called");
491  const int filesCount = info.filesCount();
492  if (filesCount <= 0)
493  return;
494 
495  emit layoutAboutToBeChanged();
496  // Initialize files_index array
497  qDebug("Torrent contains %d files", filesCount);
498  m_filesIndex.reserve(filesCount);
499 
500  TorrentContentModelFolder *currentParent;
501  // Iterate over files
502  for (int i = 0; i < filesCount; ++i)
503  {
504  currentParent = m_rootItem;
505  const QString path = Utils::Fs::toUniformPath(info.filePath(i));
506 
507  // Iterate of parts of the path to create necessary folders
508  QList<QStringView> pathFolders = QStringView(path).split(u'/', Qt::SkipEmptyParts);
509  pathFolders.removeLast();
510 
511  for (const QStringView pathPart : asConst(pathFolders))
512  {
513  const QString folderPath = pathPart.toString();
514  TorrentContentModelFolder *newParent = currentParent->childFolderWithName(folderPath);
515  if (!newParent)
516  {
517  newParent = new TorrentContentModelFolder(folderPath, currentParent);
518  currentParent->appendChild(newParent);
519  }
520  currentParent = newParent;
521  }
522  // Actually create the file
524  Utils::Fs::fileName(info.filePath(i)), info.fileSize(i), currentParent, i);
525  currentParent->appendChild(fileItem);
526  m_filesIndex.push_back(fileItem);
527  }
528  emit layoutChanged();
529 }
virtual int filesCount() const =0
virtual qlonglong fileSize(int index) const =0
virtual QString filePath(int index) const =0
TorrentContentModelFolder * childFolderWithName(const QString &name) const
void appendChild(TorrentContentModelItem *item)
QString fileName(const QString &filePath)
Definition: fs.cpp:87
QString toUniformPath(const QString &path)
Definition: fs.cpp:69

References TorrentContentModelFolder::appendChild(), asConst(), TorrentContentModelFolder::childFolderWithName(), Utils::Fs::fileName(), BitTorrent::AbstractFileStorage::filePath(), BitTorrent::AbstractFileStorage::filesCount(), BitTorrent::AbstractFileStorage::fileSize(), m_filesIndex, m_rootItem, and Utils::Fs::toUniformPath().

Referenced by AddNewTorrentDialog::contentLayoutChanged(), PropertiesWidget::loadDynamicData(), and AddNewTorrentDialog::setupTreeview().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateFilesAvailability()

void TorrentContentModel::updateFilesAvailability ( const QVector< qreal > &  fa)

Definition at line 239 of file torrentcontentmodel.cpp.

240 {
241  Q_ASSERT(m_filesIndex.size() == fa.size());
242  // XXX: Why is this necessary?
243  if (m_filesIndex.size() != fa.size()) return;
244 
245  emit layoutAboutToBeChanged();
246  for (int i = 0; i < m_filesIndex.size(); ++i)
247  m_filesIndex[i]->setAvailability(fa[i]);
248  // Update folders progress in the tree
250  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
251 }

References columnCount(), index(), m_filesIndex, m_rootItem, TorrentContentModelFolder::recalculateProgress(), and rowCount().

Referenced by PropertiesWidget::loadDynamicData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateFilesPriorities()

void TorrentContentModel::updateFilesPriorities ( const QVector< BitTorrent::DownloadPriority > &  fprio)

Definition at line 226 of file torrentcontentmodel.cpp.

227 {
228  Q_ASSERT(m_filesIndex.size() == fprio.size());
229  // XXX: Why is this necessary?
230  if (m_filesIndex.size() != fprio.size())
231  return;
232 
233  emit layoutAboutToBeChanged();
234  for (int i = 0; i < fprio.size(); ++i)
235  m_filesIndex[i]->setPriority(static_cast<BitTorrent::DownloadPriority>(fprio[i]));
236  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
237 }

References columnCount(), index(), m_filesIndex, and rowCount().

Referenced by AddNewTorrentDialog::contentLayoutChanged(), and PropertiesWidget::loadDynamicData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateFilesProgress()

void TorrentContentModel::updateFilesProgress ( const QVector< qreal > &  fp)

Definition at line 211 of file torrentcontentmodel.cpp.

212 {
213  Q_ASSERT(m_filesIndex.size() == fp.size());
214  // XXX: Why is this necessary?
215  if (m_filesIndex.size() != fp.size()) return;
216 
217  emit layoutAboutToBeChanged();
218  for (int i = 0; i < fp.size(); ++i)
219  m_filesIndex[i]->setProgress(fp[i]);
220  // Update folders progress in the tree
223  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
224 }

References columnCount(), index(), m_filesIndex, m_rootItem, TorrentContentModelFolder::recalculateAvailability(), TorrentContentModelFolder::recalculateProgress(), and rowCount().

Referenced by PropertiesWidget::loadDynamicData().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_fileIconProvider

QFileIconProvider* TorrentContentModel::m_fileIconProvider
private

Definition at line 89 of file torrentcontentmodel.h.

Referenced by data(), and ~TorrentContentModel().

◆ m_filesIndex

QVector<TorrentContentModelFile *> TorrentContentModel::m_filesIndex
private

◆ m_rootItem


The documentation for this class was generated from the following files: