summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qformlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/kernel/qformlayout.cpp')
-rw-r--r--src/widgets/kernel/qformlayout.cpp426
1 files changed, 296 insertions, 130 deletions
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index 600934b8a1..01097b6123 100644
--- a/src/widgets/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** 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 The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qapplication.h"
#include "qdebug.h"
@@ -43,19 +7,19 @@
#include "qlabel.h"
#include "qlayout_p.h"
#include "qlayoutengine_p.h"
+#include "qlist.h"
#include "qrect.h"
-#include "qvector.h"
#include "qwidget.h"
QT_BEGIN_NAMESPACE
-namespace {
+namespace QtPrivate {
// Fixed column matrix, stores items as [i11, i12, i21, i22...],
// with FORTRAN-style index operator(r, c).
template <class T, int NumColumns>
class FixedColumnMatrix {
public:
- typedef QVector<T> Storage;
+ typedef QList<T> Storage;
FixedColumnMatrix() { }
@@ -104,13 +68,11 @@ void FixedColumnMatrix<T, NumColumns>::storageIndexToPosition(int idx, int *rowP
const uint DefaultFieldGrowthPolicy = 255;
const uint DefaultRowWrapPolicy = 255;
-enum { ColumnCount = 2 };
-
// -- our data structure for our items
// This owns the QLayoutItem
struct QFormLayoutItem
{
- QFormLayoutItem(QLayoutItem* i) : item(i), fullRow(false), isHfw(false) { }
+ QFormLayoutItem(QLayoutItem* i) : item(i) { }
~QFormLayoutItem() { delete item; }
// Wrappers
@@ -127,37 +89,68 @@ struct QFormLayoutItem
void setGeometry(const QRect& r) { item->setGeometry(r); }
QRect geometry() const { return item->geometry(); }
+ void setVisible(bool on);
+ bool isHidden() const { return !isVisible || (widget() && widget()->isHidden()); }
+
// For use with FixedColumnMatrix
bool operator==(const QFormLayoutItem& other) { return item == other.item; }
- QLayoutItem *item;
- bool fullRow;
+ QLayoutItem *item = nullptr;
+ bool fullRow = false;
+ bool isVisible = true;
// set by updateSizes
- bool isHfw;
+ bool isHfw = false;
QSize minSize;
QSize sizeHint;
QSize maxSize;
// also set by updateSizes
- int sbsHSpace; // only used for side by side, for the field item only (not label)
- int vSpace; // This is the spacing to the item in the row above
+ int sbsHSpace = -1; // only used for side by side, for the field item only (not label)
+ int vSpace = -1; // This is the spacing to the item in the row above
// set by setupVerticalLayoutData
- bool sideBySide;
- int vLayoutIndex;
+ bool sideBySide = false;
+ int vLayoutIndex = -1;
// set by setupHorizontalLayoutData
- int layoutPos;
- int layoutWidth;
+ int layoutPos = -1;
+ int layoutWidth = -1;
};
+static void hideOrShowWidgetsInLayout(QLayout *layout, bool on)
+{
+ for (int i = 0; i < layout->count(); ++i) {
+ QLayoutItem *item = layout->itemAt(i);
+ if (QWidget *widget = item->widget())
+ widget->setVisible(on);
+ else if (item->layout())
+ hideOrShowWidgetsInLayout(item->layout(), on);
+ }
+}
+
+void QFormLayoutItem::setVisible(bool on)
+{
+ isVisible = on;
+ // Explicitly hide the widget so that it loses focus and
+ // doesn't automatically get shown again when this layout
+ // hides and shows.
+ if (widget()) {
+ widget()->setVisible(on);
+ return;
+ }
+ // Layouts can't be hidden, so we have to traverse the widgets
+ // inside and hide all of them so that they also lose focus.
+ if (layout())
+ hideOrShowWidgetsInLayout(layout(), on);
+}
+
class QFormLayoutPrivate : public QLayoutPrivate
{
Q_DECLARE_PUBLIC(QFormLayout)
public:
- typedef FixedColumnMatrix<QFormLayoutItem *, ColumnCount> ItemMatrix;
+ using ItemMatrix = QtPrivate::FixedColumnMatrix<QFormLayoutItem *, 2>;
QFormLayoutPrivate();
~QFormLayoutPrivate() { }
@@ -169,7 +162,7 @@ public:
void setLayout(int row, QFormLayout::ItemRole role, QLayout *layout);
void setWidget(int row, QFormLayout::ItemRole role, QWidget *widget);
- void arrangeWidgets(const QVector<QLayoutStruct>& layouts, QRect &rect);
+ void arrangeWidgets(const QList<QLayoutStruct> &layouts, QRect &rect);
void updateSizes();
@@ -199,40 +192,37 @@ public:
ItemMatrix m_matrix;
QList<QFormLayoutItem *> m_things;
- int layoutWidth; // the last width that we called setupVerticalLayoutData on (for vLayouts)
+ int layoutWidth = -1; // the last width that we called setupVerticalLayoutData on (for vLayouts)
- int hfw_width; // the last width we calculated HFW for
- int hfw_height; // what that height was
- int hfw_minheight; // what that minheight was
+ int hfw_width = -1; // the last width we calculated HFW for
+ int hfw_height = -1; // what that height was
- int hfw_sh_height; // the hfw for sh_width
- int hfw_sh_minheight; // the minhfw for sh_width
+ int hfw_sh_height = -1; // the hfw for sh_width
+ int hfw_sh_minheight = -1; // the minhfw for sh_width
- int min_width; // the width that gets turned into minSize (from updateSizes)
- int sh_width; // the width that gets turned into prefSize (from updateSizes)
- int thresh_width; // the width that we start splitting label/field pairs at (from updateSizes)
+ int min_width = -1; // the width that gets turned into minSize (from updateSizes)
+ int sh_width = -1; // the width that gets turned into prefSize (from updateSizes)
+ int thresh_width = QLAYOUTSIZE_MAX; // the width that we start splitting label/field pairs at (from updateSizes)
QSize minSize;
QSize prefSize;
int formMaxWidth;
void calcSizeHints();
- QVector<QLayoutStruct> vLayouts; // set by setupVerticalLayoutData;
+ QList<QLayoutStruct> vLayouts; // set by setupVerticalLayoutData;
int vLayoutCount; // Number of rows we calculated in setupVerticalLayoutData
int maxLabelWidth; // the label width we calculated in setupVerticalLayoutData
- QVector<QLayoutStruct> hfwLayouts;
+ QList<QLayoutStruct> hfwLayouts;
- int hSpacing;
- int vSpacing;
+ int hSpacing = -1;
+ int vSpacing = -1;
QLayoutItem* replaceAt(int index, QLayoutItem*) override;
};
QFormLayoutPrivate::QFormLayoutPrivate()
: fieldGrowthPolicy(DefaultFieldGrowthPolicy),
rowWrapPolicy(DefaultRowWrapPolicy), has_hfw(false), dirty(true), sizesDirty(true),
- expandVertical(0), expandHorizontal(0), labelAlignment(0), formAlignment(0),
- layoutWidth(-1), hfw_width(-1), hfw_sh_height(-1), min_width(-1),
- sh_width(-1), thresh_width(QLAYOUTSIZE_MAX), hSpacing(-1), vSpacing(-1)
+ expandVertical(0), expandHorizontal(0)
{
}
@@ -298,11 +288,11 @@ void QFormLayoutPrivate::updateSizes()
bool expandH = false;
bool expandV = false;
- QFormLayoutItem *prevLbl = 0;
- QFormLayoutItem *prevFld = 0;
+ QFormLayoutItem *prevLbl = nullptr;
+ QFormLayoutItem *prevFld = nullptr;
QWidget *parent = q->parentWidget();
- QStyle *style = parent ? parent->style() : 0;
+ QStyle *style = parent ? parent->style() : nullptr;
int userVSpacing = q->verticalSpacing();
int userHSpacing = wrapAllRows ? 0 : q->horizontalSpacing();
@@ -367,9 +357,9 @@ void QFormLayoutPrivate::updateSizes()
QSizePolicy::ControlTypes fldtoptypes =
QSizePolicy::ControlTypes(fldtop ? fldtop->controlTypes() : QSizePolicy::DefaultType);
if (label && lbltop)
- label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical, 0, parent);
+ label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical, nullptr, parent);
if (field && fldtop)
- field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical, 0, parent);
+ field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical, nullptr, parent);
} else {
// Side by side.. we have to also consider the spacings to empty cells, which can strangely be more than
// non empty cells..
@@ -381,23 +371,25 @@ void QFormLayoutPrivate::updateSizes()
QSizePolicy::ControlTypes(fldtop ? fldtop->controlTypes() : QSizePolicy::DefaultType);
// To be compatible to QGridLayout, we have to compare solitary labels & fields with both predecessors
- if (label) {
+ if (label && !label->isHidden()) {
if (!field) {
- int lblspacing = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical, 0, parent);
- int fldspacing = style->combinedLayoutSpacing(fldtoptypes, lbltypes, Qt::Vertical, 0, parent);
+ int lblspacing = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical, nullptr, parent);
+ int fldspacing = style->combinedLayoutSpacing(fldtoptypes, lbltypes, Qt::Vertical, nullptr, parent);
label->vSpace = qMax(lblspacing, fldspacing);
- } else
- label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical, 0, parent);
+ } else {
+ label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical, nullptr, parent);
+ }
}
- if (field) {
+ if (field && !field->isHidden()) {
// check spacing against both the previous label and field
if (!label) {
- int lblspacing = style->combinedLayoutSpacing(lbltoptypes, fldtypes, Qt::Vertical, 0, parent);
- int fldspacing = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical, 0, parent);
+ int lblspacing = style->combinedLayoutSpacing(lbltoptypes, fldtypes, Qt::Vertical, nullptr, parent);
+ int fldspacing = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical, nullptr, parent);
field->vSpace = qMax(lblspacing, fldspacing);
- } else
- field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical, 0, parent);
+ } else {
+ field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical, nullptr, parent);
+ }
}
}
}
@@ -406,7 +398,7 @@ void QFormLayoutPrivate::updateSizes()
// hard-coded the left and right control types so that all the rows have the same
// inter-column spacing (otherwise the right column isn't always left aligned)
if (userHSpacing < 0 && !wrapAllRows && (label || !field->fullRow) && field)
- field->sbsHSpace = style->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, 0, parent);
+ field->sbsHSpace = style->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal, nullptr, parent);
}
// Now update our min/sizehint widths
@@ -419,13 +411,15 @@ void QFormLayoutPrivate::updateSizes()
if (label) {
maxMinLblWidth = qMax(maxMinLblWidth, label->minSize.width());
maxShLblWidth = qMax(maxShLblWidth, label->sizeHint.width());
- if (field) {
+ }
+ if (field) {
+ if (field->fullRow) {
+ maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width());
+ maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width());
+ } else {
maxMinFldWidth = qMax(maxMinFldWidth, field->minSize.width() + field->sbsHSpace);
maxShFldWidth = qMax(maxShFldWidth, field->sizeHint.width() + field->sbsHSpace);
}
- } else if (field) {
- maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width());
- maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width());
}
prevLbl = label;
@@ -479,12 +473,12 @@ void QFormLayoutPrivate::recalcHFW(int w)
} else {
hfw_width = w;
hfw_height = qMin(QLAYOUTSIZE_MAX, h);
- hfw_minheight = qMin(QLAYOUTSIZE_MAX, mh);
}
}
void QFormLayoutPrivate::setupHfwLayoutData()
{
+ Q_Q(QFormLayout);
// setupVerticalLayoutData must be called before this
// setupHorizontalLayoutData must also be called before this
// copies non hfw data into hfw
@@ -509,7 +503,11 @@ void QFormLayoutPrivate::setupHfwLayoutData()
QFormLayoutItem *label = m_matrix(i, 0);
QFormLayoutItem *field = m_matrix(i, 1);
- if (label) {
+ // ignore rows with only hidden items
+ if (!q->isRowVisible(i))
+ continue;
+
+ if (label && label->vLayoutIndex > -1) {
if (label->isHfw) {
// We don't check sideBySide here, since a label is only
// ever side by side with its field
@@ -524,7 +522,7 @@ void QFormLayoutPrivate::setupHfwLayoutData()
}
}
- if (field) {
+ if (field && field->vLayoutIndex > -1) {
int hfw = field->isHfw ? field->heightForWidth(field->layoutWidth) : 0;
int h = field->isHfw ? hfw : field->sizeHint.height();
int mh = field->isHfw ? hfw : field->minSize.height();
@@ -596,13 +594,13 @@ static inline int spacingHelper(QWidget* parent, QStyle *style, int userVSpacing
QSizePolicy::ControlTypes(item1 ? item1->controlTypes() : QSizePolicy::DefaultType);
int spacing2 = 0;
- spacing = style->combinedLayoutSpacing(itemtypes, prevItem1->controlTypes(), Qt::Vertical, 0, parent);
+ spacing = style->combinedLayoutSpacing(itemtypes, prevItem1->controlTypes(), Qt::Vertical, nullptr, parent);
// At most of one of item2 and prevItem2 will be nonnull
if (item2)
- spacing2 = style->combinedLayoutSpacing(item2->controlTypes(), prevItem1->controlTypes(), Qt::Vertical, 0, parent);
+ spacing2 = style->combinedLayoutSpacing(item2->controlTypes(), prevItem1->controlTypes(), Qt::Vertical, nullptr, parent);
else if (prevItem2)
- spacing2 = style->combinedLayoutSpacing(itemtypes, prevItem2->controlTypes(), Qt::Vertical, 0, parent);
+ spacing2 = style->combinedLayoutSpacing(itemtypes, prevItem2->controlTypes(), Qt::Vertical, nullptr, parent);
spacing = qMax(spacing, spacing2);
}
@@ -650,7 +648,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
vLayouts.clear();
vLayouts.resize((2 * rr) + 2); // a max, some may be unused
- QStyle *style = 0;
+ QStyle *style = nullptr;
int userVSpacing = q->verticalSpacing();
@@ -678,17 +676,23 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
maxLabelWidth = width;
}
- QFormLayoutItem *prevItem1 = 0;
- QFormLayoutItem *prevItem2 = 0;
+ QFormLayoutItem *prevItem1 = nullptr;
+ QFormLayoutItem *prevItem2 = nullptr;
bool prevRowSplit = false;
for (int i = 0; i < rr; ++i) {
- QFormLayoutItem *label = m_matrix(i, 0);
+ QFormLayoutItem *label = m_matrix(i, 0);
QFormLayoutItem *field = m_matrix(i, 1);
- // Totally ignore empty rows...
- if (!label && !field)
+ // Ignore empty rows or rows with only hidden items,
+ // and invalidate their position in the layout.
+ if (!q->isRowVisible(i)) {
+ if (label)
+ label->vLayoutIndex = -1;
+ if (field)
+ field->vLayoutIndex = -1;
continue;
+ }
QSize min1;
QSize min2;
@@ -713,13 +717,13 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
initLayoutStruct(vLayouts[vidx], label);
if (vidx > 1)
- vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, label, 0, prevItem1, prevItem2);
+ vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, label, nullptr, prevItem1, prevItem2);
label->vLayoutIndex = vidx;
label->sideBySide = false;
prevItem1 = label;
- prevItem2 = 0;
+ prevItem2 = nullptr;
if (vLayouts[vidx].stretch > 0)
addTopBottomStretch = false;
@@ -731,13 +735,13 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
initLayoutStruct(vLayouts[vidx], field);
if (vidx > 1)
- vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, field, 0, prevItem1, prevItem2);
+ vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, field, nullptr, prevItem1, prevItem2);
field->vLayoutIndex = vidx;
field->sideBySide = false;
prevItem1 = field;
- prevItem2 = 0;
+ prevItem2 = nullptr;
if (vLayouts[vidx].stretch > 0)
addTopBottomStretch = false;
@@ -760,7 +764,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
if (label->expandingDirections() & Qt::Vertical)
expanding = true;
- label->sideBySide = (field != 0);
+ label->sideBySide = (field != nullptr);
label->vLayoutIndex = vidx;
stretch1 = label->vStretch();
}
@@ -781,7 +785,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
vLayouts[vidx].expansive = expanding || (vLayouts[vidx].stretch > 0);
vLayouts[vidx].empty = false;
- if (vLayouts[vidx].stretch > 0)
+ if (vLayouts[vidx].expansive)
addTopBottomStretch = false;
if (vidx > 1)
@@ -792,7 +796,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
prevItem2 = field;
} else {
prevItem1 = field;
- prevItem2 = 0;
+ prevItem2 = nullptr;
}
prevRowSplit = false;
@@ -993,12 +997,12 @@ QLayoutItem* QFormLayoutPrivate::replaceAt(int index, QLayoutItem *newitem)
{
Q_Q(QFormLayout);
if (!newitem)
- return 0;
+ return nullptr;
const int storageIndex = storageIndexFromLayoutItem(m_matrix, m_things.value(index));
if (Q_UNLIKELY(storageIndex == -1)) {
// ### Qt6 - fix warning too when this class becomes public
qWarning("QFormLayoutPrivate::replaceAt: Invalid index %d", index);
- return 0;
+ return nullptr;
}
int row, col;
@@ -1191,10 +1195,14 @@ QLayoutItem* QFormLayoutPrivate::replaceAt(int index, QLayoutItem *newitem)
/*!
Constructs a new form layout with the given \a parent widget.
+ The layout is set directly as the top-level layout for \a parent.
+ There can be only one top-level layout for a widget. It is returned
+ by QWidget::layout().
+
\sa QWidget::setLayout()
*/
QFormLayout::QFormLayout(QWidget *parent)
- : QLayout(*new QFormLayoutPrivate, 0, parent)
+ : QLayout(*new QFormLayoutPrivate, nullptr, parent)
{
}
@@ -1330,7 +1338,7 @@ void QFormLayout::insertRow(int row, const QString &labelText, QWidget *field)
if (field && !d->checkWidget(field))
return;
- QLabel *label = 0;
+ QLabel *label = nullptr;
if (!labelText.isEmpty()) {
label = new QLabel(labelText);
#ifndef QT_NO_SHORTCUT
@@ -1352,7 +1360,7 @@ void QFormLayout::insertRow(int row, const QString &labelText, QLayout *field)
if (field && !d->checkLayout(field))
return;
- insertRow(row, labelText.isEmpty() ? 0 : new QLabel(labelText), field);
+ insertRow(row, labelText.isEmpty() ? nullptr : new QLabel(labelText), field);
}
/*!
@@ -1644,7 +1652,7 @@ void QFormLayout::addItem(QLayoutItem *item)
int QFormLayout::count() const
{
Q_D(const QFormLayout);
- return d->m_things.count();
+ return d->m_things.size();
}
/*!
@@ -1655,7 +1663,7 @@ QLayoutItem *QFormLayout::itemAt(int index) const
Q_D(const QFormLayout);
if (QFormLayoutItem *formItem = d->m_things.value(index))
return formItem->item;
- return 0;
+ return nullptr;
}
/*!
@@ -1668,7 +1676,7 @@ QLayoutItem *QFormLayout::takeAt(int index)
const int storageIndex = storageIndexFromLayoutItem(d->m_matrix, d->m_things.value(index));
if (Q_UNLIKELY(storageIndex == -1)) {
qWarning("QFormLayout::takeAt: Invalid index %d", index);
- return 0;
+ return nullptr;
}
int row, col;
@@ -1694,7 +1702,7 @@ Qt::Orientations QFormLayout::expandingDirections() const
QFormLayoutPrivate *e = const_cast<QFormLayoutPrivate *>(d);
e->updateSizes();
- Qt::Orientations o = 0;
+ Qt::Orientations o;
if (e->expandHorizontal)
o = Qt::Horizontal;
if (e->expandVertical)
@@ -1833,7 +1841,7 @@ QLayoutItem *QFormLayout::itemAt(int row, ItemRole role) const
{
Q_D(const QFormLayout);
if (uint(row) >= uint(d->m_matrix.rowCount()))
- return 0;
+ return nullptr;
switch (role) {
case SpanningRole:
if (QFormLayoutItem *item = d->m_matrix(row, 1))
@@ -1846,7 +1854,7 @@ QLayoutItem *QFormLayout::itemAt(int row, ItemRole role) const
return item->item;
break;
}
- return 0;
+ return nullptr;
}
/*!
@@ -1930,7 +1938,7 @@ QWidget *QFormLayout::labelForField(QWidget *field) const
if (QFormLayoutItem *label = d->m_matrix(row, LabelRole))
return label->widget();
}
- return 0;
+ return nullptr;
}
/*!
@@ -1949,7 +1957,7 @@ QWidget *QFormLayout::labelForField(QLayout *field) const
if (QFormLayoutItem *label = d->m_matrix(row, LabelRole))
return label->widget();
}
- return 0;
+ return nullptr;
}
/*!
@@ -2169,14 +2177,14 @@ int QFormLayout::spacing() const
}
}
-void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, QRect &rect)
+void QFormLayoutPrivate::arrangeWidgets(const QList<QLayoutStruct> &layouts, QRect &rect)
{
Q_Q(QFormLayout);
int i;
const int rr = m_matrix.rowCount();
QWidget *w = q->parentWidget();
- Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QApplication::layoutDirection();
+ Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QGuiApplication::layoutDirection();
Qt::Alignment formAlignment = fixedAlignment(q->formAlignment(), layoutDirection);
int leftOffset = 0;
@@ -2191,7 +2199,10 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q
QFormLayoutItem *label = m_matrix(i, 0);
QFormLayoutItem *field = m_matrix(i, 1);
- if (label) {
+ if (!q->isRowVisible(i))
+ continue;
+
+ if (label && label->vLayoutIndex > -1) {
int height = layouts.at(label->vLayoutIndex).size;
if ((label->expandingDirections() & Qt::Vertical) == 0) {
/*
@@ -2207,15 +2218,18 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector<QLayoutStruct>& layouts, Q
QSize sz(qMin(label->layoutWidth, label->sizeHint.width()), height);
int x = leftOffset + rect.x() + label->layoutPos;
- if (fixedAlignment(q->labelAlignment(), layoutDirection) & Qt::AlignRight)
+ const auto fAlign = fixedAlignment(q->labelAlignment(), layoutDirection);
+ if (fAlign & Qt::AlignRight)
x += label->layoutWidth - sz.width();
+ else if (fAlign & Qt::AlignHCenter)
+ x += label->layoutWidth / 2 - sz.width() / 2;
QPoint p(x, layouts.at(label->vLayoutIndex).pos);
// ### expansion & sizepolicy stuff
label->setGeometry(QStyle::visualRect(layoutDirection, rect, QRect(p, sz)));
}
- if (field) {
+ if (field && field->vLayoutIndex > -1) {
QSize sz(field->layoutWidth, layouts.at(field->vLayoutIndex).size);
QPoint p(field->layoutPos + leftOffset + rect.x(), layouts.at(field->vLayoutIndex).pos);
/*
@@ -2295,6 +2309,158 @@ void QFormLayout::setItem(int row, ItemRole role, QLayoutItem *item)
}
/*!
+ \since 6.4
+
+ Shows the row \a row if \a on is true, otherwise hides the row.
+
+ \a row must be non-negative and less than rowCount().
+
+ \sa removeRow(), takeRow()
+*/
+void QFormLayout::setRowVisible(int row, bool on)
+{
+ Q_D(QFormLayout);
+ QFormLayoutItem *label = d->m_matrix(row, 0);
+ QFormLayoutItem *field = d->m_matrix(row, 1);
+ bool change = false;
+ if (label) {
+ change = label->isVisible != on;
+ label->setVisible(on);
+ }
+ if (field) {
+ change |= field->isVisible != on;
+ field->setVisible(on);
+ }
+ if (change)
+ invalidate();
+}
+
+/*!
+ \since 6.4
+
+ \overload
+
+ Shows the row corresponding to \a widget if \a on is true,
+ otherwise hides the row.
+
+ \sa removeRow(), takeRow()
+*/
+void QFormLayout::setRowVisible(QWidget *widget, bool on)
+{
+ Q_D(QFormLayout);
+ if (Q_UNLIKELY(!d->checkWidget(widget)))
+ return;
+
+ int row;
+ ItemRole role;
+ getWidgetPosition(widget, &row, &role);
+
+ if (Q_UNLIKELY(row < 0)) {
+ qWarning("QFormLayout::setRowVisible: Invalid widget");
+ return;
+ }
+
+ setRowVisible(row, on);
+}
+
+/*!
+ \since 6.4
+
+ \overload
+
+ Shows the row corresponding to \a layout if \a on is true,
+ otherwise hides the row.
+
+ \sa removeRow(), takeRow()
+*/
+void QFormLayout::setRowVisible(QLayout *layout, bool on)
+{
+ Q_D(QFormLayout);
+ if (Q_UNLIKELY(!d->checkLayout(layout)))
+ return;
+
+ int row;
+ ItemRole role;
+ getLayoutPosition(layout, &row, &role);
+
+ if (Q_UNLIKELY(row < 0)) {
+ qWarning("QFormLayout::setRowVisible: Invalid layout");
+ return;
+ }
+
+ setRowVisible(row, on);
+}
+
+/*!
+ \since 6.4
+
+ Returns true if some items in the row \a row are visible,
+ otherwise returns false.
+*/
+bool QFormLayout::isRowVisible(int row) const
+{
+ Q_D(const QFormLayout);
+ QFormLayoutItem *label = d->m_matrix(row, 0);
+ QFormLayoutItem *field = d->m_matrix(row, 1);
+
+ int visibleItemCount = 2;
+ if (!label || label->isHidden() || (label->widget() && label->widget()->isHidden()))
+ --visibleItemCount;
+ if (!field || field->isHidden() || (field->widget() && field->widget()->isHidden()))
+ --visibleItemCount;
+
+ return visibleItemCount > 0;
+}
+
+/*!
+ \since 6.4
+ \overload
+
+ Returns true if some items in the row corresponding to \a widget
+ are visible, otherwise returns false.
+*/
+bool QFormLayout::isRowVisible(QWidget *widget) const
+{
+ Q_D(const QFormLayout);
+ if (Q_UNLIKELY(!d->checkWidget(widget)))
+ return false;
+ int row;
+ ItemRole role;
+ getWidgetPosition(widget, &row, &role);
+
+ if (Q_UNLIKELY(row < 0)) {
+ qWarning("QFormLayout::takeRow: Invalid widget");
+ return false;
+ }
+
+ return isRowVisible(row);
+}
+
+/*!
+ \since 6.4
+ \overload
+
+ Returns true if some items in the row corresponding to \a layout
+ are visible, otherwise returns false.
+*/
+bool QFormLayout::isRowVisible(QLayout *layout) const
+{
+ Q_D(const QFormLayout);
+ if (Q_UNLIKELY(!d->checkLayout(layout)))
+ return false;
+ int row;
+ ItemRole role;
+ getLayoutPosition(layout, &row, &role);
+
+ if (Q_UNLIKELY(row < 0)) {
+ qWarning("QFormLayout::takeRow: Invalid layout");
+ return false;
+ }
+
+ return isRowVisible(row);
+}
+
+/*!
\internal
*/
@@ -2321,7 +2487,7 @@ void QFormLayout::resetRowWrapPolicy()
void QFormLayout::resetFormAlignment()
{
Q_D(QFormLayout);
- d->formAlignment = 0;
+ d->formAlignment = { };
}
/*!
@@ -2331,7 +2497,7 @@ void QFormLayout::resetFormAlignment()
void QFormLayout::resetLabelAlignment()
{
Q_D(QFormLayout);
- d->labelAlignment = 0;
+ d->labelAlignment = { };
}
#if 0