Only emit headerDataChanged for valid proxy intervals.
Modeltest asserts before the patch, and passes afterward. Task-number: QTBUG-26515 Change-Id: I08a89cd5c9c59613badcddbd056a3d0b8fbbca13 Reviewed-by: Marc Mutz <marc.mutz@kdab.com> Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
This commit is contained in:
parent
fb07ce50ae
commit
da64a50792
@ -1226,15 +1226,43 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
|
||||
void QSortFilterProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation,
|
||||
int start, int end)
|
||||
{
|
||||
Q_ASSERT(start <= end);
|
||||
|
||||
Q_Q(QSortFilterProxyModel);
|
||||
Mapping *m = create_mapping(QModelIndex()).value();
|
||||
int proxy_start = (orientation == Qt::Vertical
|
||||
? m->proxy_rows.at(start)
|
||||
: m->proxy_columns.at(start));
|
||||
int proxy_end = (orientation == Qt::Vertical
|
||||
? m->proxy_rows.at(end)
|
||||
: m->proxy_columns.at(end));
|
||||
emit q->headerDataChanged(orientation, proxy_start, proxy_end);
|
||||
|
||||
const QVector<int> &source_to_proxy = (orientation == Qt::Vertical) ? m->proxy_rows : m->proxy_columns;
|
||||
|
||||
QVector<int> proxy_positions;
|
||||
proxy_positions.reserve(end - start + 1);
|
||||
{
|
||||
Q_ASSERT(source_to_proxy.size() > end);
|
||||
QVector<int>::const_iterator it = source_to_proxy.constBegin() + start;
|
||||
const QVector<int>::const_iterator endIt = source_to_proxy.constBegin() + end + 1;
|
||||
for ( ; it != endIt; ++it) {
|
||||
if (*it != -1)
|
||||
proxy_positions.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
qSort(proxy_positions);
|
||||
|
||||
int last_index = 0;
|
||||
const int numItems = proxy_positions.size();
|
||||
while (last_index < numItems) {
|
||||
const int proxyStart = proxy_positions.at(last_index);
|
||||
int proxyEnd = proxyStart;
|
||||
++last_index;
|
||||
for (int i = last_index; i < numItems; ++i) {
|
||||
if (proxy_positions.at(i) == proxyEnd + 1) {
|
||||
++last_index;
|
||||
++proxyEnd;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit q->headerDataChanged(orientation, proxyStart, proxyEnd);
|
||||
}
|
||||
}
|
||||
|
||||
void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset()
|
||||
|
@ -140,6 +140,7 @@ private slots:
|
||||
void testMultipleProxiesWithSelection();
|
||||
void mapSelectionFromSource();
|
||||
void filteredColumns();
|
||||
void headerDataChanged();
|
||||
|
||||
void testParentLayoutChanged();
|
||||
void moveSourceRows();
|
||||
@ -3155,6 +3156,40 @@ void tst_QSortFilterProxyModel::filteredColumns()
|
||||
insertCommand->doCommand();
|
||||
}
|
||||
|
||||
class ChangableHeaderData : public QStringListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ChangableHeaderData(QObject *parent = 0)
|
||||
: QStringListModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void emitHeaderDataChanged()
|
||||
{
|
||||
headerDataChanged(Qt::Vertical, 0, rowCount() - 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void tst_QSortFilterProxyModel::headerDataChanged()
|
||||
{
|
||||
ChangableHeaderData *model = new ChangableHeaderData(this);
|
||||
|
||||
QStringList numbers;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
numbers.append(QString::number(i));
|
||||
model->setStringList(numbers);
|
||||
|
||||
QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
|
||||
proxy->setSourceModel(model);
|
||||
|
||||
new ModelTest(proxy, this);
|
||||
|
||||
model->emitHeaderDataChanged();
|
||||
}
|
||||
|
||||
void tst_QSortFilterProxyModel::resetInvalidate_data()
|
||||
{
|
||||
QTest::addColumn<int>("test");
|
||||
|
@ -80,7 +80,7 @@ ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject (
|
||||
connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
|
||||
this, SLOT ( runAllTests() ) );
|
||||
|
||||
// Special checks for inserting/removing
|
||||
// Special checks for changes
|
||||
connect ( model, SIGNAL ( layoutAboutToBeChanged() ),
|
||||
this, SLOT ( layoutAboutToBeChanged() ) );
|
||||
connect ( model, SIGNAL ( layoutChanged() ),
|
||||
@ -94,6 +94,10 @@ ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject (
|
||||
this, SLOT ( rowsInserted ( const QModelIndex &, int, int ) ) );
|
||||
connect ( model, SIGNAL ( rowsRemoved ( const QModelIndex &, int, int ) ),
|
||||
this, SLOT ( rowsRemoved ( const QModelIndex &, int, int ) ) );
|
||||
connect ( model, SIGNAL ( dataChanged ( const QModelIndex &, const QModelIndex & ) ),
|
||||
this, SLOT ( dataChanged ( const QModelIndex &, const QModelIndex & ) ) );
|
||||
connect ( model, SIGNAL ( headerDataChanged ( Qt::Orientation, int, int ) ),
|
||||
this, SLOT ( headerDataChanged ( Qt::Orientation, int, int ) ) );
|
||||
|
||||
runAllTests();
|
||||
}
|
||||
@ -561,4 +565,27 @@ void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
|
||||
QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) );
|
||||
}
|
||||
|
||||
void ModelTest::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
||||
{
|
||||
QVERIFY(topLeft.isValid());
|
||||
QVERIFY(bottomRight.isValid());
|
||||
QModelIndex commonParent = bottomRight.parent();
|
||||
QVERIFY(topLeft.parent() == commonParent);
|
||||
QVERIFY(topLeft.row() <= bottomRight.row());
|
||||
QVERIFY(topLeft.column() <= bottomRight.column());
|
||||
int rowCount = model->rowCount(commonParent);
|
||||
int columnCount = model->columnCount(commonParent);
|
||||
QVERIFY(bottomRight.row() < rowCount);
|
||||
QVERIFY(bottomRight.column() < columnCount);
|
||||
}
|
||||
|
||||
void ModelTest::headerDataChanged(Qt::Orientation orientation, int start, int end)
|
||||
{
|
||||
QVERIFY(start >= 0);
|
||||
QVERIFY(end >= 0);
|
||||
QVERIFY(start <= end);
|
||||
int itemCount = orientation == Qt::Vertical ? model->rowCount() : model->columnCount();
|
||||
QVERIFY(start < itemCount);
|
||||
QVERIFY(end < itemCount);
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,8 @@ protected Q_SLOTS:
|
||||
void rowsInserted( const QModelIndex & parent, int start, int end );
|
||||
void rowsAboutToBeRemoved( const QModelIndex &parent, int start, int end );
|
||||
void rowsRemoved( const QModelIndex & parent, int start, int end );
|
||||
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
void headerDataChanged(Qt::Orientation orientation, int start, int end);
|
||||
|
||||
private:
|
||||
void checkChildren( const QModelIndex &parent, int currentDepth = 0 );
|
||||
|
Loading…
Reference in New Issue
Block a user