Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
properties.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "properties_p.h"
6#include "ui4_p.h"
10
11#include <QtCore/qdatetime.h>
12#include <QtCore/qurl.h>
13#include <QtCore/qdebug.h>
14
15#include <QtGui/qicon.h>
16#include <QtGui/qpixmap.h>
17#include <QtGui/qfont.h>
18#include <QtWidgets/qframe.h>
19#include <QtWidgets/qabstractscrollarea.h>
20
21#include <limits>
22
24
25using namespace Qt::StringLiterals;
26
27#ifdef QFORMINTERNAL_NAMESPACE
28namespace QFormInternal
29{
30#endif
31
32// Convert complex DOM types with the help of QAbstractFormBuilder
33QVariant domPropertyToVariant(QAbstractFormBuilder *afb,const QMetaObject *meta,const DomProperty *p)
34{
35 // Complex types that need functions from QAbstractFormBuilder
36 switch(p->kind()) {
37 case DomProperty::String: {
38 const int index = meta->indexOfProperty(p->attributeName().toUtf8().constData());
39 if (index != -1 && meta->property(index).metaType().id() == QMetaType::QKeySequence)
40 return QVariant::fromValue(QKeySequence(p->elementString()->text()));
41 }
42 break;
43
44 case DomProperty::Palette: {
45 const DomPalette *dom = p->elementPalette();
46 QPalette palette;
47
48 if (dom->elementActive())
49 afb->setupColorGroup(palette, QPalette::Active, dom->elementActive());
50
51 if (dom->elementInactive())
52 afb->setupColorGroup(palette, QPalette::Inactive, dom->elementInactive());
53
54 if (dom->elementDisabled())
55 afb->setupColorGroup(palette, QPalette::Disabled, dom->elementDisabled());
56
57 palette.setCurrentColorGroup(QPalette::Active);
58 return QVariant::fromValue(palette);
59 }
60
61 case DomProperty::Set: {
62 const QByteArray pname = p->attributeName().toUtf8();
63 const int index = meta->indexOfProperty(pname.constData());
64 if (index == -1) {
65 uiLibWarning(QCoreApplication::translate("QFormBuilder", "The set-type property %1 could not be read.").arg(p->attributeName()));
66 return QVariant();
67 }
68
69 const QMetaEnum e = meta->property(index).enumerator();
70 Q_ASSERT(e.isFlag() == true);
71 bool ok{};
72 QVariant result(e.keysToValue(p->elementSet().toUtf8().constData(), &ok));
73 if (!ok) {
74 uiLibWarning(QCoreApplication::translate("QFormBuilder",
75 "The value \"%1\" of the set-type property %2 could not be read.").
76 arg(p->elementSet(), p->attributeName()));
77 return {};
78 }
79 return result;
80 }
81
82 case DomProperty::Enum: {
83 const QByteArray pname = p->attributeName().toUtf8().constData();
84 const int index = meta->indexOfProperty(pname.constData());
85 const auto &enumValue = p->elementEnum();
86 // Triggers in case of objects in Designer like Spacer/Line for which properties
87 // are serialized using language introspection. On preview, however, these objects are
88 // emulated by hacks in the formbuilder (size policy/orientation)
89 if (index == -1) {
90 // ### special-casing for Line (QFrame) -- fix for 4.2. Jambi hack for enumerations
91 if (!qstrcmp(meta->className(), "QFrame")
92 && (pname == QByteArray("orientation"))) {
93 return QVariant(enumValue.endsWith("Horizontal"_L1) ? QFrame::HLine : QFrame::VLine);
94 }
95 uiLibWarning(QCoreApplication::translate("QFormBuilder", "The enumeration-type property %1 could not be read.").arg(p->attributeName()));
96 return QVariant();
97 }
98
99 const QMetaEnum e = meta->property(index).enumerator();
100 bool ok{};
101 QVariant result(e.keyToValue(enumValue.toUtf8().constData(), &ok));
102 if (!ok) {
103 uiLibWarning(QCoreApplication::translate("QFormBuilder",
104 "The value \"%1\" of the enum-type property %2 could not be read.").
105 arg(enumValue, p->attributeName()));
106 return {};
107 }
108 return result;
109 }
110 case DomProperty::Brush:
111 return QVariant::fromValue(afb->setupBrush(p->elementBrush()));
112 default:
113 if (afb->resourceBuilder()->isResourceProperty(p)) {
114 return afb->resourceBuilder()->loadResource(afb->workingDirectory(), p);
115 }
116
117 break;
118 }
119
120 // simple type
121 return domPropertyToVariant(p);
122}
123
124// Convert a legacy Qt 4 integer font weight to the closes enumeration value
125
127{
128 const QMetaEnum result = metaEnum<QAbstractFormBuilderGadget>("fontWeight");
129 Q_ASSERT(result.isValid());
130 return result;
131}
132
133// Convert simple DOM types
134QVariant domPropertyToVariant(const DomProperty *p)
135{
136 // requires non-const virtual nameToIcon, etc.
137 switch(p->kind()) {
138 case DomProperty::Bool:
139 return QVariant(p->elementBool() == "true"_L1);
140
141 case DomProperty::Cstring:
142 return QVariant(p->elementCstring().toUtf8());
143
144 case DomProperty::Point: {
145 const DomPoint *point = p->elementPoint();
146 return QVariant(QPoint(point->elementX(), point->elementY()));
147 }
148
149 case DomProperty::PointF: {
150 const DomPointF *pointf = p->elementPointF();
151 return QVariant(QPointF(pointf->elementX(), pointf->elementY()));
152 }
153
154 case DomProperty::Size: {
155 const DomSize *size = p->elementSize();
156 return QVariant(QSize(size->elementWidth(), size->elementHeight()));
157 }
158
159 case DomProperty::SizeF: {
160 const DomSizeF *sizef = p->elementSizeF();
161 return QVariant(QSizeF(sizef->elementWidth(), sizef->elementHeight()));
162 }
163
164 case DomProperty::Rect: {
165 const DomRect *rc = p->elementRect();
166 const QRect g(rc->elementX(), rc->elementY(), rc->elementWidth(), rc->elementHeight());
167 return QVariant(g);
168 }
169
170 case DomProperty::RectF: {
171 const DomRectF *rcf = p->elementRectF();
172 const QRectF g(rcf->elementX(), rcf->elementY(), rcf->elementWidth(), rcf->elementHeight());
173 return QVariant(g);
174 }
175
176 case DomProperty::String:
177 return QVariant(p->elementString()->text());
178
179 case DomProperty::Number:
180 return QVariant(p->elementNumber());
181
182 case DomProperty::UInt:
183 return QVariant(p->elementUInt());
184
185 case DomProperty::LongLong:
186 return QVariant(p->elementLongLong());
187
188 case DomProperty::ULongLong:
189 return QVariant(p->elementULongLong());
190
191 case DomProperty::Double:
192 return QVariant(p->elementDouble());
193
194 case DomProperty::Char: {
195 const DomChar *character = p->elementChar();
196 const QChar c(character->elementUnicode());
197 return QVariant::fromValue(c);
198 }
199
200 case DomProperty::Color: {
201 const DomColor *color = p->elementColor();
202 QColor c(color->elementRed(), color->elementGreen(), color->elementBlue());
203 if (color->hasAttributeAlpha())
204 c.setAlpha(color->attributeAlpha());
205 return QVariant::fromValue(c);
206 }
207
208 case DomProperty::Font: {
209 const DomFont *font = p->elementFont();
210
211 QFont f;
212 if (font->hasElementFamily() && !font->elementFamily().isEmpty())
213 f.setFamily(font->elementFamily());
214 if (font->hasElementPointSize() && font->elementPointSize() > 0)
215 f.setPointSize(font->elementPointSize());
216 if (font->hasElementItalic())
217 f.setItalic(font->elementItalic());
218 if (font->hasElementUnderline())
219 f.setUnderline(font->elementUnderline());
220 if (font->hasElementStrikeOut())
221 f.setStrikeOut(font->elementStrikeOut());
222 if (font->hasElementKerning())
223 f.setKerning(font->elementKerning());
224 if (font->hasElementAntialiasing())
225 f.setStyleStrategy(font->elementAntialiasing() ? QFont::PreferDefault : QFont::NoAntialias);
226 if (font->hasElementStyleStrategy()) {
227 f.setStyleStrategy(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QFont::StyleStrategy>("styleStrategy",
228 font->elementStyleStrategy().toLatin1().constData()));
229 }
230 if (font->hasElementHintingPreference()) {
231 f.setHintingPreference(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QFont::HintingPreference>("hintingPreference",
232 font->elementHintingPreference().toLatin1().constData()));
233 }
234
235 if (font->hasElementFontWeight()) {
236 f.setWeight(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QFont::Weight>(
237 "fontWeight",
238 font->elementFontWeight().toLatin1().constData()));
239 } else if (font->hasElementBold()) {
240 f.setBold(font->elementBold());
241 }
242
243 return QVariant::fromValue(f);
244 }
245
246 case DomProperty::Date: {
247 const DomDate *date = p->elementDate();
248 return QVariant(QDate(date->elementYear(), date->elementMonth(), date->elementDay()));
249 }
250
251 case DomProperty::Time: {
252 const DomTime *t = p->elementTime();
253 return QVariant(QTime(t->elementHour(), t->elementMinute(), t->elementSecond()));
254 }
255
256 case DomProperty::DateTime: {
257 const DomDateTime *dateTime = p->elementDateTime();
258 const QDate d(dateTime->elementYear(), dateTime->elementMonth(), dateTime->elementDay());
259 const QTime tm(dateTime->elementHour(), dateTime->elementMinute(), dateTime->elementSecond());
260 return QVariant(QDateTime(d, tm));
261 }
262
263 case DomProperty::Url: {
264 const DomUrl *url = p->elementUrl();
265 return QVariant(QUrl(url->elementString()->text()));
266 }
267
268#if QT_CONFIG(cursor)
269 case DomProperty::Cursor:
270 return QVariant::fromValue(QCursor(static_cast<Qt::CursorShape>(p->elementCursor())));
271
272 case DomProperty::CursorShape:
273 return QVariant::fromValue(QCursor(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, Qt::CursorShape>("cursorShape",
274 p->elementCursorShape().toLatin1().constData())));
275#endif
276
277 case DomProperty::Locale: {
278 const DomLocale *locale = p->elementLocale();
279 return QVariant::fromValue(QLocale(enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QLocale::Language>("language",
280 locale->attributeLanguage().toLatin1().constData()),
281 enumKeyOfObjectToValue<QAbstractFormBuilderGadget, QLocale::Territory>("country",
282 locale->attributeCountry().toLatin1().constData())));
283 }
284 case DomProperty::SizePolicy: {
285 const DomSizePolicy *sizep = p->elementSizePolicy();
286
287 QSizePolicy sizePolicy;
288 sizePolicy.setHorizontalStretch(sizep->elementHorStretch());
289 sizePolicy.setVerticalStretch(sizep->elementVerStretch());
290
291 const QMetaEnum sizeType_enum = metaEnum<QAbstractFormBuilderGadget>("sizeType");
292
293 if (sizep->hasElementHSizeType()) {
294 sizePolicy.setHorizontalPolicy((QSizePolicy::Policy) sizep->elementHSizeType());
295 } else if (sizep->hasAttributeHSizeType()) {
296 const auto sp = enumKeyToValue<QSizePolicy::Policy>(
297 sizeType_enum, sizep->attributeHSizeType().toLatin1().constData());
298 sizePolicy.setHorizontalPolicy(sp);
299 }
300
301 if (sizep->hasElementVSizeType()) {
302 sizePolicy.setVerticalPolicy((QSizePolicy::Policy) sizep->elementVSizeType());
303 } else if (sizep->hasAttributeVSizeType()) {
304 const auto sp = enumKeyToValue<QSizePolicy::Policy>(
305 sizeType_enum, sizep->attributeVSizeType().toLatin1().constData());
306 sizePolicy.setVerticalPolicy(sp);
307 }
308
309 return QVariant::fromValue(sizePolicy);
310 }
311
312 case DomProperty::StringList:
313 return QVariant(p->elementStringList()->elementString());
314
315 default:
316 uiLibWarning(QCoreApplication::translate("QFormBuilder", "Reading properties of the type %1 is not supported yet.").arg(p->kind()));
317 break;
318 }
319
320 return QVariant();
321}
322
323// Apply a simple variant type to a DOM property
324static bool applySimpleProperty(const QVariant &v, bool translateString, DomProperty *dom_prop)
325{
326 switch (v.metaType().id()) {
327 case QMetaType::QString: {
328 auto *str = new DomString();
329 str->setText(v.toString());
330 if (!translateString)
331 str->setAttributeNotr(u"true"_s);
332 dom_prop->setElementString(str);
333 }
334 return true;
335
336 case QMetaType::QByteArray:
337 dom_prop->setElementCstring(QString::fromUtf8(v.toByteArray()));
338 return true;
339
340 case QMetaType::Int:
341 dom_prop->setElementNumber(v.toInt());
342 return true;
343
344 case QMetaType::UInt:
345 dom_prop->setElementUInt(v.toUInt());
346 return true;
347
348 case QMetaType::LongLong:
349 dom_prop->setElementLongLong(v.toLongLong());
350 return true;
351
352 case QMetaType::ULongLong:
353 dom_prop->setElementULongLong(v.toULongLong());
354 return true;
355
356 case QMetaType::Double:
357 dom_prop->setElementDouble(v.toDouble());
358 return true;
359
360 case QMetaType::Bool:
361 dom_prop->setElementBool(v.toBool() ? "true"_L1 : "false"_L1);
362 return true;
363
364 case QMetaType::QChar: {
365 auto *ch = new DomChar();
366 const QChar character = v.toChar();
367 ch->setElementUnicode(character.unicode());
368 dom_prop->setElementChar(ch);
369 }
370 return true;
371
372 case QMetaType::QPoint: {
373 auto *pt = new DomPoint();
374 const QPoint point = v.toPoint();
375 pt->setElementX(point.x());
376 pt->setElementY(point.y());
377 dom_prop->setElementPoint(pt);
378 }
379 return true;
380
381 case QMetaType::QPointF: {
382 auto *ptf = new DomPointF();
383 const QPointF pointf = v.toPointF();
384 ptf->setElementX(pointf.x());
385 ptf->setElementY(pointf.y());
386 dom_prop->setElementPointF(ptf);
387 }
388 return true;
389
390 case QMetaType::QColor: {
391 auto *clr = new DomColor();
392 const auto color = qvariant_cast<QColor>(v);
393 clr->setElementRed(color.red());
394 clr->setElementGreen(color.green());
395 clr->setElementBlue(color.blue());
396 const int alphaChannel = color.alpha();
397 if (alphaChannel != 255)
398 clr->setAttributeAlpha(alphaChannel);
399 dom_prop->setElementColor(clr);
400 }
401 return true;
402
403 case QMetaType::QSize: {
404 auto *sz = new DomSize();
405 const QSize size = v.toSize();
406 sz->setElementWidth(size.width());
407 sz->setElementHeight(size.height());
408 dom_prop->setElementSize(sz);
409 }
410 return true;
411
412 case QMetaType::QSizeF: {
413 auto *szf = new DomSizeF();
414 const QSizeF sizef = v.toSizeF();
415 szf->setElementWidth(sizef.width());
416 szf->setElementHeight(sizef.height());
417 dom_prop->setElementSizeF(szf);
418 }
419 return true;
420
421 case QMetaType::QRect: {
422 auto *rc = new DomRect();
423 const QRect rect = v.toRect();
424 rc->setElementX(rect.x());
425 rc->setElementY(rect.y());
426 rc->setElementWidth(rect.width());
427 rc->setElementHeight(rect.height());
428 dom_prop->setElementRect(rc);
429 }
430 return true;
431
432 case QMetaType::QRectF: {
433 auto *rcf = new DomRectF();
434 const QRectF rectf = v.toRectF();
435 rcf->setElementX(rectf.x());
436 rcf->setElementY(rectf.y());
437 rcf->setElementWidth(rectf.width());
438 rcf->setElementHeight(rectf.height());
439 dom_prop->setElementRectF(rcf);
440 }
441 return true;
442
443 case QMetaType::QFont: {
444 auto *fnt = new DomFont();
445 const auto font = qvariant_cast<QFont>(v);
446 const uint mask = font.resolveMask();
447 if (mask & QFont::WeightResolved) {
448 switch (font.weight()) {
449 case QFont::Normal:
450 fnt->setElementBold(false);
451 break;
452 case QFont::Bold:
453 fnt->setElementBold(true);
454 break;
455 default: {
456 const QMetaEnum me = fontWeightMetaEnum();
457 const QString ws = QLatin1StringView(me.valueToKey(font.weight()));
458 fnt->setElementFontWeight(ws);
459 }
460 break;
461 }
462 }
463 if ((mask & (QFont::FamilyResolved | QFont::FamiliesResolved)) != 0)
464 fnt->setElementFamily(font.family());
465 if (mask & QFont::StyleResolved)
466 fnt->setElementItalic(font.italic());
467 if (mask & QFont::SizeResolved)
468 fnt->setElementPointSize(font.pointSize());
469 if (mask & QFont::StrikeOutResolved)
470 fnt->setElementStrikeOut(font.strikeOut());
471 if (mask & QFont::UnderlineResolved)
472 fnt->setElementUnderline(font.underline());
473 if (mask & QFont::KerningResolved)
474 fnt->setElementKerning(font.kerning());
475 if (mask & QFont::StyleStrategyResolved) {
476 const QMetaEnum styleStrategy_enum = metaEnum<QAbstractFormBuilderGadget>("styleStrategy");
477 fnt->setElementStyleStrategy(QLatin1StringView(styleStrategy_enum.valueToKey(font.styleStrategy())));
478 }
479 if (mask & QFont::HintingPreferenceResolved) {
480 const QMetaEnum hintingPreference_enum = metaEnum<QAbstractFormBuilderGadget>("hintingPreference");
481 fnt->setElementHintingPreference(QLatin1StringView(hintingPreference_enum.valueToKey(font.hintingPreference())));
482 }
483
484 dom_prop->setElementFont(fnt);
485 }
486 return true;
487
488#if QT_CONFIG(cursor)
489 case QMetaType::QCursor: {
490 const QMetaEnum cursorShape_enum = metaEnum<QAbstractFormBuilderGadget>("cursorShape");
491 dom_prop->setElementCursorShape(QLatin1StringView(cursorShape_enum.valueToKey(qvariant_cast<QCursor>(v).shape())));
492 }
493 return true;
494#endif
495
496 case QMetaType::QKeySequence: {
497 auto *s = new DomString();
498 s->setText(qvariant_cast<QKeySequence>(v).toString(QKeySequence::PortableText));
499 dom_prop->setElementString(s);
500 }
501 return true;
502
503 case QMetaType::QLocale: {
504 auto *dom = new DomLocale();
505 const auto locale = qvariant_cast<QLocale>(v);
506
507 const QMetaEnum language_enum = metaEnum<QAbstractFormBuilderGadget>("language");
508 const QMetaEnum territory_enum = metaEnum<QAbstractFormBuilderGadget>("country");
509
510 dom->setAttributeLanguage(QLatin1StringView(language_enum.valueToKey(locale.language())));
511 dom->setAttributeCountry(QLatin1StringView(territory_enum.valueToKey(locale.territory())));
512
513 dom_prop->setElementLocale(dom);
514 }
515 return true;
516
517 case QMetaType::QSizePolicy: {
518 auto *dom = new DomSizePolicy();
519 const auto sizePolicy = qvariant_cast<QSizePolicy>(v);
520
521 dom->setElementHorStretch(sizePolicy.horizontalStretch());
522 dom->setElementVerStretch(sizePolicy.verticalStretch());
523
524 const QMetaEnum sizeType_enum = metaEnum<QAbstractFormBuilderGadget>("sizeType");
525
526 dom->setAttributeHSizeType(QLatin1StringView(sizeType_enum.valueToKey(sizePolicy.horizontalPolicy())));
527 dom->setAttributeVSizeType(QLatin1StringView(sizeType_enum.valueToKey(sizePolicy.verticalPolicy())));
528
529 dom_prop->setElementSizePolicy(dom);
530 }
531 return true;
532
533 case QMetaType::QDate: {
534 auto *dom = new DomDate();
535 const auto date = qvariant_cast<QDate>(v);
536
537 dom->setElementYear(date.year());
538 dom->setElementMonth(date.month());
539 dom->setElementDay(date.day());
540
541 dom_prop->setElementDate(dom);
542 }
543 return true;
544
545 case QMetaType::QTime: {
546 auto *dom = new DomTime();
547 const auto time = qvariant_cast<QTime>(v);
548
549 dom->setElementHour(time.hour());
550 dom->setElementMinute(time.minute());
551 dom->setElementSecond(time.second());
552
553 dom_prop->setElementTime(dom);
554 }
555 return true;
556
557 case QMetaType::QDateTime: {
558 auto *dom = new DomDateTime();
559 const auto dateTime = qvariant_cast<QDateTime>(v);
560
561 dom->setElementHour(dateTime.time().hour());
562 dom->setElementMinute(dateTime.time().minute());
563 dom->setElementSecond(dateTime.time().second());
564 dom->setElementYear(dateTime.date().year());
565 dom->setElementMonth(dateTime.date().month());
566 dom->setElementDay(dateTime.date().day());
567
568 dom_prop->setElementDateTime(dom);
569 }
570 return true;
571
572 case QMetaType::QUrl: {
573 auto *dom = new DomUrl();
574 const QUrl url = v.toUrl();
575
576 auto *str = new DomString();
577 str->setText(url.toString());
578 dom->setElementString(str);
579
580 dom_prop->setElementUrl(dom);
581 }
582 return true;
583
584 case QMetaType::QStringList: {
585 auto *sl = new DomStringList;
586 sl->setElementString(qvariant_cast<QStringList>(v));
587 dom_prop->setElementStringList(sl);
588 }
589 return true;
590
591 default:
592 break;
593 }
594
595 return false;
596}
597static QString msgCannotWriteProperty(const QString &pname, const QVariant &v)
598{
599 return QCoreApplication::translate("QFormBuilder", "The property %1 could not be written. The type %2 is not supported yet.").
600 arg(pname).arg(QLatin1StringView(v.typeName()));
601
602}
603
604static bool isOfType(const QMetaObject *what, const QMetaObject *type)
605{
606 do {
607 if (what == type)
608 return true;
609 } while ((what = what->superClass()));
610 return false;
611}
612
613static bool isTranslatable(const QString &pname, const QVariant &v, const QMetaObject *meta)
614{
615 if (pname == "objectName"_L1)
616 return false;
617 if (pname == "styleSheet"_L1 && v.metaType().id() == QMetaType::QString
618 && isOfType(meta, &QWidget::staticMetaObject)) {
619 return false;
620 }
621 return true;
622}
623
624// PYSIDE-3278 (since 7.0) Write fully qualified enums for Python. This code
625// path is used by QFormBuilder or Qt Widgets Designer when writing item view
626// content properties such as alignment (oversight from PYSIDE-2492, see also
627// qdesigner_resource.cpp).
628static bool supportsQualifiedEnums(const QVersionNumber &qtVersion)
629{
630 return qtVersion >= QVersionNumber{ 7, 0, 0 };
631}
632
633static QString enumPrefix(QMetaEnum metaEnum)
634{
635 QString result;
636 if (const auto *scope = metaEnum.scope())
637 result += QLatin1StringView(scope) + "::"_L1;
638 if (const auto *name = metaEnum.enumName()) // Anonymous?
639 result += QLatin1StringView(name) + "::"_L1;
640 return result;
641}
642
643static QString enumValue(QMetaEnum metaEnum, int v, const QVersionNumber &qtVersion)
644{
645 auto value = QLatin1StringView(metaEnum.valueToKey(v));
646 return supportsQualifiedEnums(qtVersion) ? enumPrefix(metaEnum) + value : QString{ value };
647}
648
649static QString flagsValue(QMetaEnum metaEnum, int v, const QVersionNumber &qtVersion)
650{
651 QString result = QLatin1StringView(metaEnum.valueToKeys(v));
652 if (supportsQualifiedEnums(qtVersion) && !result.isEmpty()) {
653 const QString prefix = enumPrefix(metaEnum);
654 result.replace(u'|', u'|' + prefix);
655 result.prepend(prefix);
656 }
657 return result;
658}
659
660// Convert complex variant types to DOM properties with the help of QAbstractFormBuilder
661// Does not perform a check using QAbstractFormBuilder::checkProperty().
662DomProperty *variantToDomProperty(QAbstractFormBuilder *afb, const QMetaObject *meta,
663 const QString &pname, const QVariant &v)
664{
665 auto *dom_prop = new DomProperty();
666 dom_prop->setAttributeName(pname);
667
668 const int pindex = meta->indexOfProperty(pname.toLatin1().constData());
669 if (pindex != -1) {
670 QMetaProperty meta_property = meta->property(pindex);
671 if (v.canConvert<int>() && meta_property.isEnumType()) {
672 const QMetaEnum e = meta_property.enumerator();
673 if (e.isFlag())
674 dom_prop->setElementSet(flagsValue(e, v.toInt(), afb->d->m_saveVersion));
675 else
676 dom_prop->setElementEnum(enumValue(e, v.toInt(), afb->d->m_saveVersion));
677 return dom_prop;
678 }
679 if (!meta_property.hasStdCppSet()
680 || (isOfType(meta, &QAbstractScrollArea::staticMetaObject)
681 && pname == "cursor"_L1)) {
682 dom_prop->setAttributeStdset(0);
683 }
684 }
685
686 // Try simple properties
687 if (applySimpleProperty(v, isTranslatable(pname, v, meta), dom_prop))
688 return dom_prop;
689
690 // Complex properties
691 switch (v.metaType().id()) {
692 case QMetaType::QPalette: {
693 auto *dom = new DomPalette();
694 auto palette = qvariant_cast<QPalette>(v);
695
696 palette.setCurrentColorGroup(QPalette::Active);
697 dom->setElementActive(afb->saveColorGroup(palette));
698
699 palette.setCurrentColorGroup(QPalette::Inactive);
700 dom->setElementInactive(afb->saveColorGroup(palette));
701
702 palette.setCurrentColorGroup(QPalette::Disabled);
703 dom->setElementDisabled(afb->saveColorGroup(palette));
704
705 dom_prop->setElementPalette(dom);
706 } break;
707 case QMetaType::QBrush:
708 dom_prop->setElementBrush(afb->saveBrush(qvariant_cast<QBrush>(v)));
709 break;
710 default: {
711 const bool hadAttributeStdset = dom_prop->hasAttributeStdset();
712 const bool attributeStdset = dom_prop->attributeStdset();
713 delete dom_prop;
714 if (afb->resourceBuilder()->isResourceType(v)) {
715 dom_prop = afb->resourceBuilder()->saveResource(afb->workingDirectory(), v);
716 if (dom_prop) {
717 dom_prop->setAttributeName(pname);
718 if (hadAttributeStdset)
719 dom_prop->setAttributeStdset(attributeStdset);
720 }
721 break;
722 }
723 uiLibWarning(msgCannotWriteProperty(pname, v));
724 } return nullptr;
725 }
726 return dom_prop;
727}
728
729#ifdef QFORMINTERNAL_NAMESPACE
730}
731#endif
732
733QT_END_NAMESPACE
Combined button and popup list for selecting options.
static bool isOfType(const QMetaObject *what, const QMetaObject *type)
static bool applySimpleProperty(const QVariant &v, bool translateString, DomProperty *dom_prop)
static QMetaEnum fontWeightMetaEnum()
DomProperty * variantToDomProperty(QAbstractFormBuilder *afb, const QMetaObject *meta, const QString &pname, const QVariant &v)
static QString flagsValue(QMetaEnum metaEnum, int v, const QVersionNumber &qtVersion)
static QString msgCannotWriteProperty(const QString &pname, const QVariant &v)
static bool isTranslatable(const QString &pname, const QVariant &v, const QMetaObject *meta)
static QString enumPrefix(QMetaEnum metaEnum)
static bool supportsQualifiedEnums(const QVersionNumber &qtVersion)
QVariant domPropertyToVariant(QAbstractFormBuilder *afb, const QMetaObject *meta, const DomProperty *p)
QVariant domPropertyToVariant(const DomProperty *p)
static QString enumValue(QMetaEnum metaEnum, int v, const QVersionNumber &qtVersion)