QHeaderView: fix inconsistent saved state, ignored during restore

The code that updates a section size must also update length,
otherwise saveState can end up saving inconsistent state, and
restoreState() goes to an early-return, not doing anything.

The actual bug was fixed meanwhile because _q_sectionsChanged is called
again, which recalculates length. I still see this only as a safety
measure, every other code path that changes section sizes updates length
right away.

Change-Id: I6cc16261692d93b3640afafef600a5bdff8dca0c
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
This commit is contained in:
David Faure 2018-03-01 11:04:00 +01:00 committed by Thorbjørn Lund Martsum
parent 3eb42abab6
commit 4a04eea4f4
2 changed files with 58 additions and 1 deletions

View File

@ -2191,7 +2191,11 @@ void QHeaderViewPrivate::_q_sectionsAboutToBeChanged(const QList<QPersistentMode
if (stretchLastSection && lastSectionLogicalIdx >= 0 && lastSectionLogicalIdx < sectionItems.count()) {
const int visual = visualIndex(lastSectionLogicalIdx);
if (visual >= 0 && visual < sectionItems.size()) {
sectionItems[visual].size = lastSectionSize;
auto &itemRef = sectionItems[visual];
if (itemRef.size != lastSectionSize) {
length += lastSectionSize - itemRef.size;
itemRef.size = lastSectionSize;
}
}
}
for (int i = 0; i < sectionItems.size(); ++i) {

View File

@ -162,6 +162,7 @@ private slots:
void renderToPixmap();
void styleOptionViewItem();
void keyboardNavigationWithDisabled();
void saveRestoreState();
void statusTip_data();
void statusTip();
@ -4076,6 +4077,58 @@ void tst_QTreeView::keyboardNavigationWithDisabled()
QCOMPARE(view.currentIndex(), model.index(6, 0));
}
class RemoveColumnOne : public QSortFilterProxyModel
{
public:
bool filterAcceptsColumn(int source_column, const QModelIndex &) const override
{
if (m_removeColumn)
return source_column != 1;
return true;
}
void removeColumn()
{
m_removeColumn = true;
invalidate();
}
private:
bool m_removeColumn = false;
};
void tst_QTreeView::saveRestoreState()
{
QStandardItemModel model;
for (int i = 0; i < 100; i++) {
QList<QStandardItem *> items;
items << new QStandardItem(QLatin1String("item ") + QString::number(i)) << new QStandardItem(QStringLiteral("hidden by proxy")) << new QStandardItem(QStringLiteral("hidden by user"));
model.appendRow(items);
}
QCOMPARE(model.columnCount(), 3);
RemoveColumnOne proxy;
proxy.setSourceModel(&model);
QCOMPARE(proxy.columnCount(), 3);
QTreeView view;
view.setModel(&proxy);
view.resize(500, 500);
view.show();
view.header()->hideSection(2);
QVERIFY(view.header()->isSectionHidden(2));
proxy.removeColumn();
QCOMPARE(proxy.columnCount(), 2);
QVERIFY(view.header()->isSectionHidden(1));
const QByteArray data = view.header()->saveState();
QTreeView view2;
view2.setModel(&proxy);
view2.resize(500, 500);
view2.show();
view2.header()->restoreState(data);
QVERIFY(view2.header()->isSectionHidden(1));
}
class Model_11466 : public QAbstractItemModel
{
Q_OBJECT