1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "layout_propertysheet.h"
30
31// sdk
32#include <QtDesigner/qextensionmanager.h>
33#include <QtDesigner/abstractformeditor.h>
34// shared
35
36#include <qlayout_widget_p.h>
37
38#include <QtDesigner/private/ui4_p.h>
39#include <QtDesigner/private/formbuilderextra_p.h>
40
41#include <QtWidgets/qformlayout.h>
42
43#include <QtCore/qhash.h>
44#include <QtCore/qdebug.h>
45#include <QtCore/qtextstream.h>
46#include <QtCore/qbytearray.h>
47#include <QtCore/QRegularExpression> // Remove once there is an editor for lists
48
49QT_BEGIN_NAMESPACE
50
51#define USE_LAYOUT_SIZE_CONSTRAINT
52
53static const char *leftMargin = "leftMargin";
54static const char *topMargin = "topMargin";
55static const char *rightMargin = "rightMargin";
56static const char *bottomMargin = "bottomMargin";
57static const char *horizontalSpacing = "horizontalSpacing";
58static const char *verticalSpacing = "verticalSpacing";
59static const char *spacing = "spacing";
60static const char *margin = "margin";
61static const char *sizeConstraint = "sizeConstraint";
62static const char *boxStretchPropertyC = "stretch";
63static const char *gridRowStretchPropertyC = "rowStretch";
64static const char *gridColumnStretchPropertyC = "columnStretch";
65static const char *gridRowMinimumHeightPropertyC = "rowMinimumHeight";
66static const char *gridColumnMinimumWidthPropertyC = "columnMinimumWidth";
67
68namespace {
69 enum LayoutPropertyType {
70 LayoutPropertyNone,
71 LayoutPropertyMargin, // Deprecated
72 LayoutPropertyLeftMargin,
73 LayoutPropertyTopMargin,
74 LayoutPropertyRightMargin,
75 LayoutPropertyBottomMargin,
76 LayoutPropertySpacing,
77 LayoutPropertyHorizontalSpacing,
78 LayoutPropertyVerticalSpacing,
79 LayoutPropertySizeConstraint,
80 LayoutPropertyBoxStretch,
81 LayoutPropertyGridRowStretch,
82 LayoutPropertyGridColumnStretch,
83 LayoutPropertyGridRowMinimumHeight,
84 LayoutPropertyGridColumnMinimumWidth
85 };
86}
87
88// Check for a comma-separated list of integers. Used for
89// per-cell stretch properties and grid per row/column properties.
90// As it works now, they are passed as QByteArray strings. The
91// property sheet refuses all invalid values. This could be
92// replaced by lists once the property editor can handle them.
93
94static bool isIntegerList(const QString &s)
95{
96 // Check for empty string or comma-separated list of integers
97 static const QRegularExpression re(QStringLiteral("^[0-9]+(,[0-9]+)+$"));
98 Q_ASSERT(re.isValid());
99 return s.isEmpty() || re.match(subject: s).hasMatch();
100}
101
102// Quick lookup by name
103static LayoutPropertyType layoutPropertyType(const QString &name)
104{
105 static QHash<QString, LayoutPropertyType> namePropertyMap;
106 if (namePropertyMap.isEmpty()) {
107 namePropertyMap.insert(akey: QLatin1String(leftMargin), avalue: LayoutPropertyLeftMargin);
108 namePropertyMap.insert(akey: QLatin1String(topMargin), avalue: LayoutPropertyTopMargin);
109 namePropertyMap.insert(akey: QLatin1String(rightMargin), avalue: LayoutPropertyRightMargin);
110 namePropertyMap.insert(akey: QLatin1String(bottomMargin), avalue: LayoutPropertyBottomMargin);
111 namePropertyMap.insert(akey: QLatin1String(horizontalSpacing), avalue: LayoutPropertyHorizontalSpacing);
112 namePropertyMap.insert(akey: QLatin1String(verticalSpacing), avalue: LayoutPropertyVerticalSpacing);
113 namePropertyMap.insert(akey: QLatin1String(spacing), avalue: LayoutPropertySpacing);
114 namePropertyMap.insert(akey: QLatin1String(margin), avalue: LayoutPropertyMargin);
115 namePropertyMap.insert(akey: QLatin1String(sizeConstraint), avalue: LayoutPropertySizeConstraint);
116 namePropertyMap.insert(akey: QLatin1String(boxStretchPropertyC ), avalue: LayoutPropertyBoxStretch);
117 namePropertyMap.insert(akey: QLatin1String(gridRowStretchPropertyC), avalue: LayoutPropertyGridRowStretch);
118 namePropertyMap.insert(akey: QLatin1String(gridColumnStretchPropertyC), avalue: LayoutPropertyGridColumnStretch);
119 namePropertyMap.insert(akey: QLatin1String(gridRowMinimumHeightPropertyC), avalue: LayoutPropertyGridRowMinimumHeight);
120 namePropertyMap.insert(akey: QLatin1String(gridColumnMinimumWidthPropertyC), avalue: LayoutPropertyGridColumnMinimumWidth);
121 }
122 return namePropertyMap.value(akey: name, adefaultValue: LayoutPropertyNone);
123}
124
125// return the layout margin if it is margin
126static int getLayoutMargin(const QLayout *l, LayoutPropertyType type)
127{
128 int left, top, right, bottom;
129 l->getContentsMargins(left: &left, top: &top, right: &right, bottom: &bottom);
130 switch (type) {
131 case LayoutPropertyLeftMargin:
132 return left;
133 case LayoutPropertyTopMargin:
134 return top;
135 case LayoutPropertyRightMargin:
136 return right;
137 case LayoutPropertyBottomMargin:
138 return bottom;
139 default:
140 Q_ASSERT(0);
141 break;
142 }
143 return 0;
144}
145
146// return the layout margin if it is margin
147static void setLayoutMargin(QLayout *l, LayoutPropertyType type, int margin)
148{
149 int left, top, right, bottom;
150 l->getContentsMargins(left: &left, top: &top, right: &right, bottom: &bottom);
151 switch (type) {
152 case LayoutPropertyLeftMargin:
153 left = margin;
154 break;
155 case LayoutPropertyTopMargin:
156 top = margin;
157 break;
158 case LayoutPropertyRightMargin:
159 right = margin;
160 break;
161 case LayoutPropertyBottomMargin:
162 bottom = margin;
163 break;
164 default:
165 Q_ASSERT(0);
166 break;
167 }
168 l->setContentsMargins(left, top, right, bottom);
169}
170
171namespace qdesigner_internal {
172
173// ---------- LayoutPropertySheet: This sheet is never visible in
174// the property editor. Rather, the sheet pulled for QLayoutWidget
175// forwards all properties to it. Some properties (grid spacings) must be handled
176// manually, as they are QDOC_PROPERTY only and not visible to introspection. Ditto
177// for the 4 margins.
178
179LayoutPropertySheet::LayoutPropertySheet(QLayout *l, QObject *parent)
180 : QDesignerPropertySheet(l, parent), m_layout(l)
181{
182 const QString layoutGroup = QStringLiteral("Layout");
183 int pindex = createFakeProperty(propertyName: QLatin1String(leftMargin), value: 0);
184 setPropertyGroup(index: pindex, group: layoutGroup);
185
186 pindex = createFakeProperty(propertyName: QLatin1String(topMargin), value: 0);
187 setPropertyGroup(index: pindex, group: layoutGroup);
188
189 pindex = createFakeProperty(propertyName: QLatin1String(rightMargin), value: 0);
190 setPropertyGroup(index: pindex, group: layoutGroup);
191
192 pindex = createFakeProperty(propertyName: QLatin1String(bottomMargin), value: 0);
193 setPropertyGroup(index: pindex, group: layoutGroup);
194
195 const int visibleMask = LayoutProperties::visibleProperties(layout: m_layout);
196 if (visibleMask & LayoutProperties::HorizSpacingProperty) {
197 pindex = createFakeProperty(propertyName: QLatin1String(horizontalSpacing), value: 0);
198 setPropertyGroup(index: pindex, group: layoutGroup);
199
200 pindex = createFakeProperty(propertyName: QLatin1String(verticalSpacing), value: 0);
201 setPropertyGroup(index: pindex, group: layoutGroup);
202
203 setAttribute(index: indexOf(name: QLatin1String(spacing)), b: true);
204 }
205
206 setAttribute(index: indexOf(name: QLatin1String(margin)), b: true);
207 // Stretch
208 if (visibleMask & LayoutProperties::BoxStretchProperty) {
209 pindex = createFakeProperty(propertyName: QLatin1String(boxStretchPropertyC), value: QByteArray());
210 setPropertyGroup(index: pindex, group: layoutGroup);
211 setAttribute(index: pindex, b: true);
212 } else {
213 // Add the grid per-row/column stretch and size limits
214 if (visibleMask & LayoutProperties::GridColumnStretchProperty) {
215 const QByteArray empty;
216 pindex = createFakeProperty(propertyName: QLatin1String(gridRowStretchPropertyC), value: empty);
217 setPropertyGroup(index: pindex, group: layoutGroup);
218 setAttribute(index: pindex, b: true);
219 pindex = createFakeProperty(propertyName: QLatin1String(gridColumnStretchPropertyC), value: empty);
220 setPropertyGroup(index: pindex, group: layoutGroup);
221 setAttribute(index: pindex, b: true);
222 pindex = createFakeProperty(propertyName: QLatin1String(gridRowMinimumHeightPropertyC), value: empty);
223 setPropertyGroup(index: pindex, group: layoutGroup);
224 setAttribute(index: pindex, b: true);
225 pindex = createFakeProperty(propertyName: QLatin1String(gridColumnMinimumWidthPropertyC), value: empty);
226 setPropertyGroup(index: pindex, group: layoutGroup);
227 setAttribute(index: pindex, b: true);
228 }
229 }
230#ifdef USE_LAYOUT_SIZE_CONSTRAINT
231 // SizeConstraint cannot possibly be handled as a real property
232 // as it affects the layout parent widget and thus
233 // conflicts with Designer's special layout widget.
234 // It will take effect on the preview only.
235 pindex = createFakeProperty(propertyName: QLatin1String(sizeConstraint));
236 setPropertyGroup(index: pindex, group: layoutGroup);
237#endif
238}
239
240LayoutPropertySheet::~LayoutPropertySheet() = default;
241
242void LayoutPropertySheet::setProperty(int index, const QVariant &value)
243{
244 const LayoutPropertyType type = layoutPropertyType(name: propertyName(index));
245 if (QLayoutWidget *lw = qobject_cast<QLayoutWidget *>(object: m_layout->parent())) {
246 switch (type) {
247 case LayoutPropertyLeftMargin:
248 lw->setLayoutLeftMargin(value.toInt());
249 return;
250 case LayoutPropertyTopMargin:
251 lw->setLayoutTopMargin(value.toInt());
252 return;
253 case LayoutPropertyRightMargin:
254 lw->setLayoutRightMargin(value.toInt());
255 return;
256 case LayoutPropertyBottomMargin:
257 lw->setLayoutBottomMargin(value.toInt());
258 return;
259 case LayoutPropertyMargin: {
260 const int v = value.toInt();
261 lw->setLayoutLeftMargin(v);
262 lw->setLayoutTopMargin(v);
263 lw->setLayoutRightMargin(v);
264 lw->setLayoutBottomMargin(v);
265 }
266 return;
267 default:
268 break;
269 }
270 }
271 switch (type) {
272 case LayoutPropertyLeftMargin:
273 case LayoutPropertyTopMargin:
274 case LayoutPropertyRightMargin:
275 case LayoutPropertyBottomMargin:
276 setLayoutMargin(l: m_layout, type, margin: value.toInt());
277 return;
278 case LayoutPropertyHorizontalSpacing:
279 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout)) {
280 grid->setHorizontalSpacing(value.toInt());
281 return;
282 }
283 if (QFormLayout *form = qobject_cast<QFormLayout *>(object: m_layout)) {
284 form->setHorizontalSpacing(value.toInt());
285 return;
286 }
287 break;
288 case LayoutPropertyVerticalSpacing:
289 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout)) {
290 grid->setVerticalSpacing(value.toInt());
291 return;
292 }
293 if (QFormLayout *form = qobject_cast<QFormLayout *>(object: m_layout)) {
294 form->setVerticalSpacing(value.toInt());
295 return;
296 }
297 break;
298 case LayoutPropertyBoxStretch:
299 // TODO: Remove the regexp check once a proper editor for integer
300 // lists is in place?
301 if (QBoxLayout *box = qobject_cast<QBoxLayout *>(object: m_layout)) {
302 const QString stretch = value.toString();
303 if (isIntegerList(s: stretch))
304 QFormBuilderExtra::setBoxLayoutStretch(value.toString(), box);
305 }
306 break;
307 case LayoutPropertyGridRowStretch:
308 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout)) {
309 const QString stretch = value.toString();
310 if (isIntegerList(s: stretch))
311 QFormBuilderExtra::setGridLayoutRowStretch(stretch, grid);
312 }
313 break;
314 case LayoutPropertyGridColumnStretch:
315 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout)) {
316 const QString stretch = value.toString();
317 if (isIntegerList(s: stretch))
318 QFormBuilderExtra::setGridLayoutColumnStretch(value.toString(), grid);
319 }
320 break;
321 case LayoutPropertyGridRowMinimumHeight:
322 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout)) {
323 const QString minSize = value.toString();
324 if (isIntegerList(s: minSize))
325 QFormBuilderExtra::setGridLayoutRowMinimumHeight(minSize, grid);
326 }
327 break;
328 case LayoutPropertyGridColumnMinimumWidth:
329 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout)) {
330 const QString minSize = value.toString();
331 if (isIntegerList(s: minSize))
332 QFormBuilderExtra::setGridLayoutColumnMinimumWidth(minSize, grid);
333 }
334 break;
335 default:
336 break;
337 }
338 QDesignerPropertySheet::setProperty(index, value);
339}
340
341QVariant LayoutPropertySheet::property(int index) const
342{
343 const LayoutPropertyType type = layoutPropertyType(name: propertyName(index));
344 if (const QLayoutWidget *lw = qobject_cast<QLayoutWidget *>(object: m_layout->parent())) {
345 switch (type) {
346 case LayoutPropertyLeftMargin:
347 return lw->layoutLeftMargin();
348 case LayoutPropertyTopMargin:
349 return lw->layoutTopMargin();
350 case LayoutPropertyRightMargin:
351 return lw->layoutRightMargin();
352 case LayoutPropertyBottomMargin:
353 return lw->layoutBottomMargin();
354 default:
355 break;
356 }
357 }
358 switch (type) {
359 case LayoutPropertyLeftMargin:
360 case LayoutPropertyTopMargin:
361 case LayoutPropertyRightMargin:
362 case LayoutPropertyBottomMargin:
363 return getLayoutMargin(l: m_layout, type);
364 case LayoutPropertyHorizontalSpacing:
365 if (const QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
366 return grid->horizontalSpacing();
367 if (const QFormLayout *form = qobject_cast<QFormLayout *>(object: m_layout))
368 return form->horizontalSpacing();
369 break;
370 case LayoutPropertyVerticalSpacing:
371 if (const QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
372 return grid->verticalSpacing();
373 if (const QFormLayout *form = qobject_cast<QFormLayout *>(object: m_layout))
374 return form->verticalSpacing();
375 break;
376 case LayoutPropertyBoxStretch:
377 if (const QBoxLayout *box = qobject_cast<QBoxLayout *>(object: m_layout))
378 return QVariant(QByteArray(QFormBuilderExtra::boxLayoutStretch(box).toUtf8()));
379 break;
380 case LayoutPropertyGridRowStretch:
381 if (const QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
382 return QVariant(QByteArray(QFormBuilderExtra::gridLayoutRowStretch(grid).toUtf8()));
383 break;
384 case LayoutPropertyGridColumnStretch:
385 if (const QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
386 return QVariant(QByteArray(QFormBuilderExtra::gridLayoutColumnStretch(grid).toUtf8()));
387 break;
388 case LayoutPropertyGridRowMinimumHeight:
389 if (const QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
390 return QVariant(QByteArray(QFormBuilderExtra::gridLayoutRowMinimumHeight(grid).toUtf8()));
391 break;
392 case LayoutPropertyGridColumnMinimumWidth:
393 if (const QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
394 return QVariant(QByteArray(QFormBuilderExtra::gridLayoutColumnMinimumWidth(grid).toUtf8()));
395 break;
396 default:
397 break;
398 }
399 return QDesignerPropertySheet::property(index);
400}
401
402bool LayoutPropertySheet::reset(int index)
403{
404 int left, top, right, bottom;
405 m_layout->getContentsMargins(left: &left, top: &top, right: &right, bottom: &bottom);
406 const LayoutPropertyType type = layoutPropertyType(name: propertyName(index));
407 bool rc = true;
408 switch (type) {
409 case LayoutPropertyLeftMargin:
410 m_layout->setContentsMargins(left: -1, top, right, bottom);
411 break;
412 case LayoutPropertyTopMargin:
413 m_layout->setContentsMargins(left, top: -1, right, bottom);
414 break;
415 case LayoutPropertyRightMargin:
416 m_layout->setContentsMargins(left, top, right: -1, bottom);
417 break;
418 case LayoutPropertyBottomMargin:
419 m_layout->setContentsMargins(left, top, right, bottom: -1);
420 break;
421 case LayoutPropertyBoxStretch:
422 if (QBoxLayout *box = qobject_cast<QBoxLayout *>(object: m_layout))
423 QFormBuilderExtra::clearBoxLayoutStretch(box);
424 break;
425 case LayoutPropertyGridRowStretch:
426 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
427 QFormBuilderExtra::clearGridLayoutRowStretch(grid);
428 break;
429 case LayoutPropertyGridColumnStretch:
430 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
431 QFormBuilderExtra::clearGridLayoutColumnStretch(grid);
432 break;
433 case LayoutPropertyGridRowMinimumHeight:
434 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
435 QFormBuilderExtra::clearGridLayoutRowMinimumHeight(grid);
436 break;
437 case LayoutPropertyGridColumnMinimumWidth:
438 if (QGridLayout *grid = qobject_cast<QGridLayout *>(object: m_layout))
439 QFormBuilderExtra::clearGridLayoutColumnMinimumWidth(grid);
440 break;
441 default:
442 rc = QDesignerPropertySheet::reset(index);
443 break;
444 }
445 return rc;
446}
447
448void LayoutPropertySheet::setChanged(int index, bool changed)
449{
450 const LayoutPropertyType type = layoutPropertyType(name: propertyName(index));
451 switch (type) {
452 case LayoutPropertySpacing:
453 if (LayoutProperties::visibleProperties(layout: m_layout) & LayoutProperties::HorizSpacingProperty) {
454 setChanged(index: indexOf(name: QLatin1String(horizontalSpacing)), changed);
455 setChanged(index: indexOf(name: QLatin1String(verticalSpacing)), changed);
456 }
457 break;
458 case LayoutPropertyMargin:
459 setChanged(index: indexOf(name: QLatin1String(leftMargin)), changed);
460 setChanged(index: indexOf(name: QLatin1String(topMargin)), changed);
461 setChanged(index: indexOf(name: QLatin1String(rightMargin)), changed);
462 setChanged(index: indexOf(name: QLatin1String(bottomMargin)), changed);
463 break;
464 default:
465 break;
466 }
467 QDesignerPropertySheet::setChanged(index, changed);
468}
469
470void LayoutPropertySheet::stretchAttributesToDom(QDesignerFormEditorInterface *core, QLayout *lt, DomLayout *domLayout)
471{
472 // Check if the respective stretch properties of the layout are changed.
473 // If so, set them to the DOM
474 const int visibleMask = LayoutProperties::visibleProperties(layout: lt);
475 if (!(visibleMask & (LayoutProperties::BoxStretchProperty|LayoutProperties::GridColumnStretchProperty|LayoutProperties::GridRowStretchProperty)))
476 return;
477 const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(manager: core->extensionManager(), object: lt);
478 Q_ASSERT(sheet);
479
480 // Stretch
481 if (visibleMask & LayoutProperties::BoxStretchProperty) {
482 const int index = sheet->indexOf(name: QLatin1String(boxStretchPropertyC));
483 Q_ASSERT(index != -1);
484 if (sheet->isChanged(index))
485 domLayout->setAttributeStretch(sheet->property(index).toString());
486 }
487 if (visibleMask & LayoutProperties::GridColumnStretchProperty) {
488 const int index = sheet->indexOf(name: QLatin1String(gridColumnStretchPropertyC));
489 Q_ASSERT(index != -1);
490 if (sheet->isChanged(index))
491 domLayout->setAttributeColumnStretch(sheet->property(index).toString());
492 }
493 if (visibleMask & LayoutProperties::GridRowStretchProperty) {
494 const int index = sheet->indexOf(name: QLatin1String(gridRowStretchPropertyC));
495 Q_ASSERT(index != -1);
496 if (sheet->isChanged(index))
497 domLayout->setAttributeRowStretch(sheet->property(index).toString());
498 }
499 if (visibleMask & LayoutProperties::GridRowMinimumHeightProperty) {
500 const int index = sheet->indexOf(name: QLatin1String(gridRowMinimumHeightPropertyC));
501 Q_ASSERT(index != -1);
502 if (sheet->isChanged(index))
503 domLayout->setAttributeRowMinimumHeight(sheet->property(index).toString());
504 }
505 if (visibleMask & LayoutProperties::GridColumnMinimumWidthProperty) {
506 const int index = sheet->indexOf(name: QLatin1String(gridColumnMinimumWidthPropertyC));
507 Q_ASSERT(index != -1);
508 if (sheet->isChanged(index))
509 domLayout->setAttributeColumnMinimumWidth(sheet->property(index).toString());
510 }
511}
512
513void LayoutPropertySheet::markChangedStretchProperties(QDesignerFormEditorInterface *core, QLayout *lt, const DomLayout *domLayout)
514{
515 // While the actual values are applied by the form builder, we still need
516 // to mark them as 'changed'.
517 QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(manager: core->extensionManager(), object: lt);
518 Q_ASSERT(sheet);
519 if (!domLayout->attributeStretch().isEmpty())
520 sheet->setChanged(index: sheet->indexOf(name: QLatin1String(boxStretchPropertyC)), changed: true);
521 if (!domLayout->attributeRowStretch().isEmpty())
522 sheet->setChanged(index: sheet->indexOf(name: QLatin1String(gridRowStretchPropertyC)), changed: true);
523 if (!domLayout->attributeColumnStretch().isEmpty())
524 sheet->setChanged(index: sheet->indexOf(name: QLatin1String(gridColumnStretchPropertyC)), changed: true);
525 if (!domLayout->attributeColumnMinimumWidth().isEmpty())
526 sheet->setChanged(index: sheet->indexOf(name: QLatin1String(gridColumnMinimumWidthPropertyC)), changed: true);
527 if (!domLayout->attributeRowMinimumHeight().isEmpty())
528 sheet->setChanged(index: sheet->indexOf(name: QLatin1String(gridRowMinimumHeightPropertyC)), changed: true);
529}
530
531}
532
533QT_END_NAMESPACE
534

source code of qttools/src/designer/src/components/formeditor/layout_propertysheet.cpp