diff options
author | J-P Nurmi <jpnurmi@digia.com> | 2013-08-06 14:08:47 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-15 11:37:27 +0200 |
commit | bff78163f6dc83d833b2097a51453523cfa7b00b (patch) | |
tree | 78907fb8dbb1c04d8f2e62861681315b482883e1 | |
parent | bab29dd76c7b6794e683220c918dca7c3f5a89fd (diff) |
QHeaderView::paintSection(): fix visible index handling
Sections may be hidden => QStyleOptionHeader::position must reflect the
state seen on the screen. Otherwise styles will give wrong visual
results.
Task-number: QTBUG-32203
Change-Id: I7ef86496be092bf6f52ec45f757b501f38c3a431
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
-rw-r--r-- | src/widgets/itemviews/qheaderview.cpp | 24 | ||||
-rw-r--r-- | src/widgets/itemviews/qheaderview_p.h | 2 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 65 |
3 files changed, 88 insertions, 3 deletions
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index edfbc5c8f1..864a55d2ea 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2635,11 +2635,13 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical // the section position int visual = visualIndex(logicalIndex); Q_ASSERT(visual != -1); - if (count() == 1) + bool first = d->isFirstVisibleSection(visual); + bool last = d->isLastVisibleSection(visual); + if (first && last) opt.position = QStyleOptionHeader::OnlyOneSection; - else if (visual == 0) + else if (first) opt.position = QStyleOptionHeader::Beginning; - else if (visual == count() - 1) + else if (last) opt.position = QStyleOptionHeader::End; else opt.position = QStyleOptionHeader::Middle; @@ -3062,6 +3064,22 @@ bool QHeaderViewPrivate::isSectionSelected(int section) const return s; } +bool QHeaderViewPrivate::isFirstVisibleSection(int section) const +{ + if (sectionStartposRecalc) + recalcSectionStartPos(); + const SectionItem &item = sectionItems.at(section); + return item.size > 0 && item.calculated_startpos == 0; +} + +bool QHeaderViewPrivate::isLastVisibleSection(int section) const +{ + if (sectionStartposRecalc) + recalcSectionStartPos(); + const SectionItem &item = sectionItems.at(section); + return item.size > 0 && item.calculatedEndPos() == length; +} + /*! \internal Returns the last visible (ie. not hidden) visual index diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index 7fda0c8873..f886430ba8 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -114,6 +114,8 @@ public: void _q_layoutChanged(); bool isSectionSelected(int section) const; + bool isFirstVisibleSection(int section) const; + bool isLastVisibleSection(int section) const; inline bool rowIntersectsSelection(int row) const { return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false); diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index fa67e16db9..548b74f914 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -46,6 +46,7 @@ #include <QStringListModel> #include <QSortFilterProxyModel> #include <QTableView> +#include <QProxyStyle> #include <qabstractitemmodel.h> #include <qapplication.h> @@ -59,6 +60,20 @@ typedef QList<int> IntList; typedef QList<bool> BoolList; +class TestStyle : public QProxyStyle +{ +public: + void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const + { + if (element == CE_HeaderSection) { + if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) + lastPosition = header->position; + } + QProxyStyle::drawControl(element, option, painter, widget); + } + mutable QStyleOptionHeader::SectionPosition lastPosition; +}; + class protected_QHeaderView : public QHeaderView { Q_OBJECT @@ -229,6 +244,7 @@ private slots: void mixedTests(); void resizeToContentTest(); void testStreamWithHide(); + void testStylePosition(); protected: void setupTestData(bool use_reset_model = false); @@ -2732,5 +2748,54 @@ void tst_QHeaderView::testStreamWithHide() #endif } +void tst_QHeaderView::testStylePosition() +{ + topLevel->show(); + QVERIFY(QTest::qWaitForWindowExposed(topLevel)); + + protected_QHeaderView *header = static_cast<protected_QHeaderView *>(view); + + TestStyle proxy; + header->setStyle(&proxy); + + QImage image(1, 1, QImage::Format_ARGB32); + QPainter p(&image); + + // 0, 1, 2, 3 + header->paintSection(&p, view->rect(), 0); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::Beginning); + header->paintSection(&p, view->rect(), 1); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::Middle); + header->paintSection(&p, view->rect(), 2); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::Middle); + header->paintSection(&p, view->rect(), 3); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::End); + + // (0),2,1,3 + view->setSectionHidden(0, true); + view->swapSections(1, 2); + header->paintSection(&p, view->rect(), 1); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::Middle); + header->paintSection(&p, view->rect(), 2); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::Beginning); + header->paintSection(&p, view->rect(), 3); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::End); + + // (1),2,0,(3) + view->setSectionHidden(3, true); + view->setSectionHidden(0, false); + view->setSectionHidden(1, true); + view->swapSections(0, 1); + header->paintSection(&p, view->rect(), 0); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::End); + header->paintSection(&p, view->rect(), 2); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::Beginning); + + // (1),2,(0),(3) + view->setSectionHidden(0, true); + header->paintSection(&p, view->rect(), 2); + QCOMPARE(proxy.lastPosition, QStyleOptionHeader::OnlyOneSection); +} + QTEST_MAIN(tst_QHeaderView) #include "tst_qheaderview.moc" |