From 53022e04bb578c12cdc9460d7ce4eedefbc8c2e4 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 12 Nov 2014 17:13:22 +0300 Subject: [PATCH] Make the defaultSectionSize property of QHeaderView style dependent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new enum items PM_HeaderDefaultSectionSizeHorizontal and PM_HeaderDefaultSectionSizeVertical to QStyle and get corresponding values in QHeaderView. This way we get rid of some magic constants in QHeaderView and we can have reasonable values for the default section size for high-DPI displays. [ChangeLog][QtWidgets][QHeaderView] Default section size is now style-dependent by default. [ChangeLog][QtWidgets][QHeaderView] Added resetDefaultSectionSize(). Change-Id: I44e152c5cf0bec1e5d78e1e62f47a2d1f761dfbf Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qheaderview.cpp | 39 +++++++++++++++++++ src/widgets/itemviews/qheaderview.h | 3 +- src/widgets/itemviews/qheaderview_p.h | 6 ++- src/widgets/styles/qcommonstyle.cpp | 6 +++ src/widgets/styles/qstyle.cpp | 5 +++ src/widgets/styles/qstyle.h | 3 ++ .../itemviews/qheaderview/tst_qheaderview.cpp | 36 +++++++++++++++++ 7 files changed, 95 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index f1ebc4505e..e887434d14 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1515,6 +1515,11 @@ void QHeaderView::setCascadingSectionResizes(bool enable) This property only affects sections that have \l Interactive or \l Fixed as their resize mode. + By default, the value of this property is style dependent. + Thus, when the style changes, this property updates from it. + Calling setDefaultSectionSize() stops the updates, calling + resetDefaultSectionSize() will restore default behavior. + \sa setSectionResizeMode(), minimumSectionSize */ int QHeaderView::defaultSectionSize() const @@ -1531,6 +1536,15 @@ void QHeaderView::setDefaultSectionSize(int size) d->setDefaultSectionSize(size); } +void QHeaderView::resetDefaultSectionSize() +{ + Q_D(QHeaderView); + if (d->customDefaultSectionSize) { + d->updateDefaultSectionSizeFromStyle(); + d->customDefaultSectionSize = false; + } +} + /*! \since 4.2 \property QHeaderView::minimumSectionSize @@ -2209,6 +2223,10 @@ bool QHeaderView::event(QEvent *e) resizeSections(); } break; } + case QEvent::StyleChange: + if (!d->customDefaultSectionSize) + d->updateDefaultSectionSizeFromStyle(); + break; default: break; } @@ -3465,6 +3483,7 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size) executePostedLayout(); invalidateCachedSizeHint(); defaultSectionSize = size; + customDefaultSectionSize = true; if (state == QHeaderViewPrivate::ResizeSection) preventCursorChangeInSetOffset = true; for (int i = 0; i < sectionItems.count(); ++i) { @@ -3485,6 +3504,17 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size) viewport->update(); } +void QHeaderViewPrivate::updateDefaultSectionSizeFromStyle() +{ + Q_Q(QHeaderView); + if (orientation == Qt::Horizontal) { + defaultSectionSize = q->style()->pixelMetric(QStyle::PM_HeaderDefaultSectionSizeHorizontal, 0, q); + } else { + defaultSectionSize = qMax(q->minimumSectionSize(), + q->style()->pixelMetric(QStyle::PM_HeaderDefaultSectionSizeVertical, 0, q)); + } +} + void QHeaderViewPrivate::recalcSectionStartPos() const // linear (but fast) { int pixelpos = 0; @@ -3632,6 +3662,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const out << sectionItems; out << resizeContentsPrecision; + out << customDefaultSectionSize; } bool QHeaderViewPrivate::read(QDataStream &in) @@ -3708,6 +3739,14 @@ bool QHeaderViewPrivate::read(QDataStream &in) if (in.status() == QDataStream::Ok) // we haven't read past end resizeContentsPrecision = tmpint; + bool tmpbool; + in >> tmpbool; + if (in.status() == QDataStream::Ok) { // we haven't read past end + customDefaultSectionSize = tmpbool; + if (!customDefaultSectionSize) + updateDefaultSectionSizeFromStyle(); + } + return true; } diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h index b8ed9f3f7d..0163243cdf 100644 --- a/src/widgets/itemviews/qheaderview.h +++ b/src/widgets/itemviews/qheaderview.h @@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections) Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection) Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes) - Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize) + Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize RESET resetDefaultSectionSize) Q_PROPERTY(int minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize) Q_PROPERTY(int maximumSectionSize READ maximumSectionSize WRITE setMaximumSectionSize) Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment) @@ -156,6 +156,7 @@ public: int defaultSectionSize() const; void setDefaultSectionSize(int size); + void resetDefaultSectionSize(); int minimumSectionSize() const; void setMinimumSectionSize(int size); diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index fd99ea5474..2fde1bf79a 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -84,6 +84,7 @@ public: cascadingResizing(false), resizeRecursionBlock(false), allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView + customDefaultSectionSize(false), stretchSections(0), contentsSections(0), minimumSectionSize(-1), @@ -155,8 +156,7 @@ public: inline void setDefaultValues(Qt::Orientation o) { orientation = o; - defaultSectionSize = (o == Qt::Horizontal ? 100 - : qMax(q_func()->minimumSectionSize(), 30)); + updateDefaultSectionSizeFromStyle(); defaultAlignment = (o == Qt::Horizontal ? Qt::Alignment(Qt::AlignCenter) : Qt::AlignLeft|Qt::AlignVCenter); @@ -275,6 +275,7 @@ public: bool cascadingResizing; bool resizeRecursionBlock; bool allowUserMoveOfSection0; + bool customDefaultSectionSize; int stretchSections; int contentsSections; int defaultSectionSize; @@ -321,6 +322,7 @@ public: void removeSectionsFromSectionItems(int start, int end); void resizeSectionItem(int visualIndex, int oldSize, int newSize); void setDefaultSectionSize(int size); + void updateDefaultSectionSizeFromStyle(); void recalcSectionStartPos() const; // not really const inline int headerLength() const { // for debugging diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 6b8cba1b18..29df1c6387 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -4592,6 +4592,12 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid case PM_HeaderGripMargin: ret = int(QStyleHelper::dpiScaled(4.)); break; + case PM_HeaderDefaultSectionSizeHorizontal: + ret = int(QStyleHelper::dpiScaled(100.)); + break; + case PM_HeaderDefaultSectionSizeVertical: + ret = int(QStyleHelper::dpiScaled(30.)); + break; case PM_TabBarScrollButtonWidth: ret = int(QStyleHelper::dpiScaled(16.)); break; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 2d5f676b65..5999ba5431 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1472,6 +1472,11 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, \value PM_TreeViewIndentation The indentation of items in a tree view. This enum value has been introduced in Qt 5.4. + \value PM_HeaderDefaultSectionSizeHorizontal The default size of sections + in a horizontal header. This enum value has been introduced in Qt 5.5. + \value PM_HeaderDefaultSectionSizeVertical The default size of sections + in a vertical header. This enum value has been introduced in Qt 5.5. + \value PM_CustomBase Base value for custom pixel metrics. Custom values must be greater than this value. diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index fa15a0d4c4..225146c5bb 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -550,6 +550,9 @@ public: PM_SubMenuOverlap, PM_TreeViewIndentation, + PM_HeaderDefaultSectionSizeHorizontal, + PM_HeaderDefaultSectionSizeVertical, + // do not add any values below/greater than this PM_CustomBase = 0xf0000000 }; diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 408e98b873..eacf2e51fd 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -176,6 +176,7 @@ private slots: void moveSectionAndRemove(); void saveRestore(); void defaultSectionSizeTest(); + void defaultSectionSizeTestStyles(); void defaultAlignment_data(); void defaultAlignment(); @@ -1679,6 +1680,41 @@ void tst_QHeaderView::defaultSectionSizeTest() QVERIFY(hv->sectionSize(2) == 0); // section is hidden. It should not be resized. } +class TestHeaderViewStyle : public QProxyStyle +{ +public: + TestHeaderViewStyle() : horizontalSectionSize(100) {} + int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE + { + if (metric == QStyle::PM_HeaderDefaultSectionSizeHorizontal) + return horizontalSectionSize; + else + return QProxyStyle::pixelMetric(metric, option, widget); + } + int horizontalSectionSize; +}; + +void tst_QHeaderView::defaultSectionSizeTestStyles() +{ + TestHeaderViewStyle style1; + TestHeaderViewStyle style2; + style1.horizontalSectionSize = 100; + style2.horizontalSectionSize = 200; + + QHeaderView hv(Qt::Horizontal); + hv.setStyle(&style1); + QCOMPARE(hv.defaultSectionSize(), style1.horizontalSectionSize); + hv.setStyle(&style2); + QCOMPARE(hv.defaultSectionSize(), style2.horizontalSectionSize); + hv.setDefaultSectionSize(70); + QCOMPARE(hv.defaultSectionSize(), 70); + hv.setStyle(&style1); + QCOMPARE(hv.defaultSectionSize(), 70); + hv.resetDefaultSectionSize(); + QCOMPARE(hv.defaultSectionSize(), style1.horizontalSectionSize); + hv.setStyle(&style2); + QCOMPARE(hv.defaultSectionSize(), style2.horizontalSectionSize); +} void tst_QHeaderView::defaultAlignment_data() {