QGIM: override sibling() to avoid the roundtrip through parent()
Change-Id: I91bc8d3e94d35fb30bc4886ba6be554ca7cf866b Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
This commit is contained in:
parent
4b198c5e64
commit
0ae202c2a7
@ -448,6 +448,22 @@ QModelIndex QGenericItemModel::parent(const QModelIndex &child) const
|
||||
return impl->callConst<QModelIndex>(QGenericItemModelImplBase::Parent, child);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
|
||||
Returns the sibling at \a row and \a column for the item at \a index, or an
|
||||
invalid QModelIndex if there is no sibling at that location.
|
||||
|
||||
This implementation is significantly faster than going through the parent()
|
||||
of the \a index.
|
||||
|
||||
\sa index(), QModelIndex::row(), QModelIndex::column()
|
||||
*/
|
||||
QModelIndex QGenericItemModel::sibling(int row, int column, const QModelIndex &index) const
|
||||
{
|
||||
return impl->callConst<QModelIndex>(QGenericItemModelImplBase::Sibling, row, column, index);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
QModelIndex sibling(int row, int column, const QModelIndex &index) const override;
|
||||
int rowCount(const QModelIndex &parent = {}) const override;
|
||||
int columnCount(const QModelIndex &parent = {}) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
@ -210,6 +211,8 @@ public:
|
||||
break;
|
||||
case Parent: makeCall(that, &Structure::parent, r, args);
|
||||
break;
|
||||
case Sibling: makeCall(that, &Self::sibling, r, args);
|
||||
break;
|
||||
case RowCount: makeCall(that, &Structure::rowCount, r, args);
|
||||
break;
|
||||
case ColumnCount: makeCall(that, &Structure::columnCount, r, args);
|
||||
@ -258,6 +261,24 @@ public:
|
||||
return that().indexImpl(row, column, parent);
|
||||
}
|
||||
|
||||
QModelIndex sibling(int row, int column, const QModelIndex &index) const
|
||||
{
|
||||
if (row == index.row() && column == index.column())
|
||||
return index;
|
||||
|
||||
if (column < 0 || column >= m_itemModel->columnCount())
|
||||
return {};
|
||||
|
||||
if (row == index.row())
|
||||
return createIndex(row, column, index.constInternalPointer());
|
||||
|
||||
const_row_ptr parentRow = static_cast<const_row_ptr>(index.constInternalPointer());
|
||||
const auto siblingCount = size(that().childrenOf(parentRow));
|
||||
if (row < 0 || row >= int(siblingCount))
|
||||
return {};
|
||||
return createIndex(row, column, parentRow);
|
||||
}
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
@ -1199,7 +1220,6 @@ protected:
|
||||
return std::addressof(*children);
|
||||
}
|
||||
|
||||
private:
|
||||
const range_type &childrenOf(const_row_ptr row) const
|
||||
{
|
||||
if (!row)
|
||||
@ -1210,6 +1230,7 @@ private:
|
||||
return *m_protocol.childRows(*row);
|
||||
}
|
||||
|
||||
private:
|
||||
range_type &childrenOf(row_ptr row)
|
||||
{
|
||||
if (!row)
|
||||
@ -1232,6 +1253,7 @@ class QGenericTableItemModelImpl
|
||||
using range_type = typename Base::range_type;
|
||||
using range_features = typename Base::range_features;
|
||||
using row_type = typename Base::row_type;
|
||||
using const_row_ptr = typename Base::const_row_ptr;
|
||||
using row_traits = typename Base::row_traits;
|
||||
using row_features = typename Base::row_features;
|
||||
|
||||
@ -1350,6 +1372,12 @@ protected:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const range_type &childrenOf(const_row_ptr row) const
|
||||
{
|
||||
Q_ASSERT(!row);
|
||||
return *this->m_data.model();
|
||||
}
|
||||
|
||||
void resetParentInChildren(range_type *)
|
||||
{
|
||||
}
|
||||
|
@ -458,6 +458,7 @@ public:
|
||||
enum ConstOp {
|
||||
Index,
|
||||
Parent,
|
||||
Sibling,
|
||||
RowCount,
|
||||
ColumnCount,
|
||||
Flags,
|
||||
|
@ -292,6 +292,8 @@ private slots:
|
||||
|
||||
void dimensions_data() { createTestData(); }
|
||||
void dimensions();
|
||||
void sibling_data() { createTestData(); }
|
||||
void sibling();
|
||||
void flags_data() { createTestData(); }
|
||||
void flags();
|
||||
void data_data() { createTestData(); }
|
||||
@ -892,6 +894,31 @@ void tst_QGenericItemModel::dimensions()
|
||||
QCOMPARE(model->columnCount(), expectedColumnCount);
|
||||
}
|
||||
|
||||
void tst_QGenericItemModel::sibling()
|
||||
{
|
||||
QFETCH(Factory, factory);
|
||||
auto model = factory();
|
||||
|
||||
QModelIndex withChildren;
|
||||
const auto test = [model = model.get(), &withChildren](const QModelIndex &parent){
|
||||
const QModelIndex first = model->index(0, 0, parent);
|
||||
// deliberately requesting siblings outside of the range
|
||||
for (int r = 0; r < model->rowCount() + 1; ++r) {
|
||||
for (int c = 0; c < model->columnCount() + 1; ++c) {
|
||||
const QModelIndex next = model->sibling(r, c, first);
|
||||
const QModelIndex qaimNext = model->QAbstractItemModel::sibling(r, c, first);
|
||||
if (!withChildren.isValid() && model->hasChildren(next))
|
||||
withChildren = next;
|
||||
QCOMPARE(next, qaimNext);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
test({});
|
||||
if (withChildren.isValid())
|
||||
test(withChildren);
|
||||
}
|
||||
|
||||
void tst_QGenericItemModel::flags()
|
||||
{
|
||||
QFETCH(Factory, factory);
|
||||
|
Loading…
x
Reference in New Issue
Block a user