From 188c2ef11e92d04dcf334309c85a7f1b14945aaa Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 3 Feb 2010 18:00:24 +0100 Subject: QHeaderView: fixes sectionClicked() emitted with wrong section index The obvious fix is to use the previsously computed 'section' as paramatter. (It is even faster) But one might wonder why logicalIndexAt() does not return the same result before and after flipSortIndicator(). The reason is that while being sorted, in _q_layoutChanged, all the hidden section where unhidden and hidden again. Leaving some pending computation. Task-number: QTBUG-7833 Reviewed-by: Gabriel --- src/gui/itemviews/qheaderview.cpp | 14 ++++--- tests/auto/qheaderview/tst_qheaderview.cpp | 64 ++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 8a456e6..1c26e51 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -1853,11 +1853,9 @@ void QHeaderViewPrivate::_q_layoutChanged() persistentHiddenSections.clear(); return; } + + QBitArray oldSectionHidden = sectionHidden; bool sectionCountChanged = false; - for (int i = 0; i < sectionHidden.count(); ++i) { - if (sectionHidden.testBit(i)) - q->setSectionHidden(logicalIndex(i), false); - } for (int i = 0; i < persistentHiddenSections.count(); ++i) { QModelIndex index = persistentHiddenSections.at(i); @@ -1866,6 +1864,7 @@ void QHeaderViewPrivate::_q_layoutChanged() ? index.column() : index.row()); q->setSectionHidden(logical, true); + oldSectionHidden.setBit(logical, false); } else if (!sectionCountChanged && (modelSectionCount() != sectionCount)) { sectionCountChanged = true; break; @@ -1873,6 +1872,11 @@ void QHeaderViewPrivate::_q_layoutChanged() } persistentHiddenSections.clear(); + for (int i = 0; i < oldSectionHidden.count(); ++i) { + if (oldSectionHidden.testBit(i)) + q->setSectionHidden(logicalIndex(i), false); + } + // the number of sections changed; we need to reread the state of the model if (sectionCountChanged) q->initializeSections(); @@ -2300,7 +2304,7 @@ void QHeaderView::mouseReleaseEvent(QMouseEvent *e) int section = logicalIndexAt(pos); if (section != -1 && section == d->pressed) { d->flipSortIndicator(section); - emit sectionClicked(logicalIndexAt(pos)); + emit sectionClicked(section); } if (d->pressed != -1) updateSection(d->pressed); diff --git a/tests/auto/qheaderview/tst_qheaderview.cpp b/tests/auto/qheaderview/tst_qheaderview.cpp index 857e7e3..4642830 100644 --- a/tests/auto/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/qheaderview/tst_qheaderview.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -190,6 +191,7 @@ private slots: void task236450_hidden(); void task248050_hideRow(); void QTBUG6058_reset(); + void QTBUG7833_sectionClicked(); protected: QHeaderView *view; @@ -1992,6 +1994,68 @@ void tst_QHeaderView::QTBUG6058_reset() QCOMPARE(checkHeaderViewOrder(&view, QVector() << 2 << 0 << 1 << 3 << 4 << 5 ) , 0); } +void tst_QHeaderView::QTBUG7833_sectionClicked() +{ + + + + + QTableView tv; + QStandardItemModel *sim = new QStandardItemModel(&tv); + QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(&tv); + proxyModel->setSourceModel(sim); + proxyModel->setDynamicSortFilter(true); + proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); + + QList row; + for (int i = 0; i < 12; i++) + row.append(new QStandardItem(QString(QLatin1Char('A' + i)))); + sim->appendRow(row); + row.clear(); + for (int i = 12; i > 0; i--) + row.append(new QStandardItem(QString(QLatin1Char('A' + i)))); + sim->appendRow(row); + + tv.setSortingEnabled(true); + tv.horizontalHeader()->setSortIndicatorShown(true); + tv.horizontalHeader()->setClickable(true); + tv.horizontalHeader()->setStretchLastSection(true); + tv.horizontalHeader()->setResizeMode(QHeaderView::Interactive); + + tv.setModel(proxyModel); + tv.setColumnHidden(5, true); + tv.setColumnHidden(6, true); + tv.horizontalHeader()->swapSections(8, 10); + tv.sortByColumn(1, Qt::AscendingOrder); + + QSignalSpy clickedSpy(tv.horizontalHeader(), SIGNAL(sectionClicked(int))); + QSignalSpy pressedSpy(tv.horizontalHeader(), SIGNAL(sectionPressed(int))); + + + QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, + QPoint(tv.horizontalHeader()->sectionViewportPosition(11) + 5, 5)); + QCOMPARE(clickedSpy.count(), 1); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(clickedSpy.at(0).at(0).toInt(), 11); + QCOMPARE(pressedSpy.at(0).at(0).toInt(), 11); + + QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, + QPoint(tv.horizontalHeader()->sectionViewportPosition(8) + 5, 5)); + + QCOMPARE(clickedSpy.count(), 2); + QCOMPARE(pressedSpy.count(), 2); + QCOMPARE(clickedSpy.at(1).at(0).toInt(), 8); + QCOMPARE(pressedSpy.at(1).at(0).toInt(), 8); + + QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier, + QPoint(tv.horizontalHeader()->sectionViewportPosition(0) + 5, 5)); + + QCOMPARE(clickedSpy.count(), 3); + QCOMPARE(pressedSpy.count(), 3); + QCOMPARE(clickedSpy.at(2).at(0).toInt(), 0); + QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0); +} + QTEST_MAIN(tst_QHeaderView) #include "tst_qheaderview.moc" -- cgit v0.12