summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@digia.com>2013-08-06 14:08:47 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-15 11:37:27 +0200
commitbff78163f6dc83d833b2097a51453523cfa7b00b (patch)
tree78907fb8dbb1c04d8f2e62861681315b482883e1
parentbab29dd76c7b6794e683220c918dca7c3f5a89fd (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.cpp24
-rw-r--r--src/widgets/itemviews/qheaderview_p.h2
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp65
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"