diff options
-rw-r--r-- | dist/changes-5.2.0 | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.cpp | 4 | ||||
-rw-r--r-- | src/widgets/kernel/qlayoutitem.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qsizepolicy.h | 5 | ||||
-rw-r--r-- | src/widgets/kernel/qsizepolicy.qdoc | 17 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 10 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp | 43 | ||||
-rw-r--r-- | tests/manual/widgets/kernel/kernel.pro | 3 | ||||
-rw-r--r-- | tests/manual/widgets/kernel/sizeonhide/main.cpp | 134 | ||||
-rw-r--r-- | tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro | 3 |
11 files changed, 217 insertions, 7 deletions
diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0 index a6beaa441d..dab73b7a2e 100644 --- a/dist/changes-5.2.0 +++ b/dist/changes-5.2.0 @@ -32,6 +32,8 @@ QtWidgets - QFileDialog::setDefaultSuffix() removes leading dot characters. +- QSizePolicy got a retainSizeWhenHidden attribute. + QtCore ------ - [QTBUG-30250] QTime, QDateTime: diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index a65c34adf5..8541dd984d 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1443,7 +1443,7 @@ QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy) policy.bits.hfw << 8 | // [8] policy.bits.ctype << 9 | // [9, 13] policy.bits.wfh << 14 | // [14] - //policy.bits.padding << 15 | // [15] + policy.bits.retainSizeWhenHidden << 15 | // [15] policy.bits.verStretch << 16 | // [16, 23] policy.bits.horStretch << 24); // [24, 31] return stream << data; @@ -1468,7 +1468,7 @@ QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy) policy.bits.hfw = VALUE_OF_BITS(data, 8, 1); policy.bits.ctype = VALUE_OF_BITS(data, 9, 5); policy.bits.wfh = VALUE_OF_BITS(data, 14, 1); - policy.bits.padding = 0; + policy.bits.retainSizeWhenHidden = VALUE_OF_BITS(data, 15, 1); policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8); policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8); return stream; diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index 223bcf1d9b..a99ea77ce2 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -682,7 +682,7 @@ bool QSpacerItem::isEmpty() const */ bool QWidgetItem::isEmpty() const { - return wid->isHidden() || wid->isWindow(); + return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow(); } /*! diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 2fe85cbe0c..9c6d67410a 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -131,6 +131,9 @@ public: void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } + bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; } + void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; } + void transpose(); @@ -150,7 +153,7 @@ private: quint32 ctype : 5; quint32 hfw : 1; quint32 wfh : 1; - quint32 padding : 1; // feel free to use + quint32 retainSizeWhenHidden : 1; } bits; quint32 data; }; diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc index 6af694d999..2c088113e1 100644 --- a/src/widgets/kernel/qsizepolicy.qdoc +++ b/src/widgets/kernel/qsizepolicy.qdoc @@ -341,6 +341,23 @@ */ /*! + \fn void QSizePolicy::retainSizeWhenHidden() const + + Returns if the layout should retain the widgets size when it is hidden. This is by default false. + + \sa setRetainSizeWhenHidden() +*/ + +/*! + \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize) + + Set if a layout should retain the widgets size when it is hidden. + If \a retainSize is true the layout will not be changed by hiding the widget. + + \sa retainSizeWhenHidden() +*/ + +/*! \enum QSizePolicy::ControlType \since 4.3 diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index a0c723fa0d..2d19175725 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -264,6 +264,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , bg_role(QPalette::NoRole) , dirtyOpaqueChildren(1) , isOpaque(0) + , retainSizeWhenHiddenChanged(0) , inDirtyList(0) , isScrolled(0) , isMoved(0) @@ -9254,6 +9255,10 @@ void QWidget::setSizePolicy(QSizePolicy policy) setAttribute(Qt::WA_WState_OwnSizePolicy); if (policy == d->size_policy) return; + + if (d->size_policy.retainSizeWhenHidden() != policy.retainSizeWhenHidden()) + d->retainSizeWhenHiddenChanged = 1; + d->size_policy = policy; #ifndef QT_NO_GRAPHICSVIEW @@ -9264,6 +9269,7 @@ void QWidget::setSizePolicy(QSizePolicy policy) #endif updateGeometry(); + d->retainSizeWhenHiddenChanged = 0; if (isWindow() && d->maybeTopData()) d->topData()->sizeAdjusted = false; @@ -9392,7 +9398,9 @@ void QWidgetPrivate::updateGeometry_helper(bool forceUpdate) widgetItem->invalidateSizeCache(); QWidget *parent; if (forceUpdate || !extra || extra->minw != extra->maxw || extra->minh != extra->maxh) { - if (!q->isWindow() && !q->isHidden() && (parent = q->parentWidget())) { + const int isHidden = q->isHidden() && !size_policy.retainSizeWhenHidden() && !retainSizeWhenHiddenChanged; + + if (!q->isWindow() && !isHidden && (parent = q->parentWidget())) { if (parent->d_func()->layout) parent->d_func()->layout->invalidate(); else if (parent->isVisible()) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 111dd7f9c5..0580f72e11 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -688,6 +688,7 @@ public: QPalette::ColorRole bg_role : 8; uint dirtyOpaqueChildren : 1; uint isOpaque : 1; + uint retainSizeWhenHiddenChanged : 1; uint inDirtyList : 1; uint isScrolled : 1; uint isMoved : 1; diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index 2b9b4fd761..ab2df2e250 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -84,6 +84,7 @@ private slots: void controlTypes(); void controlTypes2(); void adjustSizeShouldMakeSureLayoutIsActivated(); + void testRetainSizeWhenHidden(); }; tst_QLayout::tst_QLayout() @@ -350,5 +351,47 @@ void tst_QLayout::adjustSizeShouldMakeSureLayoutIsActivated() QCOMPARE(main.size(), QSize(200, 10)); } +void tst_QLayout::testRetainSizeWhenHidden() +{ + QWidget widget; + QBoxLayout layout(QBoxLayout::TopToBottom, &widget); + + QLabel *label1 = new QLabel("label1 text", &widget); + layout.addWidget(label1); + QLabel *label2 = new QLabel("label2 text", &widget); + layout.addWidget(label2); + + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + int normalHeight = widget.height(); + + // a. Verify that a removed visible will mean lesser size after adjust + label1->hide(); + widget.adjustSize(); + int heightWithoutLabel1 = widget.height(); + QVERIFY(heightWithoutLabel1 < normalHeight); + + // b restore with verify that the size is the same + label1->show(); + QCOMPARE(widget.sizeHint().height(), normalHeight); + + // c verify that a policy with retainSizeWhenHidden is respected + QSizePolicy sp_remove = label1->sizePolicy(); + QSizePolicy sp_retain = label1->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + + label1->setSizePolicy(sp_retain); + label1->hide(); + QCOMPARE(widget.sizeHint().height(), normalHeight); + + // d check that changing the policy to not wanting size will result in lesser size + label1->setSizePolicy(sp_remove); + QCOMPARE(widget.sizeHint().height(), heightWithoutLabel1); + + // e verify that changing back the hidden widget to want the hidden size will ensure that it gets more size + label1->setSizePolicy(sp_retain); + QCOMPARE(widget.sizeHint().height(), normalHeight); +} + QTEST_MAIN(tst_QLayout) #include "tst_qlayout.moc" diff --git a/tests/manual/widgets/kernel/kernel.pro b/tests/manual/widgets/kernel/kernel.pro index 4d26c9ee19..968d71724f 100644 --- a/tests/manual/widgets/kernel/kernel.pro +++ b/tests/manual/widgets/kernel/kernel.pro @@ -1,3 +1,2 @@ TEMPLATE = subdirs -SUBDIRS = qtooltip - +SUBDIRS = qtooltip sizeonhide diff --git a/tests/manual/widgets/kernel/sizeonhide/main.cpp b/tests/manual/widgets/kernel/sizeonhide/main.cpp new file mode 100644 index 0000000000..e8b95dfe28 --- /dev/null +++ b/tests/manual/widgets/kernel/sizeonhide/main.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets> + +class KeepSizeExampleDlg : public QDialog +{ + Q_OBJECT +public: + QGridLayout *gridLayout; + QHBoxLayout *horizontalLayout; + QVBoxLayout *verticalLayout; + QCheckBox *checkBox; + QCheckBox *checkBox2; + QCheckBox *checkBox3; + QCheckBox *checkBox4; + QGroupBox *groupBox; + QVBoxLayout *verticalLayout2; + QRadioButton *radioButton; + QRadioButton *radioButton2; + QRadioButton *radioButton3; + QTableView *tableView; + QPushButton *pushButton; + QSpacerItem *horizontalSpacer; + + KeepSizeExampleDlg() + { + QWidget *form = this; + form->resize(408, 295); + gridLayout = new QGridLayout(form); + horizontalLayout = new QHBoxLayout(); + verticalLayout = new QVBoxLayout(); + checkBox = new QCheckBox(form); + verticalLayout->addWidget(checkBox); + checkBox2 = new QCheckBox(form); + verticalLayout->addWidget(checkBox2); + checkBox3 = new QCheckBox(form); + verticalLayout->addWidget(checkBox3); + checkBox4 = new QCheckBox(form); + verticalLayout->addWidget(checkBox4); + horizontalLayout->addLayout(verticalLayout); + groupBox = new QGroupBox(form); + verticalLayout2 = new QVBoxLayout(groupBox); + radioButton = new QRadioButton(groupBox); + verticalLayout2->addWidget(radioButton); + radioButton2 = new QRadioButton(groupBox); + verticalLayout2->addWidget(radioButton2); + radioButton3 = new QRadioButton(groupBox); + verticalLayout2->addWidget(radioButton3); + horizontalLayout->addWidget(groupBox); + gridLayout->addLayout(horizontalLayout, 0, 0, 1, 2); + tableView = new QTableView(form); + gridLayout->addWidget(tableView, 1, 0, 1, 2); + pushButton = new QPushButton(form); + gridLayout->addWidget(pushButton, 2, 0, 1, 1); + horizontalSpacer = new QSpacerItem(340, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + gridLayout->addItem(horizontalSpacer, 2, 1, 1, 1); + checkBox->setText(QString::fromUtf8("CheckBox1")); + checkBox2->setText(QString::fromUtf8("CheckBox2")); + checkBox3->setText(QString::fromUtf8("CheckBox - for client A only")); + checkBox4->setText(QString::fromUtf8("CheckBox - also for client A")); + groupBox->setTitle(QString::fromUtf8("Mode")); + radioButton->setText(QString::fromUtf8("Mode 1")); + radioButton2->setText(QString::fromUtf8("Mode 2")); + radioButton3->setText(QString::fromUtf8("Mode 3")); + pushButton->setText(QString::fromUtf8("&Hide/Show")); + + QObject::connect(pushButton, SIGNAL(clicked()), this, SLOT(showOrHide())); + } + + protected slots: + void showOrHide() + { + if (checkBox3->isVisible()) { + checkBox3->hide(); + checkBox4->hide(); + } else { + checkBox3->show(); + checkBox4->show(); + } + } +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + KeepSizeExampleDlg d; + QSizePolicy policyKeepSpace = d.checkBox3->sizePolicy(); + policyKeepSpace.setRetainSizeWhenHidden(true); + d.checkBox3->setSizePolicy(policyKeepSpace); + d.checkBox4->setSizePolicy(policyKeepSpace); + d.show(); + app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro b/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro new file mode 100644 index 0000000000..1969392ab3 --- /dev/null +++ b/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro @@ -0,0 +1,3 @@ +TEMPLATE = app +SOURCES = main.cpp +QT += widgets core-private |