QConcatenateTablesProxyModel: react to row and column moves
Fixes: QTBUG-128742 Change-Id: I6282c3c9f27c435da5d511c61fbb051da127229c Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> (cherry picked from commit b9ba28315d889d0b87ae048dffe33eac55efcda2) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
1ba89701fa
commit
d53c3809de
@ -30,10 +30,18 @@ public:
|
|||||||
void slotRowsInserted(const QModelIndex &, int start, int end);
|
void slotRowsInserted(const QModelIndex &, int start, int end);
|
||||||
void slotRowsAboutToBeRemoved(const QModelIndex &, int start, int end);
|
void slotRowsAboutToBeRemoved(const QModelIndex &, int start, int end);
|
||||||
void slotRowsRemoved(const QModelIndex &, int start, int end);
|
void slotRowsRemoved(const QModelIndex &, int start, int end);
|
||||||
|
void slotRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent, int destinationRow);
|
||||||
|
void slotRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent, int destinationRow);
|
||||||
void slotColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
|
void slotColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
|
||||||
void slotColumnsInserted(const QModelIndex &parent, int, int);
|
void slotColumnsInserted(const QModelIndex &parent, int, int);
|
||||||
void slotColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
void slotColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||||||
void slotColumnsRemoved(const QModelIndex &parent, int, int);
|
void slotColumnsRemoved(const QModelIndex &parent, int, int);
|
||||||
|
void slotColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent, int destination);
|
||||||
|
void slotColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent, int destination);
|
||||||
void slotDataChanged(const QModelIndex &from, const QModelIndex &to, const QList<int> &roles);
|
void slotDataChanged(const QModelIndex &from, const QModelIndex &to, const QList<int> &roles);
|
||||||
void slotSourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
|
void slotSourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
|
||||||
void slotSourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
|
void slotSourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
|
||||||
@ -46,7 +54,7 @@ public:
|
|||||||
int *sourceRow, int *sourceColumn, QModelIndex *sourceParent, QAbstractItemModel **sourceModel) const;
|
int *sourceRow, int *sourceColumn, QModelIndex *sourceParent, QAbstractItemModel **sourceModel) const;
|
||||||
|
|
||||||
struct ModelInfo {
|
struct ModelInfo {
|
||||||
using ConnArray = std::array<QMetaObject::Connection, 13>;
|
using ConnArray = std::array<QMetaObject::Connection, 17>;
|
||||||
ModelInfo(QAbstractItemModel *m, ConnArray &&con)
|
ModelInfo(QAbstractItemModel *m, ConnArray &&con)
|
||||||
: model(m), connections(std::move(con)) {}
|
: model(m), connections(std::move(con)) {}
|
||||||
QAbstractItemModel *model = nullptr;
|
QAbstractItemModel *model = nullptr;
|
||||||
@ -472,6 +480,10 @@ void QConcatenateTablesProxyModel::addSourceModel(QAbstractItemModel *sourceMode
|
|||||||
d, &QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeInserted),
|
d, &QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeInserted),
|
||||||
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved,
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved,
|
||||||
d, &QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeRemoved),
|
d, &QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeRemoved),
|
||||||
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::rowsMoved,
|
||||||
|
d, &QConcatenateTablesProxyModelPrivate::slotRowsMoved),
|
||||||
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::rowsAboutToBeMoved,
|
||||||
|
d, &QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeMoved),
|
||||||
|
|
||||||
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::columnsInserted,
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::columnsInserted,
|
||||||
d, &QConcatenateTablesProxyModelPrivate::slotColumnsInserted),
|
d, &QConcatenateTablesProxyModelPrivate::slotColumnsInserted),
|
||||||
@ -481,6 +493,10 @@ void QConcatenateTablesProxyModel::addSourceModel(QAbstractItemModel *sourceMode
|
|||||||
d, &QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeInserted),
|
d, &QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeInserted),
|
||||||
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::columnsAboutToBeRemoved,
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::columnsAboutToBeRemoved,
|
||||||
d, &QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeRemoved),
|
d, &QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeRemoved),
|
||||||
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::columnsMoved,
|
||||||
|
d, &QConcatenateTablesProxyModelPrivate::slotColumnsMoved),
|
||||||
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::columnsAboutToBeMoved,
|
||||||
|
d, &QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeMoved),
|
||||||
|
|
||||||
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::layoutAboutToBeChanged,
|
QObjectPrivate::connect(sourceModel, &QAbstractItemModel::layoutAboutToBeChanged,
|
||||||
d, &QConcatenateTablesProxyModelPrivate::slotSourceLayoutAboutToBeChanged),
|
d, &QConcatenateTablesProxyModelPrivate::slotSourceLayoutAboutToBeChanged),
|
||||||
@ -565,6 +581,33 @@ void QConcatenateTablesProxyModelPrivate::slotRowsRemoved(const QModelIndex &par
|
|||||||
q->endRemoveRows();
|
q->endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeMoved(
|
||||||
|
const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent, int destinationRow)
|
||||||
|
{
|
||||||
|
Q_Q(QConcatenateTablesProxyModel);
|
||||||
|
if (sourceParent.isValid() || destinationParent.isValid())
|
||||||
|
return;
|
||||||
|
const QAbstractItemModel *const model = static_cast<QAbstractItemModel *>(q->sender());
|
||||||
|
const int rowsPrior = computeRowsPrior(model);
|
||||||
|
q->beginMoveRows(sourceParent, rowsPrior + sourceStart, rowsPrior + sourceEnd,
|
||||||
|
destinationParent, rowsPrior + destinationRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QConcatenateTablesProxyModelPrivate::slotRowsMoved(const QModelIndex &sourceParent,
|
||||||
|
int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent,
|
||||||
|
int destinationRow)
|
||||||
|
{
|
||||||
|
Q_Q(QConcatenateTablesProxyModel);
|
||||||
|
Q_UNUSED(sourceStart)
|
||||||
|
Q_UNUSED(sourceEnd)
|
||||||
|
Q_UNUSED(destinationRow)
|
||||||
|
if (sourceParent.isValid() || destinationParent.isValid())
|
||||||
|
return;
|
||||||
|
q->endMoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
void QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeInserted(const QModelIndex &parent,
|
void QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeInserted(const QModelIndex &parent,
|
||||||
int start, int end)
|
int start, int end)
|
||||||
{
|
{
|
||||||
@ -625,6 +668,31 @@ void QConcatenateTablesProxyModelPrivate::slotColumnsRemoved(const QModelIndex &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QConcatenateTablesProxyModelPrivate::slotColumnsAboutToBeMoved(
|
||||||
|
const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent, int destination)
|
||||||
|
{
|
||||||
|
Q_UNUSED(sourceStart)
|
||||||
|
Q_UNUSED(sourceEnd)
|
||||||
|
Q_UNUSED(destination)
|
||||||
|
if (sourceParent.isValid() || destinationParent.isValid())
|
||||||
|
return;
|
||||||
|
slotSourceLayoutAboutToBeChanged({}, QAbstractItemModel::HorizontalSortHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QConcatenateTablesProxyModelPrivate::slotColumnsMoved(const QModelIndex &sourceParent,
|
||||||
|
int sourceStart, int sourceEnd,
|
||||||
|
const QModelIndex &destinationParent,
|
||||||
|
int destination)
|
||||||
|
{
|
||||||
|
Q_UNUSED(sourceStart)
|
||||||
|
Q_UNUSED(sourceEnd)
|
||||||
|
Q_UNUSED(destination)
|
||||||
|
if (sourceParent.isValid() || destinationParent.isValid())
|
||||||
|
return;
|
||||||
|
slotSourceLayoutChanged({}, QAbstractItemModel::HorizontalSortHint);
|
||||||
|
}
|
||||||
|
|
||||||
void QConcatenateTablesProxyModelPrivate::slotDataChanged(const QModelIndex &from,
|
void QConcatenateTablesProxyModelPrivate::slotDataChanged(const QModelIndex &from,
|
||||||
const QModelIndex &to,
|
const QModelIndex &to,
|
||||||
const QList<int> &roles)
|
const QList<int> &roles)
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
#include <QAbstractItemModelTester>
|
#include <QAbstractItemModelTester>
|
||||||
|
#include <QTransposeProxyModel>
|
||||||
|
|
||||||
#include <qconcatenatetablesproxymodel.h>
|
#include <qconcatenatetablesproxymodel.h>
|
||||||
|
|
||||||
@ -72,6 +73,8 @@ private Q_SLOTS:
|
|||||||
void shouldIncreaseColumnCountWhenRemovingFirstModel();
|
void shouldIncreaseColumnCountWhenRemovingFirstModel();
|
||||||
void shouldHandleColumnInsertionAndRemoval();
|
void shouldHandleColumnInsertionAndRemoval();
|
||||||
void shouldPropagateLayoutChanged();
|
void shouldPropagateLayoutChanged();
|
||||||
|
void shouldPropagateRowMove();
|
||||||
|
void shouldPropagateColumnMove();
|
||||||
void shouldReactToModelReset();
|
void shouldReactToModelReset();
|
||||||
void shouldUpdateColumnsOnModelReset();
|
void shouldUpdateColumnsOnModelReset();
|
||||||
void shouldPropagateDropOnItem_data();
|
void shouldPropagateDropOnItem_data();
|
||||||
@ -545,6 +548,68 @@ void tst_QConcatenateTablesProxyModel::shouldPropagateLayoutChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QConcatenateTablesProxyModel::shouldPropagateRowMove()
|
||||||
|
{
|
||||||
|
// Given two source models (which support moving rows)
|
||||||
|
QStringListModel model1({ "0", "1", "2" });
|
||||||
|
QStringListModel model2({ "A", "B", "C" });
|
||||||
|
QConcatenateTablesProxyModel proxy;
|
||||||
|
new QAbstractItemModelTester(&proxy, &proxy);
|
||||||
|
proxy.addSourceModel(&model1);
|
||||||
|
proxy.addSourceModel(&model2);
|
||||||
|
QCOMPARE(extractColumnTexts(&proxy, 0), QStringLiteral("012ABC"));
|
||||||
|
QSignalSpy rowsATBMSpy(&proxy, &QAbstractItemModel::rowsAboutToBeMoved);
|
||||||
|
QSignalSpy rowsMovedSpy(&proxy, &QAbstractItemModel::rowsMoved);
|
||||||
|
|
||||||
|
// When moving a row
|
||||||
|
QVERIFY(model2.moveRow({}, 0, {}, 2));
|
||||||
|
|
||||||
|
// Then
|
||||||
|
QCOMPARE(extractColumnTexts(&proxy, 0), QStringLiteral("012BAC"));
|
||||||
|
QCOMPARE(rowsATBMSpy.count(), 1);
|
||||||
|
QCOMPARE(rowsMovedSpy.count(), 1);
|
||||||
|
QCOMPARE(rowsATBMSpy[0][1].toInt(), 3); // sourceStart
|
||||||
|
QCOMPARE(rowsATBMSpy[0][2].toInt(), 3); // sourceEnd
|
||||||
|
QCOMPARE(rowsATBMSpy[0][4].toInt(), 5); // destinationRow
|
||||||
|
QCOMPARE(rowsMovedSpy[0][1].toInt(), 3); // sourceStart
|
||||||
|
QCOMPARE(rowsMovedSpy[0][2].toInt(), 3); // sourceEnd
|
||||||
|
QCOMPARE(rowsMovedSpy[0][4].toInt(), 5); // destinationRow
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QConcatenateTablesProxyModel::shouldPropagateColumnMove()
|
||||||
|
{
|
||||||
|
// Given two source models (which support moving rows)
|
||||||
|
// and two transpose proxies (so it becomes columns)
|
||||||
|
QStringListModel model1({ "0", "1", "2" });
|
||||||
|
QStringListModel model2({ "A", "B", "C" });
|
||||||
|
QTransposeProxyModel transpose1;
|
||||||
|
QTransposeProxyModel transpose2;
|
||||||
|
transpose1.setSourceModel(&model1);
|
||||||
|
transpose2.setSourceModel(&model2);
|
||||||
|
|
||||||
|
QConcatenateTablesProxyModel proxy;
|
||||||
|
new QAbstractItemModelTester(&proxy, &proxy);
|
||||||
|
proxy.addSourceModel(&transpose1);
|
||||||
|
proxy.addSourceModel(&transpose2);
|
||||||
|
QCOMPARE(extractRowTexts(&proxy, 0), QStringLiteral("012"));
|
||||||
|
QCOMPARE(extractRowTexts(&proxy, 1), QStringLiteral("ABC"));
|
||||||
|
QSignalSpy columnsATBMSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved);
|
||||||
|
QSignalSpy columnsMovedSpy(&proxy, &QAbstractItemModel::columnsMoved);
|
||||||
|
QPersistentModelIndex A(proxy.index(1, 0));
|
||||||
|
QCOMPARE(A.data().toString(), "A");
|
||||||
|
|
||||||
|
// When moving a row in a stringlist model, which moves a column in a transpose proxy
|
||||||
|
QVERIFY(model2.moveRow({}, 0, {}, 2));
|
||||||
|
|
||||||
|
// Then, well, we didn't fully move a column in the concatenate proxy.
|
||||||
|
// It will emit layoutChanged and update persistent indexes, instead.
|
||||||
|
QCOMPARE(extractRowTexts(&proxy, 0), QStringLiteral("012"));
|
||||||
|
QCOMPARE(extractRowTexts(&proxy, 1), QStringLiteral("BAC"));
|
||||||
|
QCOMPARE(columnsATBMSpy.count(), 0);
|
||||||
|
QCOMPARE(columnsMovedSpy.count(), 0);
|
||||||
|
QCOMPARE(A.data().toString(), "A");
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QConcatenateTablesProxyModel::shouldReactToModelReset()
|
void tst_QConcatenateTablesProxyModel::shouldReactToModelReset()
|
||||||
{
|
{
|
||||||
// Given two source models, the second one being a QSFPM
|
// Given two source models, the second one being a QSFPM
|
||||||
|
Loading…
x
Reference in New Issue
Block a user