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