Browse Source

Merge pull request #17786 from Chocobo1/selection

Fix torrent content checkboxes not updated properly
adaptive-webui-19844
Chocobo1 2 years ago committed by GitHub
parent
commit
bc0d906adc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/gui/torrentcontentfiltermodel.cpp
  2. 178
      src/gui/torrentcontentmodel.cpp
  3. 6
      src/gui/torrentcontentmodel.h

8
src/gui/torrentcontentfiltermodel.cpp

@ -110,17 +110,13 @@ bool TorrentContentFilterModel::lessThan(const QModelIndex &left, const QModelIn @@ -110,17 +110,13 @@ bool TorrentContentFilterModel::lessThan(const QModelIndex &left, const QModelIn
void TorrentContentFilterModel::selectAll()
{
for (int i = 0; i < rowCount(); ++i)
setData(index(i, 0), Qt::Checked, Qt::CheckStateRole);
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
setData(index(i, TorrentContentModelItem::COL_NAME), Qt::Checked, Qt::CheckStateRole);
}
void TorrentContentFilterModel::selectNone()
{
for (int i = 0; i < rowCount(); ++i)
setData(index(i, 0), Qt::Unchecked, Qt::CheckStateRole);
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
setData(index(i, TorrentContentModelItem::COL_NAME), Qt::Unchecked, Qt::CheckStateRole);
}
bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const

178
src/gui/torrentcontentmodel.cpp

@ -220,7 +220,7 @@ void TorrentContentModel::updateFilesProgress(const QVector<qreal> &fp) @@ -220,7 +220,7 @@ void TorrentContentModel::updateFilesProgress(const QVector<qreal> &fp)
// Update folders progress in the tree
m_rootItem->recalculateProgress();
m_rootItem->recalculateAvailability();
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
notifyModelUpdate(index(0, 0));
}
void TorrentContentModel::updateFilesPriorities(const QVector<BitTorrent::DownloadPriority> &fprio)
@ -233,7 +233,7 @@ void TorrentContentModel::updateFilesPriorities(const QVector<BitTorrent::Downlo @@ -233,7 +233,7 @@ void TorrentContentModel::updateFilesPriorities(const QVector<BitTorrent::Downlo
emit layoutAboutToBeChanged();
for (int i = 0; i < fprio.size(); ++i)
m_filesIndex[i]->setPriority(static_cast<BitTorrent::DownloadPriority>(fprio[i]));
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
notifyModelUpdate(index(0, 0));
}
void TorrentContentModel::updateFilesAvailability(const QVector<qreal> &fa)
@ -247,7 +247,7 @@ void TorrentContentModel::updateFilesAvailability(const QVector<qreal> &fa) @@ -247,7 +247,7 @@ void TorrentContentModel::updateFilesAvailability(const QVector<qreal> &fa)
m_filesIndex[i]->setAvailability(fa[i]);
// Update folders progress in the tree
m_rootItem->recalculateProgress();
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
notifyModelUpdate(index(0, 0));
}
QVector<BitTorrent::DownloadPriority> TorrentContentModel::getFilePriorities() const
@ -269,66 +269,83 @@ bool TorrentContentModel::allFiltered() const @@ -269,66 +269,83 @@ bool TorrentContentModel::allFiltered() const
int TorrentContentModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return static_cast<TorrentContentModelItem*>(parent.internalPointer())->columnCount();
return m_rootItem->columnCount();
Q_UNUSED(parent);
return TorrentContentModelItem::NB_COL;
}
bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &value, int role)
bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &value, const int role)
{
if (!index.isValid())
return false;
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole))
{
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
qDebug("setData(%s, %d)", qUtf8Printable(item->name()), value.toInt());
auto *item = static_cast<TorrentContentModelItem *>(index.internalPointer());
BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal;
if (value.toInt() == Qt::PartiallyChecked)
prio = BitTorrent::DownloadPriority::Mixed;
else if (value.toInt() == Qt::Unchecked)
prio = BitTorrent::DownloadPriority::Ignored;
const BitTorrent::DownloadPriority currentPrio = item->priority();
const auto checkState = static_cast<Qt::CheckState>(value.toInt());
const BitTorrent::DownloadPriority newPrio = (checkState == Qt::PartiallyChecked)
? BitTorrent::DownloadPriority::Mixed
: ((checkState == Qt::Unchecked)
? BitTorrent::DownloadPriority::Ignored
: BitTorrent::DownloadPriority::Normal);
if (item->priority() != prio)
if (currentPrio != newPrio)
{
item->setPriority(prio);
item->setPriority(newPrio);
// Update folders progress in the tree
m_rootItem->recalculateProgress();
m_rootItem->recalculateAvailability();
emit dataChanged(this->index(0, 0), this->index((rowCount() - 1), (columnCount() - 1)));
notifyModelUpdate(index);
emit filteredFilesChanged();
return true;
}
return true;
}
if (role == Qt::EditRole)
{
Q_ASSERT(index.isValid());
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
auto *item = static_cast<TorrentContentModelItem *>(index.internalPointer());
switch (index.column())
{
case TorrentContentModelItem::COL_NAME:
item->setName(value.toString());
{
const QString currentName = item->name();
const QString newName = value.toString();
if (currentName != newName)
{
item->setName(newName);
emit dataChanged(index, index);
return true;
}
}
break;
case TorrentContentModelItem::COL_PRIO:
{
const BitTorrent::DownloadPriority previousPrio = item->priority();
const BitTorrent::DownloadPriority currentPrio = item->priority();
const auto newPrio = static_cast<BitTorrent::DownloadPriority>(value.toInt());
item->setPriority(newPrio);
if ((newPrio != previousPrio) && ((newPrio == BitTorrent::DownloadPriority::Ignored)
|| (previousPrio == BitTorrent::DownloadPriority::Ignored)))
if (currentPrio != newPrio)
{
emit filteredFilesChanged();
item->setPriority(newPrio);
notifyModelUpdate(index);
if ((newPrio == BitTorrent::DownloadPriority::Ignored)
|| (currentPrio == BitTorrent::DownloadPriority::Ignored))
{
emit filteredFilesChanged();
}
return true;
}
}
break;
default:
return false;
break;
}
emit dataChanged(index, index);
return true;
}
return false;
@ -336,14 +353,14 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu @@ -336,14 +353,14 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu
TorrentContentModelItem::ItemType TorrentContentModel::itemType(const QModelIndex &index) const
{
return static_cast<const TorrentContentModelItem*>(index.internalPointer())->itemType();
return static_cast<const TorrentContentModelItem *>(index.internalPointer())->itemType();
}
int TorrentContentModel::getFileIndex(const QModelIndex &index)
{
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
auto *item = static_cast<TorrentContentModelItem *>(index.internalPointer());
if (item->itemType() == TorrentContentModelItem::FileType)
return static_cast<TorrentContentModelFile*>(item)->fileIndex();
return static_cast<TorrentContentModelFile *>(item)->fileIndex();
Q_ASSERT(item->itemType() == TorrentContentModelItem::FileType);
return -1;
@ -354,7 +371,7 @@ QVariant TorrentContentModel::data(const QModelIndex &index, const int role) con @@ -354,7 +371,7 @@ QVariant TorrentContentModel::data(const QModelIndex &index, const int role) con
if (!index.isValid())
return {};
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
auto *item = static_cast<TorrentContentModelItem *>(index.internalPointer());
switch (role)
{
@ -392,8 +409,10 @@ QVariant TorrentContentModel::data(const QModelIndex &index, const int role) con @@ -392,8 +409,10 @@ QVariant TorrentContentModel::data(const QModelIndex &index, const int role) con
return item->underlyingData(index.column());
default:
return {};
break;
}
return {};
}
Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const
@ -431,19 +450,14 @@ QVariant TorrentContentModel::headerData(int section, Qt::Orientation orientatio @@ -431,19 +450,14 @@ QVariant TorrentContentModel::headerData(int section, Qt::Orientation orientatio
}
}
QModelIndex TorrentContentModel::index(int row, int column, const QModelIndex &parent) const
QModelIndex TorrentContentModel::index(const int row, const int column, const QModelIndex &parent) const
{
if (parent.isValid() && (parent.column() != 0))
return {};
if (column >= TorrentContentModelItem::NB_COL)
if (column >= columnCount())
return {};
TorrentContentModelFolder *parentItem = nullptr;
if (!parent.isValid())
parentItem = m_rootItem;
else
parentItem = static_cast<TorrentContentModelFolder*>(parent.internalPointer());
const TorrentContentModelFolder *parentItem = parent.isValid()
? static_cast<TorrentContentModelFolder *>(parent.internalPointer())
: m_rootItem;
Q_ASSERT(parentItem);
if (row >= parentItem->childCount())
@ -452,6 +466,7 @@ QModelIndex TorrentContentModel::index(int row, int column, const QModelIndex &p @@ -452,6 +466,7 @@ QModelIndex TorrentContentModel::index(int row, int column, const QModelIndex &p
TorrentContentModelItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
return {};
}
@ -460,28 +475,26 @@ QModelIndex TorrentContentModel::parent(const QModelIndex &index) const @@ -460,28 +475,26 @@ QModelIndex TorrentContentModel::parent(const QModelIndex &index) const
if (!index.isValid())
return {};
auto *childItem = static_cast<TorrentContentModelItem*>(index.internalPointer());
if (!childItem)
const auto *item = static_cast<TorrentContentModelItem *>(index.internalPointer());
if (!item)
return {};
TorrentContentModelItem *parentItem = childItem->parent();
TorrentContentModelItem *parentItem = item->parent();
if (parentItem == m_rootItem)
return {};
// From https://doc.qt.io/qt-6/qabstractitemmodel.html#parent:
// A common convention used in models that expose tree data structures is that only items
// in the first column have children. For that case, when reimplementing this function in
// a subclass the column of the returned QModelIndex would be 0.
return createIndex(parentItem->row(), 0, parentItem);
}
int TorrentContentModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() > 0)
return 0;
TorrentContentModelFolder *parentItem = nullptr;
if (!parent.isValid())
parentItem = m_rootItem;
else
parentItem = dynamic_cast<TorrentContentModelFolder*>(static_cast<TorrentContentModelItem*>(parent.internalPointer()));
const TorrentContentModelFolder *parentItem = parent.isValid()
? dynamic_cast<TorrentContentModelFolder *>(static_cast<TorrentContentModelItem *>(parent.internalPointer()))
: m_rootItem;
return parentItem ? parentItem->childCount() : 0;
}
@ -551,20 +564,47 @@ void TorrentContentModel::setupModelData(const BitTorrent::AbstractFileStorage & @@ -551,20 +564,47 @@ void TorrentContentModel::setupModelData(const BitTorrent::AbstractFileStorage &
emit layoutChanged();
}
void TorrentContentModel::selectAll()
void TorrentContentModel::notifyModelUpdate(const QModelIndex &index)
{
for (int i = 0; i < m_rootItem->childCount(); ++i)
Q_ASSERT(index.isValid());
const int lastColumnIndex = columnCount(index) - 1;
// emit itself
emit dataChanged(index.siblingAtColumn(0), index.siblingAtColumn(lastColumnIndex));
// propagate up the model
QModelIndex parentIndex = parent(index);
while (parentIndex.isValid())
{
TorrentContentModelItem* child = m_rootItem->child(i);
if (child->priority() == BitTorrent::DownloadPriority::Ignored)
child->setPriority(BitTorrent::DownloadPriority::Normal);
emit dataChanged(parentIndex.siblingAtColumn(0), parentIndex.siblingAtColumn(lastColumnIndex));
parentIndex = parent(parentIndex);
}
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
}
void TorrentContentModel::selectNone()
{
for (int i = 0; i < m_rootItem->childCount(); ++i)
m_rootItem->child(i)->setPriority(BitTorrent::DownloadPriority::Ignored);
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
// propagate down the model
QVector<QModelIndex> parentIndexes;
if (hasChildren(index))
parentIndexes.push_back(index);
while (!parentIndexes.isEmpty())
{
const QModelIndex parent = parentIndexes.takeLast();
const int childCount = rowCount(parent);
const QModelIndex childTopLeft = this->index(0, 0, parent);
const QModelIndex childBottomRight = this->index((childCount - 1), lastColumnIndex, parent);
// emit this generation
emit dataChanged(childTopLeft, childBottomRight);
// check generations further down
parentIndexes.reserve(childCount);
for (int i = 0; i < childCount; ++i)
{
const QModelIndex child = childTopLeft.siblingAtRow(i);
if (hasChildren(child))
parentIndexes.push_back(child);
}
}
}

6
src/gui/torrentcontentmodel.h

@ -79,11 +79,9 @@ public: @@ -79,11 +79,9 @@ public:
signals:
void filteredFilesChanged();
public slots:
void selectAll();
void selectNone();
private:
void notifyModelUpdate(const QModelIndex &index);
TorrentContentModelFolder *m_rootItem = nullptr;
QVector<TorrentContentModelFile *> m_filesIndex;
QFileIconProvider *m_fileIconProvider = nullptr;

Loading…
Cancel
Save