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 | |
67 | QT_BEGIN_NAMESPACE |
68 | |
69 | #ifdef QFORMINTERNAL_NAMESPACE |
70 | namespace QFormInternal |
71 | { |
72 | #endif |
73 | |
74 | static 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 |
83 | QVariant 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 |
160 | QVariant 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 |
339 | static 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 | } |
595 | static 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 | |
602 | static 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 | |
611 | static 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(). |
623 | DomProperty *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 | |
693 | QT_END_NAMESPACE |
694 | |