1/****************************************************************************
2**
3** Copyright (C) 2018 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:BSD$
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** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include "properties_p.h"
52#include "ui4_p.h"
53#include "abstractformbuilder.h"
54#include "formbuilderextra_p.h"
55#include "resourcebuilder_p.h"
56
57#include <QtCore/qdatetime.h>
58#include <QtCore/qurl.h>
59#include <QtCore/qdebug.h>
60
61#include <QtGui/qicon.h>
62#include <QtGui/qpixmap.h>
63#include <QtGui/qfont.h>
64#include <QtWidgets/qframe.h>
65#include <QtWidgets/qabstractscrollarea.h>
66
67QT_BEGIN_NAMESPACE
68
69#ifdef QFORMINTERNAL_NAMESPACE
70namespace QFormInternal
71{
72#endif
73
74static inline void fixEnum(QString &s)
75{
76 int qualifierIndex = s.lastIndexOf(c: QLatin1Char(':'));
77 if (qualifierIndex == -1)
78 qualifierIndex = s.lastIndexOf(c: QLatin1Char('.'));
79 if (qualifierIndex != -1)
80 s.remove(i: 0, len: qualifierIndex + 1);
81}
82// Convert complex DOM types with the help of QAbstractFormBuilder
83QVariant domPropertyToVariant(QAbstractFormBuilder *afb,const QMetaObject *meta,const DomProperty *p)
84{
85 // Complex types that need functions from QAbstractFormBuilder
86 switch(p->kind()) {
87 case DomProperty::String: {
88 const int index = meta->indexOfProperty(name: p->attributeName().toUtf8());
89 if (index != -1 && meta->property(index).type() == QVariant::KeySequence)
90 return QVariant::fromValue(value: QKeySequence(p->elementString()->text()));
91 }
92 break;
93
94 case DomProperty::Palette: {
95 const DomPalette *dom = p->elementPalette();
96 QPalette palette;
97
98 if (dom->elementActive())
99 afb->setupColorGroup(palette, colorGroup: QPalette::Active, group: dom->elementActive());
100
101 if (dom->elementInactive())
102 afb->setupColorGroup(palette, colorGroup: QPalette::Inactive, group: dom->elementInactive());
103
104 if (dom->elementDisabled())
105 afb->setupColorGroup(palette, colorGroup: QPalette::Disabled, group: dom->elementDisabled());
106
107 palette.setCurrentColorGroup(QPalette::Active);
108 return QVariant::fromValue(value: palette);
109 }
110
111 case DomProperty::Set: {
112 const QByteArray pname = p->attributeName().toUtf8();
113 const int index = meta->indexOfProperty(name: pname);
114 if (index == -1) {
115 uiLibWarning(message: QCoreApplication::translate(context: "QFormBuilder", key: "The set-type property %1 could not be read.").arg(a: p->attributeName()));
116 return QVariant();
117 }
118
119 const QMetaEnum e = meta->property(index).enumerator();
120 Q_ASSERT(e.isFlag() == true);
121 return QVariant(e.keysToValue(keys: p->elementSet().toUtf8()));
122 }
123
124 case DomProperty::Enum: {
125 const QByteArray pname = p->attributeName().toUtf8();
126 const int index = meta->indexOfProperty(name: pname);
127 QString enumValue = p->elementEnum();
128 // Triggers in case of objects in Designer like Spacer/Line for which properties
129 // are serialized using language introspection. On preview, however, these objects are
130 // emulated by hacks in the formbuilder (size policy/orientation)
131 fixEnum(s&: enumValue);
132 if (index == -1) {
133 // ### special-casing for Line (QFrame) -- fix for 4.2. Jambi hack for enumerations
134 if (!qstrcmp(str1: meta->className(), str2: "QFrame")
135 && (pname == QByteArray("orientation"))) {
136 return QVariant(enumValue == QFormBuilderStrings::instance().horizontalPostFix ? QFrame::HLine : QFrame::VLine);
137 }
138 uiLibWarning(message: QCoreApplication::translate(context: "QFormBuilder", key: "The enumeration-type property %1 could not be read.").arg(a: p->attributeName()));
139 return QVariant();
140 }
141
142 const QMetaEnum e = meta->property(index).enumerator();
143 return QVariant(e.keyToValue(key: enumValue.toUtf8()));
144 }
145 case DomProperty::Brush:
146 return QVariant::fromValue(value: afb->setupBrush(p->elementBrush()));
147 default:
148 if (afb->resourceBuilder()->isResourceProperty(p)) {
149 return afb->resourceBuilder()->loadResource(workingDirectory: afb->workingDirectory(), property: p);
150 }
151
152 break;
153 }
154
155 // simple type
156 return domPropertyToVariant(property: p);
157}
158
159// Convert simple DOM types
160QVariant domPropertyToVariant(const DomProperty *p)
161{
162 // requires non-const virtual nameToIcon, etc.
163 switch(p->kind()) {
164 case DomProperty::Bool:
165 return QVariant(p->elementBool() == QFormBuilderStrings::instance().trueValue);
166
167 case DomProperty::Cstring:
168 return QVariant(p->elementCstring().toUtf8());
169
170 case DomProperty::Point: {
171 const DomPoint *point = p->elementPoint();
172 return QVariant(QPoint(point->elementX(), point->elementY()));
173 }
174
175 case DomProperty::PointF: {
176 const DomPointF *pointf = p->elementPointF();
177 return QVariant(QPointF(pointf->elementX(), pointf->elementY()));
178 }
179
180 case DomProperty::Size: {
181 const DomSize *size = p->elementSize();
182 return QVariant(QSize(size->elementWidth(), size->elementHeight()));
183 }
184
185 case DomProperty::SizeF: {
186 const DomSizeF *sizef = p->elementSizeF();
187 return QVariant(QSizeF(sizef->elementWidth(), sizef->elementHeight()));
188 }
189
190 case DomProperty::Rect: {
191 const DomRect *rc = p->elementRect();
192 const QRect g(rc->elementX(), rc->elementY(), rc->elementWidth(), rc->elementHeight());
193 return QVariant(g);
194 }
195
196 case DomProperty::RectF: {
197 const DomRectF *rcf = p->elementRectF();
198 const QRectF g(rcf->elementX(), rcf->elementY(), rcf->elementWidth(), rcf->elementHeight());
199 return QVariant(g);
200 }
201
202 case DomProperty::String:
203 return QVariant(p->elementString()->text());
204
205 case DomProperty::Number:
206 return QVariant(p->elementNumber());
207
208 case DomProperty::UInt:
209 return QVariant(p->elementUInt());
210
211 case DomProperty::LongLong:
212 return QVariant(p->elementLongLong());
213
214 case DomProperty::ULongLong:
215 return QVariant(p->elementULongLong());
216
217 case DomProperty::Double:
218 return QVariant(p->elementDouble());
219
220 case DomProperty::Char: {
221 const DomChar *character = p->elementChar();
222 const QChar c(character->elementUnicode());
223 return QVariant::fromValue(value: c);
224 }
225
226 case DomProperty::Color: {
227 const DomColor *color = p->elementColor();
228 QColor c(color->elementRed(), color->elementGreen(), color->elementBlue());
229 if (color->hasAttributeAlpha())
230 c.setAlpha(color->attributeAlpha());
231 return QVariant::fromValue(value: c);
232 }
233
234 case DomProperty::Font: {
235 const DomFont *font = p->elementFont();
236
237 QFont f;
238 if (font->hasElementFamily() && !font->elementFamily().isEmpty())
239 f.setFamily(font->elementFamily());
240 if (font->hasElementPointSize() && font->elementPointSize() > 0)
241 f.setPointSize(font->elementPointSize());
242 if (font->hasElementWeight() && font->elementWeight() > 0)
243 f.setWeight(font->elementWeight());
244 if (font->hasElementItalic())
245 f.setItalic(font->elementItalic());
246 if (font->hasElementBold())
247 f.setBold(font->elementBold());
248 if (font->hasElementUnderline())
249 f.setUnderline(font->elementUnderline());
250 if (font->hasElementStrikeOut())
251 f.setStrikeOut(font->elementStrikeOut());
252 if (font->hasElementKerning())
253 f.setKerning(font->elementKerning());
254 if (font->hasElementAntialiasing())
255 f.setStyleStrategy(font->elementAntialiasing() ? QFont::PreferDefault : QFont::NoAntialias);
256 if (font->hasElementStyleStrategy()) {
257 f.setStyleStrategy(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QFont::StyleStrategy>(enumName: "styleStrategy",
258 key: font->elementStyleStrategy().toLatin1().constData()));
259 }
260 return QVariant::fromValue(value: f);
261 }
262
263 case DomProperty::Date: {
264 const DomDate *date = p->elementDate();
265 return QVariant(QDate(date->elementYear(), date->elementMonth(), date->elementDay()));
266 }
267
268 case DomProperty::Time: {
269 const DomTime *t = p->elementTime();
270 return QVariant(QTime(t->elementHour(), t->elementMinute(), t->elementSecond()));
271 }
272
273 case DomProperty::DateTime: {
274 const DomDateTime *dateTime = p->elementDateTime();
275 const QDate d(dateTime->elementYear(), dateTime->elementMonth(), dateTime->elementDay());
276 const QTime tm(dateTime->elementHour(), dateTime->elementMinute(), dateTime->elementSecond());
277 return QVariant(QDateTime(d, tm));
278 }
279
280 case DomProperty::Url: {
281 const DomUrl *url = p->elementUrl();
282 return QVariant(QUrl(url->elementString()->text()));
283 }
284
285#if QT_CONFIG(cursor)
286 case DomProperty::Cursor:
287 return QVariant::fromValue(value: QCursor(static_cast<Qt::CursorShape>(p->elementCursor())));
288
289 case DomProperty::CursorShape:
290 return QVariant::fromValue(value: QCursor(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, Qt::CursorShape>(enumName: "cursorShape",
291 key: p->elementCursorShape().toLatin1().constData())));
292#endif
293
294 case DomProperty::Locale: {
295 const DomLocale *locale = p->elementLocale();
296 return QVariant::fromValue(value: QLocale(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QLocale::Language>(enumName: "language",
297 key: locale->attributeLanguage().toLatin1().constData()),
298 enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QLocale::Country>(enumName: "country",
299 key: locale->attributeCountry().toLatin1().constData())));
300 }
301 case DomProperty::SizePolicy: {
302 const DomSizePolicy *sizep = p->elementSizePolicy();
303
304 QSizePolicy sizePolicy;
305 sizePolicy.setHorizontalStretch(sizep->elementHorStretch());
306 sizePolicy.setVerticalStretch(sizep->elementVerStretch());
307
308 const QMetaEnum sizeType_enum = metaEnum<QAbstractFormBuilderGadget>(name: "sizeType");
309
310 if (sizep->hasElementHSizeType()) {
311 sizePolicy.setHorizontalPolicy((QSizePolicy::Policy) sizep->elementHSizeType());
312 } else if (sizep->hasAttributeHSizeType()) {
313 const QSizePolicy::Policy sp = enumKeyToValue<QSizePolicy::Policy>(metaEnum: sizeType_enum, key: sizep->attributeHSizeType().toLatin1());
314 sizePolicy.setHorizontalPolicy(sp);
315 }
316
317 if (sizep->hasElementVSizeType()) {
318 sizePolicy.setVerticalPolicy((QSizePolicy::Policy) sizep->elementVSizeType());
319 } else if (sizep->hasAttributeVSizeType()) {
320 const QSizePolicy::Policy sp = enumKeyToValue<QSizePolicy::Policy>(metaEnum: sizeType_enum, key: sizep->attributeVSizeType().toLatin1());
321 sizePolicy.setVerticalPolicy(sp);
322 }
323
324 return QVariant::fromValue(value: sizePolicy);
325 }
326
327 case DomProperty::StringList:
328 return QVariant(p->elementStringList()->elementString());
329
330 default:
331 uiLibWarning(message: QCoreApplication::translate(context: "QFormBuilder", key: "Reading properties of the type %1 is not supported yet.").arg(a: p->kind()));
332 break;
333 }
334
335 return QVariant();
336}
337
338// Apply a simple variant type to a DOM property
339static bool applySimpleProperty(const QVariant &v, bool translateString, DomProperty *dom_prop)
340{
341 switch (v.type()) {
342 case QVariant::String: {
343 DomString *str = new DomString();
344 str->setText(v.toString());
345 if (!translateString)
346 str->setAttributeNotr(QStringLiteral("true"));
347 dom_prop->setElementString(str);
348 }
349 return true;
350
351 case QVariant::ByteArray:
352 dom_prop->setElementCstring(QString::fromUtf8(str: v.toByteArray()));
353 return true;
354
355 case QVariant::Int:
356 dom_prop->setElementNumber(v.toInt());
357 return true;
358
359 case QVariant::UInt:
360 dom_prop->setElementUInt(v.toUInt());
361 return true;
362
363 case QVariant::LongLong:
364 dom_prop->setElementLongLong(v.toLongLong());
365 return true;
366
367 case QVariant::ULongLong:
368 dom_prop->setElementULongLong(v.toULongLong());
369 return true;
370
371 case QVariant::Double:
372 dom_prop->setElementDouble(v.toDouble());
373 return true;
374
375 case QVariant::Bool:
376 dom_prop->setElementBool(v.toBool() ? QFormBuilderStrings::instance().trueValue : QFormBuilderStrings::instance().falseValue);
377 return true;
378
379 case QVariant::Char: {
380 DomChar *ch = new DomChar();
381 const QChar character = v.toChar();
382 ch->setElementUnicode(character.unicode());
383 dom_prop->setElementChar(ch);
384 }
385 return true;
386
387 case QVariant::Point: {
388 DomPoint *pt = new DomPoint();
389 const QPoint point = v.toPoint();
390 pt->setElementX(point.x());
391 pt->setElementY(point.y());
392 dom_prop->setElementPoint(pt);
393 }
394 return true;
395
396 case QVariant::PointF: {
397 DomPointF *ptf = new DomPointF();
398 const QPointF pointf = v.toPointF();
399 ptf->setElementX(pointf.x());
400 ptf->setElementY(pointf.y());
401 dom_prop->setElementPointF(ptf);
402 }
403 return true;
404
405 case QVariant::Color: {
406 DomColor *clr = new DomColor();
407 const QColor color = qvariant_cast<QColor>(v);
408 clr->setElementRed(color.red());
409 clr->setElementGreen(color.green());
410 clr->setElementBlue(color.blue());
411 const int alphaChannel = color.alpha();
412 if (alphaChannel != 255)
413 clr->setAttributeAlpha(alphaChannel);
414 dom_prop->setElementColor(clr);
415 }
416 return true;
417
418 case QVariant::Size: {
419 DomSize *sz = new DomSize();
420 const QSize size = v.toSize();
421 sz->setElementWidth(size.width());
422 sz->setElementHeight(size.height());
423 dom_prop->setElementSize(sz);
424 }
425 return true;
426
427 case QVariant::SizeF: {
428 DomSizeF *szf = new DomSizeF();
429 const QSizeF sizef = v.toSizeF();
430 szf->setElementWidth(sizef.width());
431 szf->setElementHeight(sizef.height());
432 dom_prop->setElementSizeF(szf);
433 }
434 return true;
435
436 case QVariant::Rect: {
437 DomRect *rc = new DomRect();
438 const QRect rect = v.toRect();
439 rc->setElementX(rect.x());
440 rc->setElementY(rect.y());
441 rc->setElementWidth(rect.width());
442 rc->setElementHeight(rect.height());
443 dom_prop->setElementRect(rc);
444 }
445 return true;
446
447 case QVariant::RectF: {
448 DomRectF *rcf = new DomRectF();
449 const QRectF rectf = v.toRectF();
450 rcf->setElementX(rectf.x());
451 rcf->setElementY(rectf.y());
452 rcf->setElementWidth(rectf.width());
453 rcf->setElementHeight(rectf.height());
454 dom_prop->setElementRectF(rcf);
455 }
456 return true;
457
458 case QVariant::Font: {
459 DomFont *fnt = new DomFont();
460 const QFont font = qvariant_cast<QFont>(v);
461 const uint mask = font.resolve();
462 if (mask & QFont::WeightResolved) {
463 fnt->setElementBold(font.bold());
464 fnt->setElementWeight(font.weight());
465 }
466 if (mask & QFont::FamilyResolved)
467 fnt->setElementFamily(font.family());
468 if (mask & QFont::StyleResolved)
469 fnt->setElementItalic(font.italic());
470 if (mask & QFont::SizeResolved)
471 fnt->setElementPointSize(font.pointSize());
472 if (mask & QFont::StrikeOutResolved)
473 fnt->setElementStrikeOut(font.strikeOut());
474 if (mask & QFont::UnderlineResolved)
475 fnt->setElementUnderline(font.underline());
476 if (mask & QFont::KerningResolved)
477 fnt->setElementKerning(font.kerning());
478 if (mask & QFont::StyleStrategyResolved) {
479 const QMetaEnum styleStrategy_enum = metaEnum<QAbstractFormBuilderGadget>(name: "styleStrategy");
480 fnt->setElementStyleStrategy(QLatin1String(styleStrategy_enum.valueToKey(value: font.styleStrategy())));
481 }
482 dom_prop->setElementFont(fnt);
483 }
484 return true;
485
486#if QT_CONFIG(cursor)
487 case QVariant::Cursor: {
488 const QMetaEnum cursorShape_enum = metaEnum<QAbstractFormBuilderGadget>(name: "cursorShape");
489 dom_prop->setElementCursorShape(QLatin1String(cursorShape_enum.valueToKey(value: qvariant_cast<QCursor>(v).shape())));
490 }
491 return true;
492#endif
493
494 case QVariant::KeySequence: {
495 DomString *s = new DomString();
496 s->setText(qvariant_cast<QKeySequence>(v).toString(format: QKeySequence::PortableText));
497 dom_prop->setElementString(s);
498 }
499 return true;
500
501 case QVariant::Locale: {
502 DomLocale *dom = new DomLocale();
503 const QLocale locale = qvariant_cast<QLocale>(v);
504
505 const QMetaEnum language_enum = metaEnum<QAbstractFormBuilderGadget>(name: "language");
506 const QMetaEnum country_enum = metaEnum<QAbstractFormBuilderGadget>(name: "country");
507
508 dom->setAttributeLanguage(QLatin1String(language_enum.valueToKey(value: locale.language())));
509 dom->setAttributeCountry(QLatin1String(country_enum.valueToKey(value: locale.country())));
510
511 dom_prop->setElementLocale(dom);
512 }
513 return true;
514
515 case QVariant::SizePolicy: {
516 DomSizePolicy *dom = new DomSizePolicy();
517 const QSizePolicy sizePolicy = qvariant_cast<QSizePolicy>(v);
518
519 dom->setElementHorStretch(sizePolicy.horizontalStretch());
520 dom->setElementVerStretch(sizePolicy.verticalStretch());
521
522 const QMetaEnum sizeType_enum = metaEnum<QAbstractFormBuilderGadget>(name: "sizeType");
523
524 dom->setAttributeHSizeType(QLatin1String(sizeType_enum.valueToKey(value: sizePolicy.horizontalPolicy())));
525 dom->setAttributeVSizeType(QLatin1String(sizeType_enum.valueToKey(value: sizePolicy.verticalPolicy())));
526
527 dom_prop->setElementSizePolicy(dom);
528 }
529 return true;
530
531 case QVariant::Date: {
532 DomDate *dom = new DomDate();
533 const QDate date = qvariant_cast<QDate>(v);
534
535 dom->setElementYear(date.year());
536 dom->setElementMonth(date.month());
537 dom->setElementDay(date.day());
538
539 dom_prop->setElementDate(dom);
540 }
541 return true;
542
543 case QVariant::Time: {
544 DomTime *dom = new DomTime();
545 const QTime time = qvariant_cast<QTime>(v);
546
547 dom->setElementHour(time.hour());
548 dom->setElementMinute(time.minute());
549 dom->setElementSecond(time.second());
550
551 dom_prop->setElementTime(dom);
552 }
553 return true;
554
555 case QVariant::DateTime: {
556 DomDateTime *dom = new DomDateTime();
557 const QDateTime dateTime = qvariant_cast<QDateTime>(v);
558
559 dom->setElementHour(dateTime.time().hour());
560 dom->setElementMinute(dateTime.time().minute());
561 dom->setElementSecond(dateTime.time().second());
562 dom->setElementYear(dateTime.date().year());
563 dom->setElementMonth(dateTime.date().month());
564 dom->setElementDay(dateTime.date().day());
565
566 dom_prop->setElementDateTime(dom);
567 }
568 return true;
569
570 case QVariant::Url: {
571 DomUrl *dom = new DomUrl();
572 const QUrl url = v.toUrl();
573
574 DomString *str = new DomString();
575 str->setText(url.toString());
576 dom->setElementString(str);
577
578 dom_prop->setElementUrl(dom);
579 }
580 return true;
581
582 case QVariant::StringList: {
583 DomStringList *sl = new DomStringList;
584 sl->setElementString(qvariant_cast<QStringList>(v));
585 dom_prop->setElementStringList(sl);
586 }
587 return true;
588
589 default:
590 break;
591 }
592
593 return false;
594}
595static QString msgCannotWriteProperty(const QString &pname, const QVariant &v)
596{
597 return QCoreApplication::translate(context: "QFormBuilder", key: "The property %1 could not be written. The type %2 is not supported yet.").
598 arg(a: pname).arg(a: QLatin1String(v.typeName()));
599
600}
601
602static bool isOfType(const QMetaObject *what, const QMetaObject *type)
603{
604 do {
605 if (what == type)
606 return true;
607 } while ((what = what->superClass()));
608 return false;
609}
610
611static bool isTranslatable(const QString &pname, const QVariant &v, const QMetaObject *meta)
612{
613 const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
614 if (pname == strings.objectNameProperty)
615 return false;
616 if (pname == strings.styleSheetProperty && v.type() == QVariant::String && isOfType(what: meta, type: &QWidget::staticMetaObject))
617 return false;
618 return true;
619}
620
621// Convert complex variant types to DOM properties with the help of QAbstractFormBuilder
622// Does not perform a check using QAbstractFormBuilder::checkProperty().
623DomProperty *variantToDomProperty(QAbstractFormBuilder *afb, const QMetaObject *meta,
624 const QString &pname, const QVariant &v)
625{
626 const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
627
628 DomProperty *dom_prop = new DomProperty();
629 dom_prop->setAttributeName(pname);
630
631 const int pindex = meta->indexOfProperty(name: pname.toLatin1());
632 if (pindex != -1) {
633 QMetaProperty meta_property = meta->property(index: pindex);
634 if ((v.type() == QVariant::Int || v.type() == QVariant::UInt) && meta_property.isEnumType()) {
635 const QMetaEnum e = meta_property.enumerator();
636 if (e.isFlag())
637 dom_prop->setElementSet(QString::fromLatin1(str: e.valueToKeys(value: v.toInt())));
638 else
639 dom_prop->setElementEnum(QString::fromLatin1(str: e.valueToKey(value: v.toInt())));
640 return dom_prop;
641 }
642 if (!meta_property.hasStdCppSet() || (isOfType(what: meta, type: &QAbstractScrollArea::staticMetaObject) && pname == strings.cursorProperty))
643 dom_prop->setAttributeStdset(0);
644 }
645
646 // Try simple properties
647 if (applySimpleProperty(v, translateString: isTranslatable(pname, v, meta), dom_prop))
648 return dom_prop;
649
650 // Complex properties
651 switch (v.type()) {
652 case QVariant::Palette: {
653 DomPalette *dom = new DomPalette();
654 QPalette palette = qvariant_cast<QPalette>(v);
655
656 palette.setCurrentColorGroup(QPalette::Active);
657 dom->setElementActive(afb->saveColorGroup(palette));
658
659 palette.setCurrentColorGroup(QPalette::Inactive);
660 dom->setElementInactive(afb->saveColorGroup(palette));
661
662 palette.setCurrentColorGroup(QPalette::Disabled);
663 dom->setElementDisabled(afb->saveColorGroup(palette));
664
665 dom_prop->setElementPalette(dom);
666 } break;
667 case QVariant::Brush:
668 dom_prop->setElementBrush(afb->saveBrush(brush: qvariant_cast<QBrush>(v)));
669 break;
670 default: {
671 const bool hadAttributeStdset = dom_prop->hasAttributeStdset();
672 const bool attributeStdset = dom_prop->attributeStdset();
673 delete dom_prop;
674 if (afb->resourceBuilder()->isResourceType(value: v)) {
675 dom_prop = afb->resourceBuilder()->saveResource(workingDirectory: afb->workingDirectory(), value: v);
676 if (dom_prop) {
677 dom_prop->setAttributeName(pname);
678 if (hadAttributeStdset)
679 dom_prop->setAttributeStdset(attributeStdset);
680 }
681 break;
682 }
683 uiLibWarning(message: msgCannotWriteProperty(pname, v));
684 } return nullptr;
685 }
686 return dom_prop;
687}
688
689#ifdef QFORMINTERNAL_NAMESPACE
690}
691#endif
692
693QT_END_NAMESPACE
694

source code of qttools/src/designer/src/lib/uilib/properties.cpp