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