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>
This commit is contained in:
parent
bab29dd76c
commit
bff78163f6
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user