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 tools applications 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 "cppwriteinitialization.h"
43 #include "cppwriteiconinitialization.h"
44 #include "driver.h"
45 #include "ui4.h"
46 #include "utils.h"
47 #include "uic.h"
48 #include "databaseinfo.h"
49 #include "globaldefs.h"
50
51 #include <QtCore/QTextStream>
52 #include <QtCore/QDebug>
53
54 #include <ctype.h>
55
56 QT_BEGIN_NAMESPACE
57
58 namespace {
59 // Fixup an enumeration name from class Qt.
60 // They are currently stored as "BottomToolBarArea" instead of "Qt::BottomToolBarArea".
61 // due to MO issues. This might be fixed in the future.
fixQtEnumerationName(QString & name)62 void fixQtEnumerationName(QString& name) {
63 static const QLatin1String prefix("Qt::");
64 if (name.indexOf(prefix) != 0)
65 name.prepend(prefix);
66 }
67 // figure out the toolbar area of a DOM attrib list.
68 // By legacy, it is stored as an integer. As of 4.3.0, it is the enumeration value.
toolBarAreaStringFromDOMAttributes(const CPP::WriteInitialization::DomPropertyMap & attributes)69 QString toolBarAreaStringFromDOMAttributes(const CPP::WriteInitialization::DomPropertyMap &attributes) {
70 const DomProperty *pstyle = attributes.value(QLatin1String("toolBarArea"));
71 if (!pstyle)
72 return QString();
73
74 switch (pstyle->kind()) {
75 case DomProperty::Number: {
76 QString area = QLatin1String("static_cast<Qt::ToolBarArea>(");
77 area += QString::number(pstyle->elementNumber());
78 area += QLatin1String("), ");
79 return area;
80 }
81 case DomProperty::Enum: {
82 QString area = pstyle->elementEnum();
83 fixQtEnumerationName(area);
84 area += QLatin1String(", ");
85 return area;
86 }
87 default:
88 break;
89 }
90 return QString();
91 }
92
93 // Write a statement to create a spacer item.
writeSpacerItem(const DomSpacer * node,QTextStream & output)94 void writeSpacerItem(const DomSpacer *node, QTextStream &output) {
95 const QHash<QString, DomProperty *> properties = propertyMap(node->elementProperty());
96 output << "new QSpacerItem(";
97
98 if (properties.contains(QLatin1String("sizeHint"))) {
99 const DomSize *sizeHint = properties.value(QLatin1String("sizeHint"))->elementSize();
100 output << sizeHint->elementWidth() << ", " << sizeHint->elementHeight() << ", ";
101 }
102
103 // size type
104 QString sizeType = properties.contains(QLatin1String("sizeType")) ?
105 properties.value(QLatin1String("sizeType"))->elementEnum() :
106 QString::fromLatin1("Expanding");
107
108 if (!sizeType.startsWith(QLatin1String("QSizePolicy::")))
109 sizeType.prepend(QLatin1String("QSizePolicy::"));
110 // orientation
111 bool isVspacer = false;
112 if (properties.contains(QLatin1String("orientation"))) {
113 const QString orientation = properties.value(QLatin1String("orientation"))->elementEnum();
114 if (orientation == QLatin1String("Qt::Vertical") || orientation == QLatin1String("Vertical")) isVspacer = true;
115 }
116
117 if (isVspacer)
118 output << "QSizePolicy::Minimum, " << sizeType << ')';
119 else
120 output << sizeType << ", QSizePolicy::Minimum)";
121 }
122
123
124 // Helper for implementing comparison functions for integers.
compareInt(int i1,int i2)125 int compareInt(int i1, int i2) {
126 if (i1 < i2) return -1;
127 if (i1 > i2) return 1;
128 return 0;
129 }
130
131 // Write object->setFoo(x);
132 template <class Value>
writeSetter(const QString & indent,const QString & varName,const QString & setter,Value v,QTextStream & str)133 void writeSetter(const QString &indent, const QString &varName,const QString &setter, Value v, QTextStream &str) {
134 str << indent << varName << "->" << setter << '(' << v << ");\n";
135 }
136
writeSetupUIScriptVariableDeclarations(const QString & indent,QTextStream & str)137 void writeSetupUIScriptVariableDeclarations(const QString &indent, QTextStream &str) {
138 str << indent << "ScriptContext scriptContext;\n"
139 << indent << "QWidgetList childWidgets;\n";
140 }
141
iconHasStatePixmaps(const DomResourceIcon * i)142 static inline bool iconHasStatePixmaps(const DomResourceIcon *i) {
143 return i->hasElementNormalOff() || i->hasElementNormalOn() ||
144 i->hasElementDisabledOff() || i->hasElementDisabledOn() ||
145 i->hasElementActiveOff() || i->hasElementActiveOn() ||
146 i->hasElementSelectedOff() || i->hasElementSelectedOn();
147 }
148
isIconFormat44(const DomResourceIcon * i)149 static inline bool isIconFormat44(const DomResourceIcon *i) {
150 return iconHasStatePixmaps(i) || !i->attributeTheme().isEmpty();
151 }
152
153 // Check on properties. Filter out empty legacy pixmap/icon properties
154 // as Designer pre 4.4 used to remove missing resource references.
155 // This can no longer be handled by the code as we have 'setIcon(QIcon())' as well as 'QIcon icon'
checkProperty(const QString & fileName,const DomProperty * p)156 static bool checkProperty(const QString &fileName, const DomProperty *p) {
157 switch (p->kind()) {
158 case DomProperty::IconSet:
159 if (const DomResourceIcon *dri = p->elementIconSet()) {
160 if (!isIconFormat44(dri)) {
161 if (dri->text().isEmpty()) {
162 const QString msg = QString::fromUtf8("%1: Warning: An invalid icon property '%2' was encountered.").arg(fileName).arg(p->attributeName());
163 qWarning("%s", qPrintable(msg));
164 return false;
165 }
166 }
167 }
168 break;
169 case DomProperty::Pixmap:
170 if (const DomResourcePixmap *drp = p->elementPixmap())
171 if (drp->text().isEmpty()) {
172 const QString msg = QString::fromUtf8("%1: Warning: An invalid pixmap property '%2' was encountered.").arg(fileName).arg(p->attributeName());
173 qWarning("%s", qPrintable(msg));
174 return false;
175 }
176 break;
177 default:
178 break;
179 }
180 return true;
181 }
182
openIfndef(QTextStream & str,const QString & symbol)183 inline void openIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#ifndef ") << symbol << endl; }
closeIfndef(QTextStream & str,const QString & symbol)184 inline void closeIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#endif // ") << symbol << endl; }
185
186 const char *accessibilityDefineC = "QT_NO_ACCESSIBILITY";
187 const char *toolTipDefineC = "QT_NO_TOOLTIP";
188 const char *whatsThisDefineC = "QT_NO_WHATSTHIS";
189 const char *statusTipDefineC = "QT_NO_STATUSTIP";
190 const char *shortcutDefineC = "QT_NO_SHORTCUT";
191 }
192
193 namespace CPP {
194
FontHandle(const DomFont * domFont)195 FontHandle::FontHandle(const DomFont *domFont) :
196 m_domFont(domFont)
197 {
198 }
199
compare(const FontHandle & rhs) const200 int FontHandle::compare(const FontHandle &rhs) const
201 {
202 const QString family = m_domFont->hasElementFamily() ? m_domFont->elementFamily() : QString();
203 const QString rhsFamily = rhs.m_domFont->hasElementFamily() ? rhs.m_domFont->elementFamily() : QString();
204
205 if (const int frc = family.compare(rhsFamily))
206 return frc;
207
208 const int pointSize = m_domFont->hasElementPointSize() ? m_domFont->elementPointSize() : -1;
209 const int rhsPointSize = rhs.m_domFont->hasElementPointSize() ? rhs.m_domFont->elementPointSize() : -1;
210
211 if (const int crc = compareInt(pointSize, rhsPointSize))
212 return crc;
213
214 const int bold = m_domFont->hasElementBold() ? (m_domFont->elementBold() ? 1 : 0) : -1;
215 const int rhsBold = rhs.m_domFont->hasElementBold() ? (rhs.m_domFont->elementBold() ? 1 : 0) : -1;
216 if (const int crc = compareInt(bold, rhsBold))
217 return crc;
218
219 const int italic = m_domFont->hasElementItalic() ? (m_domFont->elementItalic() ? 1 : 0) : -1;
220 const int rhsItalic = rhs.m_domFont->hasElementItalic() ? (rhs.m_domFont->elementItalic() ? 1 : 0) : -1;
221 if (const int crc = compareInt(italic, rhsItalic))
222 return crc;
223
224 const int underline = m_domFont->hasElementUnderline() ? (m_domFont->elementUnderline() ? 1 : 0) : -1;
225 const int rhsUnderline = rhs.m_domFont->hasElementUnderline() ? (rhs.m_domFont->elementUnderline() ? 1 : 0) : -1;
226 if (const int crc = compareInt(underline, rhsUnderline))
227 return crc;
228
229 const int weight = m_domFont->hasElementWeight() ? m_domFont->elementWeight() : -1;
230 const int rhsWeight = rhs.m_domFont->hasElementWeight() ? rhs.m_domFont->elementWeight() : -1;
231 if (const int crc = compareInt(weight, rhsWeight))
232 return crc;
233
234 const int strikeOut = m_domFont->hasElementStrikeOut() ? (m_domFont->elementStrikeOut() ? 1 : 0) : -1;
235 const int rhsStrikeOut = rhs.m_domFont->hasElementStrikeOut() ? (rhs.m_domFont->elementStrikeOut() ? 1 : 0) : -1;
236 if (const int crc = compareInt(strikeOut, rhsStrikeOut))
237 return crc;
238
239 const int kerning = m_domFont->hasElementKerning() ? (m_domFont->elementKerning() ? 1 : 0) : -1;
240 const int rhsKerning = rhs.m_domFont->hasElementKerning() ? (rhs.m_domFont->elementKerning() ? 1 : 0) : -1;
241 if (const int crc = compareInt(kerning, rhsKerning))
242 return crc;
243
244 const int antialiasing = m_domFont->hasElementAntialiasing() ? (m_domFont->elementAntialiasing() ? 1 : 0) : -1;
245 const int rhsAntialiasing = rhs.m_domFont->hasElementAntialiasing() ? (rhs.m_domFont->elementAntialiasing() ? 1 : 0) : -1;
246 if (const int crc = compareInt(antialiasing, rhsAntialiasing))
247 return crc;
248
249 const QString styleStrategy = m_domFont->hasElementStyleStrategy() ? m_domFont->elementStyleStrategy() : QString();
250 const QString rhsStyleStrategy = rhs.m_domFont->hasElementStyleStrategy() ? rhs.m_domFont->elementStyleStrategy() : QString();
251
252 if (const int src = styleStrategy.compare(rhsStyleStrategy))
253 return src;
254
255 return 0;
256 }
257
IconHandle(const DomResourceIcon * domIcon)258 IconHandle::IconHandle(const DomResourceIcon *domIcon) :
259 m_domIcon(domIcon)
260 {
261 }
262
compare(const IconHandle & rhs) const263 int IconHandle::compare(const IconHandle &rhs) const
264 {
265 if (const int comp = m_domIcon->attributeTheme().compare(rhs.m_domIcon->attributeTheme()))
266 return comp;
267
268 const QString normalOff = m_domIcon->hasElementNormalOff() ? m_domIcon->elementNormalOff()->text() : QString();
269 const QString rhsNormalOff = rhs.m_domIcon->hasElementNormalOff() ? rhs.m_domIcon->elementNormalOff()->text() : QString();
270 if (const int comp = normalOff.compare(rhsNormalOff))
271 return comp;
272
273 const QString normalOn = m_domIcon->hasElementNormalOn() ? m_domIcon->elementNormalOn()->text() : QString();
274 const QString rhsNormalOn = rhs.m_domIcon->hasElementNormalOn() ? rhs.m_domIcon->elementNormalOn()->text() : QString();
275 if (const int comp = normalOn.compare(rhsNormalOn))
276 return comp;
277
278 const QString disabledOff = m_domIcon->hasElementDisabledOff() ? m_domIcon->elementDisabledOff()->text() : QString();
279 const QString rhsDisabledOff = rhs.m_domIcon->hasElementDisabledOff() ? rhs.m_domIcon->elementDisabledOff()->text() : QString();
280 if (const int comp = disabledOff.compare(rhsDisabledOff))
281 return comp;
282
283 const QString disabledOn = m_domIcon->hasElementDisabledOn() ? m_domIcon->elementDisabledOn()->text() : QString();
284 const QString rhsDisabledOn = rhs.m_domIcon->hasElementDisabledOn() ? rhs.m_domIcon->elementDisabledOn()->text() : QString();
285 if (const int comp = disabledOn.compare(rhsDisabledOn))
286 return comp;
287
288 const QString activeOff = m_domIcon->hasElementActiveOff() ? m_domIcon->elementActiveOff()->text() : QString();
289 const QString rhsActiveOff = rhs.m_domIcon->hasElementActiveOff() ? rhs.m_domIcon->elementActiveOff()->text() : QString();
290 if (const int comp = activeOff.compare(rhsActiveOff))
291 return comp;
292
293 const QString activeOn = m_domIcon->hasElementActiveOn() ? m_domIcon->elementActiveOn()->text() : QString();
294 const QString rhsActiveOn = rhs.m_domIcon->hasElementActiveOn() ? rhs.m_domIcon->elementActiveOn()->text() : QString();
295 if (const int comp = activeOn.compare(rhsActiveOn))
296 return comp;
297
298 const QString selectedOff = m_domIcon->hasElementSelectedOff() ? m_domIcon->elementSelectedOff()->text() : QString();
299 const QString rhsSelectedOff = rhs.m_domIcon->hasElementSelectedOff() ? rhs.m_domIcon->elementSelectedOff()->text() : QString();
300 if (const int comp = selectedOff.compare(rhsSelectedOff))
301 return comp;
302
303 const QString selectedOn = m_domIcon->hasElementSelectedOn() ? m_domIcon->elementSelectedOn()->text() : QString();
304 const QString rhsSelectedOn = rhs.m_domIcon->hasElementSelectedOn() ? rhs.m_domIcon->elementSelectedOn()->text() : QString();
305 if (const int comp = selectedOn.compare(rhsSelectedOn))
306 return comp;
307 // Pre 4.4 Legacy
308 if (const int comp = m_domIcon->text().compare(rhs.m_domIcon->text()))
309 return comp;
310
311 return 0;
312 }
313
314
315 #if defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
qHash(const SizePolicyHandle & handle)316 inline uint qHash(const SizePolicyHandle &handle) { return qHash(handle.m_domSizePolicy); }
qHash(const FontHandle & handle)317 inline uint qHash(const FontHandle &handle) { return qHash(handle.m_domFont); }
qHash(const IconHandle & handle)318 inline uint qHash(const IconHandle &handle) { return qHash(handle.m_domIcon); }
319 #endif
320
SizePolicyHandle(const DomSizePolicy * domSizePolicy)321 SizePolicyHandle::SizePolicyHandle(const DomSizePolicy *domSizePolicy) :
322 m_domSizePolicy(domSizePolicy)
323 {
324 }
325
compare(const SizePolicyHandle & rhs) const326 int SizePolicyHandle::compare(const SizePolicyHandle &rhs) const
327 {
328
329 const int hSizeType = m_domSizePolicy->hasElementHSizeType() ? m_domSizePolicy->elementHSizeType() : -1;
330 const int rhsHSizeType = rhs.m_domSizePolicy->hasElementHSizeType() ? rhs.m_domSizePolicy->elementHSizeType() : -1;
331 if (const int crc = compareInt(hSizeType, rhsHSizeType))
332 return crc;
333
334 const int vSizeType = m_domSizePolicy->hasElementVSizeType() ? m_domSizePolicy->elementVSizeType() : -1;
335 const int rhsVSizeType = rhs.m_domSizePolicy->hasElementVSizeType() ? rhs.m_domSizePolicy->elementVSizeType() : -1;
336 if (const int crc = compareInt(vSizeType, rhsVSizeType))
337 return crc;
338
339 const int hStretch = m_domSizePolicy->hasElementHorStretch() ? m_domSizePolicy->elementHorStretch() : -1;
340 const int rhsHStretch = rhs.m_domSizePolicy->hasElementHorStretch() ? rhs.m_domSizePolicy->elementHorStretch() : -1;
341 if (const int crc = compareInt(hStretch, rhsHStretch))
342 return crc;
343
344 const int vStretch = m_domSizePolicy->hasElementVerStretch() ? m_domSizePolicy->elementVerStretch() : -1;
345 const int rhsVStretch = rhs.m_domSizePolicy->hasElementVerStretch() ? rhs.m_domSizePolicy->elementVerStretch() : -1;
346 if (const int crc = compareInt(vStretch, rhsVStretch))
347 return crc;
348
349 const QString attributeHSizeType = m_domSizePolicy->hasAttributeHSizeType() ? m_domSizePolicy->attributeHSizeType() : QString();
350 const QString rhsAttributeHSizeType = rhs.m_domSizePolicy->hasAttributeHSizeType() ? rhs.m_domSizePolicy->attributeHSizeType() : QString();
351
352 if (const int hrc = attributeHSizeType.compare(rhsAttributeHSizeType))
353 return hrc;
354
355 const QString attributeVSizeType = m_domSizePolicy->hasAttributeVSizeType() ? m_domSizePolicy->attributeVSizeType() : QString();
356 const QString rhsAttributeVSizeType = rhs.m_domSizePolicy->hasAttributeVSizeType() ? rhs.m_domSizePolicy->attributeVSizeType() : QString();
357
358 return attributeVSizeType.compare(rhsAttributeVSizeType);
359 }
360
361 // --- WriteInitialization: LayoutDefaultHandler
362
LayoutDefaultHandler()363 WriteInitialization::LayoutDefaultHandler::LayoutDefaultHandler()
364 {
365 qFill(m_state, m_state + NumProperties, 0u);
366 qFill(m_defaultValues, m_defaultValues + NumProperties, 0);
367 }
368
369
370
acceptLayoutDefault(DomLayoutDefault * node)371 void WriteInitialization::LayoutDefaultHandler::acceptLayoutDefault(DomLayoutDefault *node)
372 {
373 if (!node)
374 return;
375 if (node->hasAttributeMargin()) {
376 m_state[Margin] |= HasDefaultValue;
377 m_defaultValues[Margin] = node->attributeMargin();
378 }
379 if (node->hasAttributeSpacing()) {
380 m_state[Spacing] |= HasDefaultValue;
381 m_defaultValues[Spacing] = node->attributeSpacing();
382 }
383 }
384
acceptLayoutFunction(DomLayoutFunction * node)385 void WriteInitialization::LayoutDefaultHandler::acceptLayoutFunction(DomLayoutFunction *node)
386 {
387 if (!node)
388 return;
389 if (node->hasAttributeMargin()) {
390 m_state[Margin] |= HasDefaultFunction;
391 m_functions[Margin] = node->attributeMargin();
392 m_functions[Margin] += QLatin1String("()");
393 }
394 if (node->hasAttributeSpacing()) {
395 m_state[Spacing] |= HasDefaultFunction;
396 m_functions[Spacing] = node->attributeSpacing();
397 m_functions[Spacing] += QLatin1String("()");
398 }
399 }
400
writeContentsMargins(const QString & indent,const QString & objectName,int value,QTextStream & str)401 static inline void writeContentsMargins(const QString &indent, const QString &objectName, int value, QTextStream &str)
402 {
403 QString contentsMargins;
404 QTextStream(&contentsMargins) << value << ", " << value << ", " << value << ", " << value;
405 writeSetter(indent, objectName, QLatin1String("setContentsMargins"), contentsMargins, str);
406 }
407
writeProperty(int p,const QString & indent,const QString & objectName,const DomPropertyMap & properties,const QString & propertyName,const QString & setter,int defaultStyleValue,bool suppressDefault,QTextStream & str) const408 void WriteInitialization::LayoutDefaultHandler::writeProperty(int p, const QString &indent, const QString &objectName,
409 const DomPropertyMap &properties, const QString &propertyName, const QString &setter,
410 int defaultStyleValue, bool suppressDefault, QTextStream &str) const
411 {
412 // User value
413 const DomPropertyMap::const_iterator mit = properties.constFind(propertyName);
414 const bool found = mit != properties.constEnd();
415 if (found) {
416 const int value = mit.value()->elementNumber();
417 // Emulate the pre 4.3 behaviour: The value form default value was only used to determine
418 // the default value, layout properties were always written
419 const bool useLayoutFunctionPre43 = !suppressDefault && (m_state[p] == (HasDefaultFunction|HasDefaultValue)) && value == m_defaultValues[p];
420 if (!useLayoutFunctionPre43) {
421 bool ifndefMac = (!(m_state[p] & (HasDefaultFunction|HasDefaultValue))
422 && value == defaultStyleValue);
423 if (ifndefMac)
424 str << "#ifndef Q_OS_MAC\n";
425 if (p == Margin) { // Use setContentsMargins for numeric values
426 writeContentsMargins(indent, objectName, value, str);
427 } else {
428 writeSetter(indent, objectName, setter, value, str);
429 }
430 if (ifndefMac)
431 str << "#endif\n";
432 return;
433 }
434 }
435 if (suppressDefault)
436 return;
437 // get default.
438 if (m_state[p] & HasDefaultFunction) {
439 // Do not use setContentsMargins to avoid repetitive evaluations.
440 writeSetter(indent, objectName, setter, m_functions[p], str);
441 return;
442 }
443 if (m_state[p] & HasDefaultValue) {
444 if (p == Margin) { // Use setContentsMargins for numeric values
445 writeContentsMargins(indent, objectName, m_defaultValues[p], str);
446 } else {
447 writeSetter(indent, objectName, setter, m_defaultValues[p], str);
448 }
449 }
450 return;
451 }
452
453
writeProperties(const QString & indent,const QString & varName,const DomPropertyMap & properties,int marginType,bool suppressMarginDefault,QTextStream & str) const454 void WriteInitialization::LayoutDefaultHandler::writeProperties(const QString &indent, const QString &varName,
455 const DomPropertyMap &properties, int marginType,
456 bool suppressMarginDefault,
457 QTextStream &str) const {
458 // Write out properties and ignore the ones found in
459 // subsequent writing of the property list.
460 int defaultSpacing = marginType == WriteInitialization::Use43UiFile ? -1 : 6;
461 writeProperty(Spacing, indent, varName, properties, QLatin1String("spacing"), QLatin1String("setSpacing"),
462 defaultSpacing, false, str);
463 // We use 9 as TopLevelMargin, since Designer seem to always use 9.
464 static const int layoutmargins[4] = {-1, 9, 9, 0};
465 writeProperty(Margin, indent, varName, properties, QLatin1String("margin"), QLatin1String("setMargin"),
466 layoutmargins[marginType], suppressMarginDefault, str);
467 }
468
needsTranslation(DomString * str)469 static bool needsTranslation(DomString *str)
470 {
471 if (!str)
472 return false;
473 return !str->hasAttributeNotr() || !toBool(str->attributeNotr());
474 }
475
476 // --- WriteInitialization
WriteInitialization(Uic * uic,bool activateScripts)477 WriteInitialization::WriteInitialization(Uic *uic, bool activateScripts) :
478 m_uic(uic),
479 m_driver(uic->driver()), m_output(uic->output()), m_option(uic->option()),
480 m_indent(m_option.indent + m_option.indent),
481 m_dindent(m_indent + m_option.indent),
482 m_stdsetdef(true),
483 m_layoutMarginType(TopLevelMargin),
484 m_mainFormUsedInRetranslateUi(false),
485 m_delayedOut(&m_delayedInitialization, QIODevice::WriteOnly),
486 m_refreshOut(&m_refreshInitialization, QIODevice::WriteOnly),
487 m_actionOut(&m_delayedActionInitialization, QIODevice::WriteOnly),
488 m_activateScripts(activateScripts), m_layoutWidget(false),
489 m_firstThemeIcon(true)
490 {
491 }
492
acceptUI(DomUI * node)493 void WriteInitialization::acceptUI(DomUI *node)
494 {
495 m_registeredImages.clear();
496 m_actionGroupChain.push(0);
497 m_widgetChain.push(0);
498 m_layoutChain.push(0);
499
500 acceptLayoutDefault(node->elementLayoutDefault());
501 acceptLayoutFunction(node->elementLayoutFunction());
502
503 if (node->elementCustomWidgets())
504 TreeWalker::acceptCustomWidgets(node->elementCustomWidgets());
505
506 if (node->elementImages())
507 TreeWalker::acceptImages(node->elementImages());
508
509 if (m_option.generateImplemetation)
510 m_output << "#include <" << m_driver->headerFileName() << ">\n\n";
511
512 m_stdsetdef = true;
513 if (node->hasAttributeStdSetDef())
514 m_stdsetdef = node->attributeStdSetDef();
515
516 const QString className = node->elementClass() + m_option.postfix;
517 m_generatedClass = className;
518
519 const QString varName = m_driver->findOrInsertWidget(node->elementWidget());
520 m_mainFormVarName = varName;
521 m_registeredWidgets.insert(varName, node->elementWidget()); // register the main widget
522
523 const QString widgetClassName = node->elementWidget()->attributeClass();
524
525 m_output << m_option.indent << "void " << "setupUi(" << widgetClassName << " *" << varName << ")\n"
526 << m_option.indent << "{\n";
527
528 if (m_activateScripts)
529 writeSetupUIScriptVariableDeclarations(m_indent, m_output);
530
531 const QStringList connections = m_uic->databaseInfo()->connections();
532 for (int i=0; i<connections.size(); ++i) {
533 QString connection = connections.at(i);
534
535 if (connection == QLatin1String("(default)"))
536 continue;
537
538 const QString varConn = connection + QLatin1String("Connection");
539 m_output << m_indent << varConn << " = QSqlDatabase::database(" << fixString(connection, m_dindent) << ");\n";
540 }
541
542 acceptWidget(node->elementWidget());
543
544 if (m_buddies.size() > 0)
545 openIfndef(m_output, QLatin1String(shortcutDefineC));
546 for (int i=0; i<m_buddies.size(); ++i) {
547 const Buddy &b = m_buddies.at(i);
548
549 if (!m_registeredWidgets.contains(b.objName)) {
550 fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
551 qPrintable(m_option.messagePrefix()),
552 b.objName.toLatin1().data());
553 continue;
554 } else if (!m_registeredWidgets.contains(b.buddy)) {
555 fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
556 qPrintable(m_option.messagePrefix()),
557 b.buddy.toLatin1().data());
558 continue;
559 }
560
561 m_output << m_indent << b.objName << "->setBuddy(" << b.buddy << ");\n";
562 }
563 if (m_buddies.size() > 0)
564 closeIfndef(m_output, QLatin1String(shortcutDefineC));
565
566 if (node->elementTabStops())
567 acceptTabStops(node->elementTabStops());
568
569 if (m_delayedActionInitialization.size())
570 m_output << "\n" << m_delayedActionInitialization;
571
572 m_output << "\n" << m_indent << "retranslateUi(" << varName << ");\n";
573
574 if (node->elementConnections())
575 acceptConnections(node->elementConnections());
576
577 if (!m_delayedInitialization.isEmpty())
578 m_output << "\n" << m_delayedInitialization << "\n";
579
580 if (m_option.autoConnection)
581 m_output << "\n" << m_indent << "QMetaObject::connectSlotsByName(" << varName << ");\n";
582
583 m_output << m_option.indent << "} // setupUi\n\n";
584
585 if (!m_mainFormUsedInRetranslateUi) {
586 m_refreshInitialization += m_indent;
587 m_refreshInitialization += QLatin1String("Q_UNUSED(");
588 m_refreshInitialization += varName ;
589 m_refreshInitialization += QLatin1String(");\n");
590 }
591
592 m_output << m_option.indent << "void " << "retranslateUi(" << widgetClassName << " *" << varName << ")\n"
593 << m_option.indent << "{\n"
594 << m_refreshInitialization
595 << m_option.indent << "} // retranslateUi\n\n";
596
597 m_layoutChain.pop();
598 m_widgetChain.pop();
599 m_actionGroupChain.pop();
600 }
601
addWizardPage(const QString & pageVarName,const DomWidget * page,const QString & parentWidget)602 void WriteInitialization::addWizardPage(const QString &pageVarName, const DomWidget *page, const QString &parentWidget)
603 {
604 /* If the node has a (free-format) string "pageId" attribute (which could
605 * an integer or an enumeration value), use setPage(), else addPage(). */
606 QString id;
607 const DomPropertyList attributes = page->elementAttribute();
608 if (!attributes.empty()) {
609 const DomPropertyList::const_iterator acend = attributes.constEnd();
610 for (DomPropertyList::const_iterator it = attributes.constBegin(); it != acend; ++it)
611 if ((*it)->attributeName() == QLatin1String("pageId")) {
612 if (const DomString *ds = (*it)->elementString())
613 id = ds->text();
614 break;
615 }
616 }
617 if (id.isEmpty()) {
618 m_output << m_indent << parentWidget << "->addPage(" << pageVarName << ");\n";
619 } else {
620 m_output << m_indent << parentWidget << "->setPage(" << id << ", " << pageVarName << ");\n";
621 }
622 }
623
acceptWidget(DomWidget * node)624 void WriteInitialization::acceptWidget(DomWidget *node)
625 {
626 m_layoutMarginType = m_widgetChain.count() == 1 ? TopLevelMargin : ChildMargin;
627 const QString className = node->attributeClass();
628 const QString varName = m_driver->findOrInsertWidget(node);
629 m_registeredWidgets.insert(varName, node); // register the current widget
630
631 QString parentWidget, parentClass;
632 if (m_widgetChain.top()) {
633 parentWidget = m_driver->findOrInsertWidget(m_widgetChain.top());
634 parentClass = m_widgetChain.top()->attributeClass();
635 }
636
637 const QString savedParentWidget = parentWidget;
638
639 if (m_uic->isContainer(parentClass) || m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3ToolBar")))
640 parentWidget.clear();
641
642 if (m_widgetChain.size() != 1)
643 m_output << m_indent << varName << " = new " << m_uic->customWidgetsInfo()->realClassName(className) << '(' << parentWidget << ");\n";
644
645 parentWidget = savedParentWidget;
646
647 if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ComboBox"))) {
648 initializeComboBox3(node);
649 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))) {
650 initializeComboBox(node);
651 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
652 initializeListWidget(node);
653 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) {
654 initializeTreeWidget(node);
655 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) {
656 initializeTableWidget(node);
657 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ListBox"))) {
658 initializeQ3ListBox(node);
659 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ListView"))) {
660 initializeQ3ListView(node);
661 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3IconView"))) {
662 initializeQ3IconView(node);
663 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3Table"))) {
664 initializeQ3Table(node);
665 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DataTable"))) {
666 initializeQ3SqlDataTable(node);
667 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DataBrowser"))) {
668 initializeQ3SqlDataBrowser(node);
669 }
670
671 if (m_uic->isButton(className))
672 addButtonGroup(node, varName);
673
674 writeProperties(varName, className, node->elementProperty());
675
676 if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenu")) && parentWidget.size()) {
677 initializeMenu(node, parentWidget);
678 }
679
680 if (node->elementLayout().isEmpty())
681 m_layoutChain.push(0);
682
683 m_layoutWidget = false;
684 if (className == QLatin1String("QWidget") && !node->hasAttributeNative()) {
685 if (const DomWidget* parentWidget = m_widgetChain.top()) {
686 const QString parentClass = parentWidget->attributeClass();
687 if (parentClass != QLatin1String("QMainWindow")
688 && !m_uic->isCustomWidgetContainer(parentClass)
689 && !m_uic->isContainer(parentClass))
690 m_layoutWidget = true;
691 }
692 }
693 m_widgetChain.push(node);
694 m_layoutChain.push(0);
695 TreeWalker::acceptWidget(node);
696 m_layoutChain.pop();
697 m_widgetChain.pop();
698 m_layoutWidget = false;
699
700 const DomPropertyMap attributes = propertyMap(node->elementAttribute());
701
702 const QString pageDefaultString = QLatin1String("Page");
703
704 int id = -1;
705 if (const DomProperty *pid = attributes.value(QLatin1String("id"))) {
706 id = pid->elementNumber();
707 }
708
709 if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMainWindow"))
710 || m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3MainWindow"))) {
711
712 if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenuBar"))) {
713 if (!m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3MainWindow")))
714 m_output << m_indent << parentWidget << "->setMenuBar(" << varName <<");\n";
715 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBar"))) {
716 m_output << m_indent << parentWidget << "->addToolBar("
717 << toolBarAreaStringFromDOMAttributes(attributes) << varName << ");\n";
718
719 if (const DomProperty *pbreak = attributes.value(QLatin1String("toolBarBreak"))) {
720 if (pbreak->elementBool() == QLatin1String("true")) {
721 m_output << m_indent << parentWidget << "->insertToolBarBreak(" << varName << ");\n";
722 }
723 }
724
725 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"))) {
726 QString area;
727 if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) {
728 area += QLatin1String("static_cast<Qt::DockWidgetArea>(");
729 area += QString::number(pstyle->elementNumber());
730 area += QLatin1String("), ");
731 }
732
733 m_output << m_indent << parentWidget << "->addDockWidget(" << area << varName << ");\n";
734 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) {
735 m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n";
736 } else if (!m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DockWindow"))
737 && !m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ToolBar"))) {
738 m_output << m_indent << parentWidget << "->setCentralWidget(" << varName << ");\n";
739 }
740 }
741
742 // Check for addPageMethod of a custom plugin first
743 const QString addPageMethod = m_uic->customWidgetsInfo()->customWidgetAddPageMethod(parentClass);
744 if (!addPageMethod.isEmpty()) {
745 m_output << m_indent << parentWidget << "->" << addPageMethod << '(' << varName << ");\n";
746 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QStackedWidget"))) {
747 m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
748 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBar"))) {
749 m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
750 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3WidgetStack"))) {
751 m_output << m_indent << parentWidget << "->addWidget(" << varName << ", " << id << ");\n";
752 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QDockWidget"))) {
753 m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n";
754 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QScrollArea"))) {
755 m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n";
756 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QSplitter"))) {
757 m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
758 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMdiArea"))) {
759 m_output << m_indent << parentWidget << "->addSubWindow(" << varName << ");\n";
760 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWorkspace"))) {
761 m_output << m_indent << parentWidget << "->addWindow(" << varName << ");\n";
762 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWizard"))) {
763 addWizardPage(varName, node, parentWidget);
764 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBox"))) {
765 QString icon;
766 if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) {
767 icon += QLatin1String(", ") ;
768 icon += iconCall(picon);
769 }
770
771 const DomProperty *plabel = attributes.value(QLatin1String("label"));
772 DomString *plabelString = plabel ? plabel->elementString() : 0;
773
774 m_output << m_indent << parentWidget << "->addItem(" << varName << icon << ", " << noTrCall(plabelString, pageDefaultString) << ");\n";
775
776 autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget << "->setItemText("
777 << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(plabelString, pageDefaultString) << ");\n";
778
779 #ifndef QT_NO_TOOLTIP
780 if (DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
781 autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setItemToolTip("
782 << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n";
783 }
784 #endif // QT_NO_TOOLTIP
785 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QTabWidget"))) {
786 QString icon;
787 if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) {
788 icon += QLatin1String(", ");
789 icon += iconCall(picon);
790 }
791
792 const DomProperty *ptitle = attributes.value(QLatin1String("title"));
793 DomString *ptitleString = ptitle ? ptitle->elementString() : 0;
794
795 m_output << m_indent << parentWidget << "->addTab(" << varName << icon << ", " << "QString());\n";
796
797 autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTabText("
798 << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptitleString, pageDefaultString) << ");\n";
799
800 #ifndef QT_NO_TOOLTIP
801 if (const DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
802 autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setTabToolTip("
803 << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n";
804 }
805 #endif // QT_NO_TOOLTIP
806 #ifndef QT_NO_WHATSTHIS
807 if (const DomProperty *pwhatsThis = attributes.value(QLatin1String("whatsThis"))) {
808 autoTrOutput(pwhatsThis->elementString()) << m_indent << parentWidget << "->setTabWhatsThis("
809 << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(pwhatsThis->elementString()) << ");\n";
810 }
811 #endif // QT_NO_WHATSTHIS
812 } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3Wizard"))) {
813 const DomProperty *ptitle = attributes.value(QLatin1String("title"));
814 DomString *ptitleString = ptitle ? ptitle->elementString() : 0;
815
816 m_output << m_indent << parentWidget << "->addPage(" << varName << ", " << noTrCall(ptitleString, pageDefaultString) << ");\n";
817
818 autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTitle("
819 << varName << ", " << autoTrCall(ptitleString, pageDefaultString) << ");\n";
820
821 }
822
823 //
824 // Special handling for qtableview/qtreeview fake header attributes
825 //
826 static QStringList realPropertyNames =
827 (QStringList() << QLatin1String("visible")
828 << QLatin1String("cascadingSectionResizes")
829 << QLatin1String("defaultSectionSize")
830 << QLatin1String("highlightSections")
831 << QLatin1String("minimumSectionSize")
832 << QLatin1String("showSortIndicator")
833 << QLatin1String("stretchLastSection"));
834
835 if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeView"))
836 || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) {
837 DomPropertyList headerProperties;
838 foreach (const QString &realPropertyName, realPropertyNames) {
839 const QString upperPropertyName = realPropertyName.at(0).toUpper()
840 + realPropertyName.mid(1);
841 const QString fakePropertyName = QLatin1String("header") + upperPropertyName;
842 if (DomProperty *fakeProperty = attributes.value(fakePropertyName)) {
843 fakeProperty->setAttributeName(realPropertyName);
844 headerProperties << fakeProperty;
845 }
846 }
847 writeProperties(varName + QLatin1String("->header()"), QLatin1String("QHeaderView"),
848 headerProperties, WritePropertyIgnoreObjectName);
849
850 } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableView"))
851 || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) {
852
853 static QStringList headerPrefixes =
854 (QStringList() << QLatin1String("horizontalHeader")
855 << QLatin1String("verticalHeader"));
856
857 foreach (const QString &headerPrefix, headerPrefixes) {
858 DomPropertyList headerProperties;
859 foreach (const QString &realPropertyName, realPropertyNames) {
860 const QString upperPropertyName = realPropertyName.at(0).toUpper()
861 + realPropertyName.mid(1);
862 const QString fakePropertyName = headerPrefix + upperPropertyName;
863 if (DomProperty *fakeProperty = attributes.value(fakePropertyName)) {
864 fakeProperty->setAttributeName(realPropertyName);
865 headerProperties << fakeProperty;
866 }
867 }
868 writeProperties(varName + QLatin1String("->") + headerPrefix + QLatin1String("()"),
869 QLatin1String("QHeaderView"),
870 headerProperties, WritePropertyIgnoreObjectName);
871 }
872 }
873
874 if (node->elementLayout().isEmpty())
875 m_layoutChain.pop();
876
877 const QStringList zOrder = node->elementZOrder();
878 for (int i = 0; i < zOrder.size(); ++i) {
879 const QString name = zOrder.at(i);
880
881 if (!m_registeredWidgets.contains(name)) {
882 fprintf(stderr, "%s: Warning: Z-order assignment: '%s' is not a valid widget.\n",
883 qPrintable(m_option.messagePrefix()),
884 name.toLatin1().data());
885 continue;
886 }
887
888 if (name.isEmpty()) {
889 continue;
890 }
891
892 m_output << m_indent << name << "->raise();\n";
893 }
894 }
895
addButtonGroup(const DomWidget * buttonNode,const QString & varName)896 void WriteInitialization::addButtonGroup(const DomWidget *buttonNode, const QString &varName)
897 {
898 const DomPropertyMap attributes = propertyMap(buttonNode->elementAttribute());
899 // Look up the button group name as specified in the attribute and find the uniquified name
900 const DomProperty *prop = attributes.value(QLatin1String("buttonGroup"));
901 if (!prop)
902 return;
903 const QString attributeName = toString(prop->elementString());
904 const DomButtonGroup *group = m_driver->findButtonGroup(attributeName);
905 // Legacy feature: Create missing groups on the fly as the UIC button group feature
906 // was present before the actual Designer support (4.5)
907 const bool createGroupOnTheFly = group == 0;
908 if (createGroupOnTheFly) {
909 DomButtonGroup *newGroup = new DomButtonGroup;
910 newGroup->setAttributeName(attributeName);
911 group = newGroup;
912 fprintf(stderr, "%s: Warning: Creating button group `%s'\n",
913 qPrintable(m_option.messagePrefix()),
914 attributeName.toLatin1().data());
915 }
916 const QString groupName = m_driver->findOrInsertButtonGroup(group);
917 // Create on demand
918 if (!m_buttonGroups.contains(groupName)) {
919 const QString className = QLatin1String("QButtonGroup");
920 m_output << m_indent;
921 if (createGroupOnTheFly)
922 m_output << className << " *";
923 m_output << groupName << " = new " << className << '(' << m_mainFormVarName << ");\n";
924 m_buttonGroups.insert(groupName);
925 writeProperties(groupName, className, group->elementProperty());
926 }
927 m_output << m_indent << groupName << "->addButton(" << varName << ");\n";
928 }
929
acceptLayout(DomLayout * node)930 void WriteInitialization::acceptLayout(DomLayout *node)
931 {
932 const QString className = node->attributeClass();
933 const QString varName = m_driver->findOrInsertLayout(node);
934
935 const DomPropertyMap properties = propertyMap(node->elementProperty());
936 const bool oldLayoutProperties = properties.constFind(QLatin1String("margin")) != properties.constEnd();
937
938 bool isGroupBox = false;
939
940 if (m_widgetChain.top()) {
941 const QString parentWidget = m_widgetChain.top()->attributeClass();
942
943 if (!m_layoutChain.top() && (m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3GroupBox"))
944 || m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3ButtonGroup")))) {
945 const QString parent = m_driver->findOrInsertWidget(m_widgetChain.top());
946
947 isGroupBox = true;
948 // special case for group box
949
950 m_output << m_indent << parent << "->setColumnLayout(0, Qt::Vertical);\n";
951 QString objectName = parent;
952 objectName += QLatin1String("->layout()");
953 int marginType = Use43UiFile;
954 if (oldLayoutProperties)
955 marginType = m_layoutMarginType;
956
957 m_LayoutDefaultHandler.writeProperties(m_indent,
958 objectName, properties, marginType, false, m_output);
959 }
960 }
961
962 m_output << m_indent << varName << " = new " << className << '(';
963
964 if (!m_layoutChain.top() && !isGroupBox)
965 m_output << m_driver->findOrInsertWidget(m_widgetChain.top());
966
967 m_output << ");\n";
968
969 if (isGroupBox) {
970 const QString tempName = m_driver->unique(QLatin1String("boxlayout"));
971 m_output << m_indent << "QBoxLayout *" << tempName << " = qobject_cast<QBoxLayout *>(" <<
972 m_driver->findOrInsertWidget(m_widgetChain.top()) << "->layout());\n";
973 m_output << m_indent << "if (" << tempName << ")\n";
974 m_output << m_dindent << tempName << "->addLayout(" << varName << ");\n";
975 }
976
977 if (isGroupBox) {
978 m_output << m_indent << varName << "->setAlignment(Qt::AlignTop);\n";
979 } else {
980 // Suppress margin on a read child layout
981 const bool suppressMarginDefault = m_layoutChain.top();
982 int marginType = Use43UiFile;
983 if (oldLayoutProperties)
984 marginType = m_layoutMarginType;
985 m_LayoutDefaultHandler.writeProperties(m_indent, varName, properties, marginType, suppressMarginDefault, m_output);
986 }
987
988 m_layoutMarginType = SubLayoutMargin;
989
990 DomPropertyList propList = node->elementProperty();
991 if (m_layoutWidget) {
992 bool left, top, right, bottom;
993 left = top = right = bottom = false;
994 for (int i = 0; i < propList.size(); ++i) {
995 const DomProperty *p = propList.at(i);
996 const QString propertyName = p->attributeName();
997 if (propertyName == QLatin1String("leftMargin") && p->kind() == DomProperty::Number)
998 left = true;
999 else if (propertyName == QLatin1String("topMargin") && p->kind() == DomProperty::Number)
1000 top = true;
1001 else if (propertyName == QLatin1String("rightMargin") && p->kind() == DomProperty::Number)
1002 right = true;
1003 else if (propertyName == QLatin1String("bottomMargin") && p->kind() == DomProperty::Number)
1004 bottom = true;
1005 }
1006 if (!left) {
1007 DomProperty *p = new DomProperty();
1008 p->setAttributeName(QLatin1String("leftMargin"));
1009 p->setElementNumber(0);
1010 propList.append(p);
1011 }
1012 if (!top) {
1013 DomProperty *p = new DomProperty();
1014 p->setAttributeName(QLatin1String("topMargin"));
1015 p->setElementNumber(0);
1016 propList.append(p);
1017 }
1018 if (!right) {
1019 DomProperty *p = new DomProperty();
1020 p->setAttributeName(QLatin1String("rightMargin"));
1021 p->setElementNumber(0);
1022 propList.append(p);
1023 }
1024 if (!bottom) {
1025 DomProperty *p = new DomProperty();
1026 p->setAttributeName(QLatin1String("bottomMargin"));
1027 p->setElementNumber(0);
1028 propList.append(p);
1029 }
1030 m_layoutWidget = false;
1031 }
1032
1033 writeProperties(varName, className, propList, WritePropertyIgnoreMargin|WritePropertyIgnoreSpacing);
1034
1035 m_layoutChain.push(node);
1036 TreeWalker::acceptLayout(node);
1037 m_layoutChain.pop();
1038
1039 // Stretch? (Unless we are compiling for UIC3)
1040 const QString numberNull = QString(QLatin1Char('0'));
1041 writePropertyList(varName, QLatin1String("setStretch"), node->attributeStretch(), numberNull);
1042 writePropertyList(varName, QLatin1String("setRowStretch"), node->attributeRowStretch(), numberNull);
1043 writePropertyList(varName, QLatin1String("setColumnStretch"), node->attributeColumnStretch(), numberNull);
1044 writePropertyList(varName, QLatin1String("setColumnMinimumWidth"), node->attributeColumnMinimumWidth(), numberNull);
1045 writePropertyList(varName, QLatin1String("setRowMinimumHeight"), node->attributeRowMinimumHeight(), numberNull);
1046 }
1047
1048 // Apply a comma-separated list of values using a function "setSomething(int idx, value)"
writePropertyList(const QString & varName,const QString & setFunction,const QString & value,const QString & defaultValue)1049 void WriteInitialization::writePropertyList(const QString &varName,
1050 const QString &setFunction,
1051 const QString &value,
1052 const QString &defaultValue)
1053 {
1054 if (value.isEmpty())
1055 return;
1056 const QStringList list = value.split(QLatin1Char(','));
1057 const int count = list.count();
1058 for (int i = 0; i < count; i++)
1059 if (list.at(i) != defaultValue)
1060 m_output << m_indent << varName << "->" << setFunction << '(' << i << ", " << list.at(i) << ");\n";
1061 }
1062
acceptSpacer(DomSpacer * node)1063 void WriteInitialization::acceptSpacer(DomSpacer *node)
1064 {
1065 m_output << m_indent << m_driver->findOrInsertSpacer(node) << " = ";
1066 writeSpacerItem(node, m_output);
1067 m_output << ";\n";
1068 }
1069
formLayoutRole(int column,int colspan)1070 static inline QString formLayoutRole(int column, int colspan)
1071 {
1072 if (colspan > 1)
1073 return QLatin1String("QFormLayout::SpanningRole");
1074 return column == 0 ? QLatin1String("QFormLayout::LabelRole") : QLatin1String("QFormLayout::FieldRole");
1075 }
1076
acceptLayoutItem(DomLayoutItem * node)1077 void WriteInitialization::acceptLayoutItem(DomLayoutItem *node)
1078 {
1079 TreeWalker::acceptLayoutItem(node);
1080
1081 DomLayout *layout = m_layoutChain.top();
1082
1083 if (!layout)
1084 return;
1085
1086 const QString layoutName = m_driver->findOrInsertLayout(layout);
1087 const QString itemName = m_driver->findOrInsertLayoutItem(node);
1088
1089 QString addArgs;
1090 QString methodPrefix = QLatin1String("add"); //Consistent API-design galore!
1091 if (layout->attributeClass() == QLatin1String("QGridLayout")) {
1092 const int row = node->attributeRow();
1093 const int col = node->attributeColumn();
1094
1095 const int rowSpan = node->hasAttributeRowSpan() ? node->attributeRowSpan() : 1;
1096 const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
1097
1098 addArgs = QString::fromLatin1("%1, %2, %3, %4, %5").arg(itemName).arg(row).arg(col).arg(rowSpan).arg(colSpan);
1099 if (!node->attributeAlignment().isEmpty())
1100 addArgs += QLatin1String(", ") + node->attributeAlignment();
1101 } else {
1102 if (layout->attributeClass() == QLatin1String("QFormLayout")) {
1103 methodPrefix = QLatin1String("set");
1104 const int row = node->attributeRow();
1105 const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
1106 const QString role = formLayoutRole(node->attributeColumn(), colSpan);
1107 addArgs = QString::fromLatin1("%1, %2, %3").arg(row).arg(role).arg(itemName);
1108 } else {
1109 addArgs = itemName;
1110 if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty())
1111 addArgs += QLatin1String(", 0, ") + node->attributeAlignment();
1112 }
1113 }
1114
1115 // figure out "add" method
1116 m_output << "\n" << m_indent << layoutName << "->";
1117 switch (node->kind()) {
1118 case DomLayoutItem::Widget:
1119 m_output << methodPrefix << "Widget(" << addArgs;
1120 break;
1121 case DomLayoutItem::Layout:
1122 m_output << methodPrefix << "Layout(" << addArgs;
1123 break;
1124 case DomLayoutItem::Spacer:
1125 m_output << methodPrefix << "Item(" << addArgs;
1126 break;
1127 case DomLayoutItem::Unknown:
1128 Q_ASSERT( 0 );
1129 break;
1130 }
1131 m_output << ");\n\n";
1132 }
1133
acceptActionGroup(DomActionGroup * node)1134 void WriteInitialization::acceptActionGroup(DomActionGroup *node)
1135 {
1136 const QString actionName = m_driver->findOrInsertActionGroup(node);
1137 QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
1138
1139 if (m_actionGroupChain.top())
1140 varName = m_driver->findOrInsertActionGroup(m_actionGroupChain.top());
1141
1142 m_output << m_indent << actionName << " = new QActionGroup(" << varName << ");\n";
1143 writeProperties(actionName, QLatin1String("QActionGroup"), node->elementProperty());
1144
1145 m_actionGroupChain.push(node);
1146 TreeWalker::acceptActionGroup(node);
1147 m_actionGroupChain.pop();
1148 }
1149
acceptAction(DomAction * node)1150 void WriteInitialization::acceptAction(DomAction *node)
1151 {
1152 if (node->hasAttributeMenu())
1153 return;
1154
1155 const QString actionName = m_driver->findOrInsertAction(node);
1156 m_registeredActions.insert(actionName, node);
1157 QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
1158
1159 if (m_actionGroupChain.top())
1160 varName = m_driver->findOrInsertActionGroup(m_actionGroupChain.top());
1161
1162 m_output << m_indent << actionName << " = new QAction(" << varName << ");\n";
1163 writeProperties(actionName, QLatin1String("QAction"), node->elementProperty());
1164 }
1165
acceptActionRef(DomActionRef * node)1166 void WriteInitialization::acceptActionRef(DomActionRef *node)
1167 {
1168 QString actionName = node->attributeName();
1169 const bool isSeparator = actionName == QLatin1String("separator");
1170 bool isMenu = false;
1171
1172 QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
1173
1174 if (actionName.isEmpty() || !m_widgetChain.top()) {
1175 return;
1176 } else if (m_driver->actionGroupByName(actionName)) {
1177 return;
1178 } else if (DomWidget *w = m_driver->widgetByName(actionName)) {
1179 isMenu = m_uic->isMenu(w->attributeClass());
1180 bool inQ3ToolBar = m_uic->customWidgetsInfo()->extends(m_widgetChain.top()->attributeClass(), QLatin1String("Q3ToolBar"));
1181 if (!isMenu && inQ3ToolBar) {
1182 m_actionOut << m_indent << actionName << "->setParent(" << varName << ");\n";
1183 return;
1184 }
1185 } else if (!(m_driver->actionByName(actionName) || isSeparator)) {
1186 fprintf(stderr, "%s: Warning: action `%s' not declared\n",
1187 qPrintable(m_option.messagePrefix()),
1188 actionName.toLatin1().data());
1189 return;
1190 }
1191
1192 if (m_widgetChain.top() && isSeparator) {
1193 // separator is always reserved!
1194 m_actionOut << m_indent << varName << "->addSeparator();\n";
1195 return;
1196 }
1197
1198 if (isMenu)
1199 actionName += QLatin1String("->menuAction()");
1200
1201 m_actionOut << m_indent << varName << "->addAction(" << actionName << ");\n";
1202 }
1203
writeProperties(const QString & varName,const QString & className,const DomPropertyList & lst,unsigned flags)1204 void WriteInitialization::writeProperties(const QString &varName,
1205 const QString &className,
1206 const DomPropertyList &lst,
1207 unsigned flags)
1208 {
1209 const bool isTopLevel = m_widgetChain.count() == 1;
1210
1211 if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
1212 DomPropertyMap properties = propertyMap(lst);
1213 if (properties.contains(QLatin1String("control"))) {
1214 DomProperty *p = properties.value(QLatin1String("control"));
1215 m_output << m_indent << varName << "->setControl(QString::fromUtf8("
1216 << fixString(toString(p->elementString()), m_dindent) << "));\n";
1217 }
1218 }
1219
1220 DomWidget *buttonGroupWidget = findWidget(QLatin1String("Q3ButtonGroup"));
1221
1222 QString indent;
1223 if (!m_widgetChain.top()) {
1224 indent = m_option.indent;
1225 m_output << m_indent << "if (" << varName << "->objectName().isEmpty())\n";
1226 }
1227 if (!(flags & WritePropertyIgnoreObjectName))
1228 m_output << m_indent << indent << varName
1229 << "->setObjectName(QString::fromUtf8(" << fixString(varName, m_dindent) << "));\n";
1230
1231 int leftMargin, topMargin, rightMargin, bottomMargin;
1232 leftMargin = topMargin = rightMargin = bottomMargin = -1;
1233 bool frameShadowEncountered = false;
1234
1235 for (int i=0; i<lst.size(); ++i) {
1236 const DomProperty *p = lst.at(i);
1237 if (!checkProperty(m_option.inputFile, p))
1238 continue;
1239 const QString propertyName = p->attributeName();
1240 QString propertyValue;
1241
1242 // special case for the property `geometry': Do not use position
1243 if (isTopLevel && propertyName == QLatin1String("geometry") && p->elementRect()) {
1244 const DomRect *r = p->elementRect();
1245 m_output << m_indent << varName << "->resize(" << r->elementWidth() << ", " << r->elementHeight() << ");\n";
1246 continue;
1247 } else if (propertyName == QLatin1String("buttonGroupId")) { // Q3ButtonGroup support
1248 if (buttonGroupWidget)
1249 m_output << m_indent << m_driver->findOrInsertWidget(buttonGroupWidget) << "->insert("
1250 << varName << ", " << p->elementNumber() << ");\n";
1251 continue;
1252 } else if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
1253 && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
1254 m_delayedOut << m_indent << varName << "->setCurrentRow("
1255 << p->elementNumber() << ");\n";
1256 continue;
1257 } else if (propertyName == QLatin1String("currentIndex") // set currentIndex later
1258 && (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))
1259 || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
1260 || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
1261 || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))) {
1262 m_delayedOut << m_indent << varName << "->setCurrentIndex("
1263 << p->elementNumber() << ");\n";
1264 continue;
1265 } else if (propertyName == QLatin1String("tabSpacing")
1266 && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))) {
1267 m_delayedOut << m_indent << varName << "->layout()->setSpacing("
1268 << p->elementNumber() << ");\n";
1269 continue;
1270 } else if (propertyName == QLatin1String("control") // ActiveQt support
1271 && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
1272 // already done ;)
1273 continue;
1274 } else if (propertyName == QLatin1String("database")
1275 && p->elementStringList()) {
1276 // Sql support
1277 continue;
1278 } else if (propertyName == QLatin1String("frameworkCode")
1279 && p->kind() == DomProperty::Bool) {
1280 // Sql support
1281 continue;
1282 } else if (propertyName == QLatin1String("orientation")
1283 && m_uic->customWidgetsInfo()->extends(className, QLatin1String("Line"))) {
1284 // Line support
1285 QString shape = QLatin1String("QFrame::HLine");
1286 if (p->elementEnum() == QLatin1String("Qt::Vertical"))
1287 shape = QLatin1String("QFrame::VLine");
1288
1289 m_output << m_indent << varName << "->setFrameShape(" << shape << ");\n";
1290 // QFrame Default is 'Plain'. Make the line 'Sunken' unless otherwise specified
1291 if (!frameShadowEncountered)
1292 m_output << m_indent << varName << "->setFrameShadow(QFrame::Sunken);\n";
1293 continue;
1294 } else if ((flags & WritePropertyIgnoreMargin) && propertyName == QLatin1String("margin")) {
1295 continue;
1296 } else if ((flags & WritePropertyIgnoreSpacing) && propertyName == QLatin1String("spacing")) {
1297 continue;
1298 } else if (propertyName == QLatin1String("leftMargin") && p->kind() == DomProperty::Number) {
1299 leftMargin = p->elementNumber();
1300 continue;
1301 } else if (propertyName == QLatin1String("topMargin") && p->kind() == DomProperty::Number) {
1302 topMargin = p->elementNumber();
1303 continue;
1304 } else if (propertyName == QLatin1String("rightMargin") && p->kind() == DomProperty::Number) {
1305 rightMargin = p->elementNumber();
1306 continue;
1307 } else if (propertyName == QLatin1String("bottomMargin") && p->kind() == DomProperty::Number) {
1308 bottomMargin = p->elementNumber();
1309 continue;
1310 } else if (propertyName == QLatin1String("frameShadow"))
1311 frameShadowEncountered = true;
1312
1313 bool stdset = m_stdsetdef;
1314 if (p->hasAttributeStdset())
1315 stdset = p->attributeStdset();
1316
1317 QString setFunction;
1318
1319 if (stdset) {
1320 setFunction = QLatin1String("->set");
1321 setFunction += propertyName.left(1).toUpper();
1322 setFunction += propertyName.mid(1);
1323 setFunction += QLatin1Char('(');
1324 } else {
1325 setFunction = QLatin1String("->setProperty(\"");
1326 setFunction += propertyName;
1327 setFunction += QLatin1String("\", QVariant(");
1328 }
1329
1330 QString varNewName = varName;
1331
1332 switch (p->kind()) {
1333 case DomProperty::Bool: {
1334 propertyValue = p->elementBool();
1335 break;
1336 }
1337 case DomProperty::Color:
1338 propertyValue = domColor2QString(p->elementColor());
1339 break;
1340 case DomProperty::Cstring:
1341 if (propertyName == QLatin1String("buddy") && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QLabel"))) {
1342 m_buddies.append(Buddy(varName, p->elementCstring()));
1343 } else {
1344 if (stdset)
1345 propertyValue = fixString(p->elementCstring(), m_dindent);
1346 else {
1347 propertyValue = QLatin1String("QByteArray(");
1348 propertyValue += fixString(p->elementCstring(), m_dindent);
1349 propertyValue += QLatin1Char(')');
1350 }
1351 }
1352 break;
1353 case DomProperty::Cursor:
1354 propertyValue = QString::fromLatin1("QCursor(static_cast<Qt::CursorShape>(%1))")
1355 .arg(p->elementCursor());
1356 break;
1357 case DomProperty::CursorShape:
1358 if (p->hasAttributeStdset() && !p->attributeStdset())
1359 varNewName += QLatin1String("->viewport()");
1360 propertyValue = QString::fromLatin1("QCursor(Qt::%1)")
1361 .arg(p->elementCursorShape());
1362 break;
1363 case DomProperty::Enum:
1364 propertyValue = p->elementEnum();
1365 if (!propertyValue.contains(QLatin1String("::"))) {
1366 QString scope = className;
1367 scope += QLatin1String("::");
1368 propertyValue.prepend(scope);
1369 }
1370 break;
1371 case DomProperty::Set:
1372 propertyValue = p->elementSet();
1373 break;
1374 case DomProperty::Font:
1375 propertyValue = writeFontProperties(p->elementFont());
1376 break;
1377 case DomProperty::IconSet:
1378 propertyValue = writeIconProperties(p->elementIconSet());
1379 break;
1380 case DomProperty::Pixmap:
1381 propertyValue = pixCall(p);
1382 break;
1383 case DomProperty::Palette: {
1384 const DomPalette *pal = p->elementPalette();
1385 const QString paletteName = m_driver->unique(QLatin1String("palette"));
1386 m_output << m_indent << "QPalette " << paletteName << ";\n";
1387
1388 writeColorGroup(pal->elementActive(), QLatin1String("QPalette::Active"), paletteName);
1389 writeColorGroup(pal->elementInactive(), QLatin1String("QPalette::Inactive"), paletteName);
1390 writeColorGroup(pal->elementDisabled(), QLatin1String("QPalette::Disabled"), paletteName);
1391
1392 propertyValue = paletteName;
1393 break;
1394 }
1395 case DomProperty::Point: {
1396 const DomPoint *po = p->elementPoint();
1397 propertyValue = QString::fromLatin1("QPoint(%1, %2)")
1398 .arg(po->elementX()).arg(po->elementY());
1399 break;
1400 }
1401 case DomProperty::PointF: {
1402 const DomPointF *pof = p->elementPointF();
1403 propertyValue = QString::fromLatin1("QPointF(%1, %2)")
1404 .arg(pof->elementX()).arg(pof->elementY());
1405 break;
1406 }
1407 case DomProperty::Rect: {
1408 const DomRect *r = p->elementRect();
1409 propertyValue = QString::fromLatin1("QRect(%1, %2, %3, %4)")
1410 .arg(r->elementX()).arg(r->elementY())
1411 .arg(r->elementWidth()).arg(r->elementHeight());
1412 break;
1413 }
1414 case DomProperty::RectF: {
1415 const DomRectF *rf = p->elementRectF();
1416 propertyValue = QString::fromLatin1("QRectF(%1, %2, %3, %4)")
1417 .arg(rf->elementX()).arg(rf->elementY())
1418 .arg(rf->elementWidth()).arg(rf->elementHeight());
1419 break;
1420 }
1421 case DomProperty::Locale: {
1422 const DomLocale *locale = p->elementLocale();
1423 propertyValue = QString::fromLatin1("QLocale(QLocale::%1, QLocale::%2)")
1424 .arg(locale->attributeLanguage()).arg(locale->attributeCountry());
1425 break;
1426 }
1427 case DomProperty::SizePolicy: {
1428 const QString spName = writeSizePolicy( p->elementSizePolicy());
1429 m_output << m_indent << spName << QString::fromLatin1(
1430 ".setHeightForWidth(%1->sizePolicy().hasHeightForWidth());\n")
1431 .arg(varName);
1432
1433 propertyValue = spName;
1434 break;
1435 }
1436 case DomProperty::Size: {
1437 const DomSize *s = p->elementSize();
1438 propertyValue = QString::fromLatin1("QSize(%1, %2)")
1439 .arg(s->elementWidth()).arg(s->elementHeight());
1440 break;
1441 }
1442 case DomProperty::SizeF: {
1443 const DomSizeF *sf = p->elementSizeF();
1444 propertyValue = QString::fromLatin1("QSizeF(%1, %2)")
1445 .arg(sf->elementWidth()).arg(sf->elementHeight());
1446 break;
1447 }
1448 case DomProperty::String: {
1449 if (propertyName == QLatin1String("objectName")) {
1450 const QString v = p->elementString()->text();
1451 if (v == varName)
1452 break;
1453
1454 // ### qWarning("Deprecated: the property `objectName' is different from the variable name");
1455 }
1456
1457 propertyValue = autoTrCall(p->elementString());
1458 break;
1459 }
1460 case DomProperty::Number:
1461 propertyValue = QString::number(p->elementNumber());
1462 break;
1463 case DomProperty::UInt:
1464 propertyValue = QString::number(p->elementUInt());
1465 propertyValue += QLatin1Char('u');
1466 break;
1467 case DomProperty::LongLong:
1468 propertyValue = QLatin1String("Q_INT64_C(");
1469 propertyValue += QString::number(p->elementLongLong());
1470 propertyValue += QLatin1Char(')');;
1471 break;
1472 case DomProperty::ULongLong:
1473 propertyValue = QLatin1String("Q_UINT64_C(");
1474 propertyValue += QString::number(p->elementULongLong());
1475 propertyValue += QLatin1Char(')');
1476 break;
1477 case DomProperty::Float:
1478 propertyValue = QString::number(p->elementFloat());
1479 break;
1480 case DomProperty::Double:
1481 propertyValue = QString::number(p->elementDouble());
1482 break;
1483 case DomProperty::Char: {
1484 const DomChar *c = p->elementChar();
1485 propertyValue = QString::fromLatin1("QChar(%1)")
1486 .arg(c->elementUnicode());
1487 break;
1488 }
1489 case DomProperty::Date: {
1490 const DomDate *d = p->elementDate();
1491 propertyValue = QString::fromLatin1("QDate(%1, %2, %3)")
1492 .arg(d->elementYear())
1493 .arg(d->elementMonth())
1494 .arg(d->elementDay());
1495 break;
1496 }
1497 case DomProperty::Time: {
1498 const DomTime *t = p->elementTime();
1499 propertyValue = QString::fromLatin1("QTime(%1, %2, %3)")
1500 .arg(t->elementHour())
1501 .arg(t->elementMinute())
1502 .arg(t->elementSecond());
1503 break;
1504 }
1505 case DomProperty::DateTime: {
1506 const DomDateTime *dt = p->elementDateTime();
1507 propertyValue = QString::fromLatin1("QDateTime(QDate(%1, %2, %3), QTime(%4, %5, %6))")
1508 .arg(dt->elementYear())
1509 .arg(dt->elementMonth())
1510 .arg(dt->elementDay())
1511 .arg(dt->elementHour())
1512 .arg(dt->elementMinute())
1513 .arg(dt->elementSecond());
1514 break;
1515 }
1516 case DomProperty::StringList:
1517 propertyValue = QLatin1String("QStringList()");
1518 if (p->elementStringList()->elementString().size()) {
1519 const QStringList lst = p->elementStringList()->elementString();
1520 for (int i=0; i<lst.size(); ++i) {
1521 propertyValue += QLatin1String(" << QString::fromUtf8(");
1522 propertyValue += fixString(lst.at(i), m_dindent);
1523 propertyValue += QLatin1Char(')');
1524 }
1525 }
1526 break;
1527
1528 case DomProperty::Url: {
1529 const DomUrl* u = p->elementUrl();
1530 propertyValue = QString::fromLatin1("QUrl(QString::fromUtf8(%1))")
1531 .arg(fixString(u->elementString()->text(), m_dindent));
1532 break;
1533 }
1534 case DomProperty::Brush:
1535 propertyValue = writeBrushInitialization(p->elementBrush());
1536 break;
1537 case DomProperty::Unknown:
1538 break;
1539 }
1540
1541 if (propertyValue.size()) {
1542 const char* defineC = 0;
1543 if (propertyName == QLatin1String("toolTip"))
1544 defineC = toolTipDefineC;
1545 else if (propertyName == QLatin1String("whatsThis"))
1546 defineC = whatsThisDefineC;
1547 else if (propertyName == QLatin1String("statusTip"))
1548 defineC = statusTipDefineC;
1549 else if (propertyName == QLatin1String("accessibleName") || propertyName == QLatin1String("accessibleDescription"))
1550 defineC = accessibilityDefineC;
1551
1552 QTextStream &o = autoTrOutput(p->elementString());
1553
1554 if (defineC)
1555 openIfndef(o, QLatin1String(defineC));
1556 o << m_indent << varNewName << setFunction << propertyValue;
1557 if (!stdset)
1558 o << ')';
1559 o << ");\n";
1560 if (defineC)
1561 closeIfndef(o, QLatin1String(defineC));
1562
1563 if (varName == m_mainFormVarName && &o == &m_refreshOut) {
1564 // this is the only place (currently) where we output mainForm name to the retranslateUi().
1565 // Other places output merely instances of a certain class (which cannot be main form, e.g. QListWidget).
1566 m_mainFormUsedInRetranslateUi = true;
1567 }
1568 }
1569 }
1570 if (leftMargin != -1 || topMargin != -1 || rightMargin != -1 || bottomMargin != -1) {
1571 QString objectName = varName;
1572 if (m_widgetChain.top()) {
1573 const QString parentWidget = m_widgetChain.top()->attributeClass();
1574
1575 if (!m_layoutChain.top() && (m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3GroupBox"))
1576 || m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3ButtonGroup")))) {
1577 objectName = m_driver->findOrInsertWidget(m_widgetChain.top()) + QLatin1String("->layout()");
1578 }
1579 }
1580 m_output << m_indent << objectName << QLatin1String("->setContentsMargins(")
1581 << leftMargin << QLatin1String(", ")
1582 << topMargin << QLatin1String(", ")
1583 << rightMargin << QLatin1String(", ")
1584 << bottomMargin << QLatin1String(");\n");
1585 }
1586 }
1587
writeSizePolicy(const DomSizePolicy * sp)1588 QString WriteInitialization::writeSizePolicy(const DomSizePolicy *sp)
1589 {
1590
1591 // check cache
1592 const SizePolicyHandle sizePolicyHandle(sp);
1593 const SizePolicyNameMap::const_iterator it = m_sizePolicyNameMap.constFind(sizePolicyHandle);
1594 if ( it != m_sizePolicyNameMap.constEnd()) {
1595 return it.value();
1596 }
1597
1598
1599 // insert with new name
1600 const QString spName = m_driver->unique(QLatin1String("sizePolicy"));
1601 m_sizePolicyNameMap.insert(sizePolicyHandle, spName);
1602
1603 m_output << m_indent << "QSizePolicy " << spName;
1604 do {
1605 if (sp->hasElementHSizeType() && sp->hasElementVSizeType()) {
1606 m_output << "(static_cast<QSizePolicy::Policy>(" << sp->elementHSizeType()
1607 << "), static_cast<QSizePolicy::Policy>(" << sp->elementVSizeType() << "));\n";
1608 break;
1609 }
1610 if (sp->hasAttributeHSizeType() && sp->hasAttributeVSizeType()) {
1611 m_output << "(QSizePolicy::" << sp->attributeHSizeType() << ", QSizePolicy::"
1612 << sp->attributeVSizeType() << ");\n";
1613 break;
1614 }
1615 m_output << ";\n";
1616 } while (false);
1617
1618 m_output << m_indent << spName << ".setHorizontalStretch("
1619 << sp->elementHorStretch() << ");\n";
1620 m_output << m_indent << spName << ".setVerticalStretch("
1621 << sp->elementVerStretch() << ");\n";
1622 return spName;
1623 }
1624 // Check for a font with the given properties in the FontPropertiesNameMap
1625 // or create a new one. Returns the name.
1626
writeFontProperties(const DomFont * f)1627 QString WriteInitialization::writeFontProperties(const DomFont *f)
1628 {
1629 // check cache
1630 const FontHandle fontHandle(f);
1631 const FontPropertiesNameMap::const_iterator it = m_fontPropertiesNameMap.constFind(fontHandle);
1632 if ( it != m_fontPropertiesNameMap.constEnd()) {
1633 return it.value();
1634 }
1635
1636 // insert with new name
1637 const QString fontName = m_driver->unique(QLatin1String("font"));
1638 m_fontPropertiesNameMap.insert(FontHandle(f), fontName);
1639
1640 m_output << m_indent << "QFont " << fontName << ";\n";
1641 if (f->hasElementFamily() && !f->elementFamily().isEmpty()) {
1642 m_output << m_indent << fontName << ".setFamily(QString::fromUtf8(" << fixString(f->elementFamily(), m_dindent)
1643 << "));\n";
1644 }
1645 if (f->hasElementPointSize() && f->elementPointSize() > 0) {
1646 m_output << m_indent << fontName << ".setPointSize(" << f->elementPointSize()
1647 << ");\n";
1648 }
1649
1650 if (f->hasElementBold()) {
1651 m_output << m_indent << fontName << ".setBold("
1652 << (f->elementBold() ? "true" : "false") << ");\n";
1653 }
1654 if (f->hasElementItalic()) {
1655 m_output << m_indent << fontName << ".setItalic("
1656 << (f->elementItalic() ? "true" : "false") << ");\n";
1657 }
1658 if (f->hasElementUnderline()) {
1659 m_output << m_indent << fontName << ".setUnderline("
1660 << (f->elementUnderline() ? "true" : "false") << ");\n";
1661 }
1662 if (f->hasElementWeight() && f->elementWeight() > 0) {
1663 m_output << m_indent << fontName << ".setWeight("
1664 << f->elementWeight() << ");" << endl;
1665 }
1666 if (f->hasElementStrikeOut()) {
1667 m_output << m_indent << fontName << ".setStrikeOut("
1668 << (f->elementStrikeOut() ? "true" : "false") << ");\n";
1669 }
1670 if (f->hasElementKerning()) {
1671 m_output << m_indent << fontName << ".setKerning("
1672 << (f->elementKerning() ? "true" : "false") << ");\n";
1673 }
1674 if (f->hasElementAntialiasing()) {
1675 m_output << m_indent << fontName << ".setStyleStrategy("
1676 << (f->elementAntialiasing() ? "QFont::PreferDefault" : "QFont::NoAntialias") << ");\n";
1677 }
1678 if (f->hasElementStyleStrategy()) {
1679 m_output << m_indent << fontName << ".setStyleStrategy(QFont::"
1680 << f->elementStyleStrategy() << ");\n";
1681 }
1682 return fontName;
1683 }
1684
1685 // Post 4.4 write resource icon
writeResourceIcon(QTextStream & output,const QString & iconName,const QString & indent,const DomResourceIcon * i)1686 static void writeResourceIcon(QTextStream &output,
1687 const QString &iconName,
1688 const QString &indent,
1689 const DomResourceIcon *i)
1690 {
1691 if (i->hasElementNormalOff())
1692 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::Off);\n";
1693 if (i->hasElementNormalOn())
1694 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOn()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::On);\n";
1695 if (i->hasElementDisabledOff())
1696 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOff()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::Off);\n";
1697 if (i->hasElementDisabledOn())
1698 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOn()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::On);\n";
1699 if (i->hasElementActiveOff())
1700 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOff()->text(), indent) << "), QSize(), QIcon::Active, QIcon::Off);\n";
1701 if (i->hasElementActiveOn())
1702 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOn()->text(), indent) << "), QSize(), QIcon::Active, QIcon::On);\n";
1703 if (i->hasElementSelectedOff())
1704 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOff()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::Off);\n";
1705 if (i->hasElementSelectedOn())
1706 output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOn()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::On);\n";
1707 }
1708
writeIconProperties(const DomResourceIcon * i)1709 QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
1710 {
1711 // check cache
1712 const IconHandle iconHandle(i);
1713 const IconPropertiesNameMap::const_iterator it = m_iconPropertiesNameMap.constFind(iconHandle);
1714 if (it != m_iconPropertiesNameMap.constEnd()) {
1715 return it.value();
1716 }
1717
1718 // insert with new name
1719 const QString iconName = m_driver->unique(QLatin1String("icon"));
1720 m_iconPropertiesNameMap.insert(IconHandle(i), iconName);
1721 if (isIconFormat44(i)) {
1722 if (i->attributeTheme().isEmpty()) {
1723 // No theme: Write resource icon as is
1724 m_output << m_indent << "QIcon " << iconName << ";\n";
1725 writeResourceIcon(m_output, iconName, m_indent, i);
1726 } else {
1727 // Theme: Generate code to check the theme and default to resource
1728 const QString themeIconName = fixString(i->attributeTheme(), QString());
1729 if (iconHasStatePixmaps(i)) {
1730 // Theme + default state pixmaps:
1731 // Generate code to check the theme and default to state pixmaps
1732 m_output << m_indent << "QIcon " << iconName << ";\n";
1733 const char themeNameStringVariableC[] = "iconThemeName";
1734 // Store theme name in a variable
1735 m_output << m_indent;
1736 if (m_firstThemeIcon) { // Declare variable string
1737 m_output << "QString ";
1738 m_firstThemeIcon = false;
1739 }
1740 m_output << themeNameStringVariableC << " = QString::fromUtf8("
1741 << themeIconName << ");\n";
1742 m_output << m_indent << "if (QIcon::hasThemeIcon("
1743 << themeNameStringVariableC
1744 << ")) {\n"
1745 << m_dindent << iconName << " = QIcon::fromTheme(" << themeNameStringVariableC << ");\n"
1746 << m_indent << "} else {\n";
1747 writeResourceIcon(m_output, iconName, m_dindent, i);
1748 m_output << m_indent << "}\n";
1749 } else {
1750 // Theme, but no state pixmaps: Construct from theme directly.
1751 m_output << m_indent << "QIcon " << iconName
1752 << "(QIcon::fromTheme(QString::fromUtf8("
1753 << themeIconName << ")));\n";
1754 } // Theme, but not state
1755 } // >= 4.4
1756 } else { // pre-4.4 legacy
1757 m_output << m_indent << "const QIcon " << iconName << " = " << pixCall(QLatin1String("QIcon"), i->text())<< ";\n";
1758 }
1759 return iconName;
1760 }
1761
domColor2QString(const DomColor * c)1762 QString WriteInitialization::domColor2QString(const DomColor *c)
1763 {
1764 if (c->hasAttributeAlpha())
1765 return QString::fromLatin1("QColor(%1, %2, %3, %4)")
1766 .arg(c->elementRed())
1767 .arg(c->elementGreen())
1768 .arg(c->elementBlue())
1769 .arg(c->attributeAlpha());
1770 return QString::fromLatin1("QColor(%1, %2, %3)")
1771 .arg(c->elementRed())
1772 .arg(c->elementGreen())
1773 .arg(c->elementBlue());
1774 }
1775
writeColorGroup(DomColorGroup * colorGroup,const QString & group,const QString & paletteName)1776 void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QString &group, const QString &paletteName)
1777 {
1778 if (!colorGroup)
1779 return;
1780
1781 // old format
1782 const QList<DomColor*> colors = colorGroup->elementColor();
1783 for (int i=0; i<colors.size(); ++i) {
1784 const DomColor *color = colors.at(i);
1785
1786 m_output << m_indent << paletteName << ".setColor(" << group
1787 << ", " << "static_cast<QPalette::ColorRole>(" << QString::number(i) << ')'
1788 << ", " << domColor2QString(color)
1789 << ");\n";
1790 }
1791
1792 // new format
1793 const QList<DomColorRole *> colorRoles = colorGroup->elementColorRole();
1794 QListIterator<DomColorRole *> itRole(colorRoles);
1795 while (itRole.hasNext()) {
1796 const DomColorRole *colorRole = itRole.next();
1797 if (colorRole->hasAttributeRole()) {
1798 const QString brushName = writeBrushInitialization(colorRole->elementBrush());
1799 m_output << m_indent << paletteName << ".setBrush(" << group
1800 << ", " << "QPalette::" << colorRole->attributeRole()
1801 << ", " << brushName << ");\n";
1802 }
1803 }
1804 }
1805
1806 // Write initialization for brush unless it is found in the cache. Returns the name to use
1807 // in an expression.
writeBrushInitialization(const DomBrush * brush)1808 QString WriteInitialization::writeBrushInitialization(const DomBrush *brush)
1809 {
1810 // Simple solid, colored brushes are cached
1811 const bool solidColoredBrush = !brush->hasAttributeBrushStyle() || brush->attributeBrushStyle() == QLatin1String("SolidPattern");
1812 uint rgb = 0;
1813 if (solidColoredBrush) {
1814 if (const DomColor *color = brush->elementColor()) {
1815 rgb = ((color->elementRed() & 0xFF) << 24) |
1816 ((color->elementGreen() & 0xFF) << 16) |
1817 ((color->elementBlue() & 0xFF) << 8) |
1818 ((color->attributeAlpha() & 0xFF));
1819 const ColorBrushHash::const_iterator cit = m_colorBrushHash.constFind(rgb);
1820 if (cit != m_colorBrushHash.constEnd())
1821 return cit.value();
1822 }
1823 }
1824 // Create and enter into cache if simple
1825 const QString brushName = m_driver->unique(QLatin1String("brush"));
1826 writeBrush(brush, brushName);
1827 if (solidColoredBrush)
1828 m_colorBrushHash.insert(rgb, brushName);
1829 return brushName;
1830 }
1831
writeBrush(const DomBrush * brush,const QString & brushName)1832 void WriteInitialization::writeBrush(const DomBrush *brush, const QString &brushName)
1833 {
1834 QString style = QLatin1String("SolidPattern");
1835 if (brush->hasAttributeBrushStyle())
1836 style = brush->attributeBrushStyle();
1837
1838 if (style == QLatin1String("LinearGradientPattern") ||
1839 style == QLatin1String("RadialGradientPattern") ||
1840 style == QLatin1String("ConicalGradientPattern")) {
1841 const DomGradient *gradient = brush->elementGradient();
1842 const QString gradientType = gradient->attributeType();
1843 const QString gradientName = m_driver->unique(QLatin1String("gradient"));
1844 if (gradientType == QLatin1String("LinearGradient")) {
1845 m_output << m_indent << "QLinearGradient " << gradientName
1846 << '(' << gradient->attributeStartX()
1847 << ", " << gradient->attributeStartY()
1848 << ", " << gradient->attributeEndX()
1849 << ", " << gradient->attributeEndY() << ");\n";
1850 } else if (gradientType == QLatin1String("RadialGradient")) {
1851 m_output << m_indent << "QRadialGradient " << gradientName
1852 << '(' << gradient->attributeCentralX()
1853 << ", " << gradient->attributeCentralY()
1854 << ", " << gradient->attributeRadius()
1855 << ", " << gradient->attributeFocalX()
1856 << ", " << gradient->attributeFocalY() << ");\n";
1857 } else if (gradientType == QLatin1String("ConicalGradient")) {
1858 m_output << m_indent << "QConicalGradient " << gradientName
1859 << '(' << gradient->attributeCentralX()
1860 << ", " << gradient->attributeCentralY()
1861 << ", " << gradient->attributeAngle() << ");\n";
1862 }
1863
1864 m_output << m_indent << gradientName << ".setSpread(QGradient::"
1865 << gradient->attributeSpread() << ");\n";
1866
1867 if (gradient->hasAttributeCoordinateMode()) {
1868 m_output << m_indent << gradientName << ".setCoordinateMode(QGradient::"
1869 << gradient->attributeCoordinateMode() << ");\n";
1870 }
1871
1872 const QList<DomGradientStop *> stops = gradient->elementGradientStop();
1873 QListIterator<DomGradientStop *> it(stops);
1874 while (it.hasNext()) {
1875 const DomGradientStop *stop = it.next();
1876 const DomColor *color = stop->elementColor();
1877 m_output << m_indent << gradientName << ".setColorAt("
1878 << stop->attributePosition() << ", "
1879 << domColor2QString(color) << ");\n";
1880 }
1881 m_output << m_indent << "QBrush " << brushName << '('
1882 << gradientName << ");\n";
1883 } else if (style == QLatin1String("TexturePattern")) {
1884 const DomProperty *property = brush->elementTexture();
1885 const QString iconValue = iconCall(property);
1886
1887 m_output << m_indent << "QBrush " << brushName << " = QBrush("
1888 << iconValue << ");\n";
1889 } else {
1890 const DomColor *color = brush->elementColor();
1891 m_output << m_indent << "QBrush " << brushName << '('
1892 << domColor2QString(color) << ");\n";
1893
1894 m_output << m_indent << brushName << ".setStyle("
1895 << "Qt::" << style << ");\n";
1896 }
1897 }
1898
acceptCustomWidget(DomCustomWidget * node)1899 void WriteInitialization::acceptCustomWidget(DomCustomWidget *node)
1900 {
1901 Q_UNUSED(node);
1902 }
1903
acceptCustomWidgets(DomCustomWidgets * node)1904 void WriteInitialization::acceptCustomWidgets(DomCustomWidgets *node)
1905 {
1906 Q_UNUSED(node);
1907 }
1908
acceptTabStops(DomTabStops * tabStops)1909 void WriteInitialization::acceptTabStops(DomTabStops *tabStops)
1910 {
1911 QString lastName;
1912
1913 const QStringList l = tabStops->elementTabStop();
1914 for (int i=0; i<l.size(); ++i) {
1915 const QString name = l.at(i);
1916
1917 if (!m_registeredWidgets.contains(name)) {
1918 fprintf(stderr, "%s: Warning: Tab-stop assignment: '%s' is not a valid widget.\n",
1919 qPrintable(m_option.messagePrefix()),
1920 name.toLatin1().data());
1921 continue;
1922 }
1923
1924 if (i == 0) {
1925 lastName = name;
1926 continue;
1927 } else if (name.isEmpty() || lastName.isEmpty()) {
1928 continue;
1929 }
1930
1931 m_output << m_indent << "QWidget::setTabOrder(" << lastName << ", " << name << ");\n";
1932
1933 lastName = name;
1934 }
1935 }
1936
initializeQ3ListBox(DomWidget * w)1937 void WriteInitialization::initializeQ3ListBox(DomWidget *w)
1938 {
1939 const QString varName = m_driver->findOrInsertWidget(w);
1940 const QString className = w->attributeClass();
1941
1942 const QList<DomItem*> items = w->elementItem();
1943
1944 if (items.isEmpty())
1945 return;
1946
1947 m_refreshOut << m_indent << varName << "->clear();\n";
1948
1949 for (int i=0; i<items.size(); ++i) {
1950 const DomItem *item = items.at(i);
1951
1952 const DomPropertyMap properties = propertyMap(item->elementProperty());
1953 const DomProperty *text = properties.value(QLatin1String("text"));
1954 const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
1955 if (!(text || pixmap))
1956 continue;
1957
1958 m_refreshOut << m_indent << varName << "->insertItem(";
1959 if (pixmap) {
1960 m_refreshOut << pixCall(pixmap);
1961
1962 if (text)
1963 m_refreshOut << ", ";
1964 }
1965 if (text)
1966 m_refreshOut << trCall(text->elementString());
1967 m_refreshOut << ");\n";
1968 }
1969 }
1970
initializeQ3IconView(DomWidget * w)1971 void WriteInitialization::initializeQ3IconView(DomWidget *w)
1972 {
1973 const QString varName = m_driver->findOrInsertWidget(w);
1974 const QString className = w->attributeClass();
1975
1976 const QList<DomItem*> items = w->elementItem();
1977
1978 if (items.isEmpty())
1979 return;
1980
1981 m_refreshOut << m_indent << varName << "->clear();\n";
1982
1983 for (int i=0; i<items.size(); ++i) {
1984 const DomItem *item = items.at(i);
1985
1986 const DomPropertyMap properties = propertyMap(item->elementProperty());
1987 const DomProperty *text = properties.value(QLatin1String("text"));
1988 const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
1989 if (!(text || pixmap))
1990 continue;
1991
1992 const QString itemName = m_driver->unique(QLatin1String("__item"));
1993 m_refreshOut << "\n";
1994 m_refreshOut << m_indent << "Q3IconViewItem *" << itemName << " = new Q3IconViewItem(" << varName << ");\n";
1995
1996 if (pixmap) {
1997 m_refreshOut << m_indent << itemName << "->setPixmap(" << pixCall(pixmap) << ");\n";
1998 }
1999
2000 if (text) {
2001 m_refreshOut << m_indent << itemName << "->setText(" << trCall(text->elementString()) << ");\n";
2002 }
2003 }
2004 }
2005
initializeQ3ListView(DomWidget * w)2006 void WriteInitialization::initializeQ3ListView(DomWidget *w)
2007 {
2008 const QString varName = m_driver->findOrInsertWidget(w);
2009 const QString className = w->attributeClass();
2010
2011 // columns
2012 const QList<DomColumn*> columns = w->elementColumn();
2013 for (int i=0; i<columns.size(); ++i) {
2014 const DomColumn *column = columns.at(i);
2015
2016 const DomPropertyMap properties = propertyMap(column->elementProperty());
2017 const DomProperty *text = properties.value(QLatin1String("text"));
2018 const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
2019 const DomProperty *clickable = properties.value(QLatin1String("clickable"));
2020 const DomProperty *resizable = properties.value(QLatin1String("resizable"));
2021
2022 const QString txt = trCall(text->elementString());
2023 m_output << m_indent << varName << "->addColumn(" << txt << ");\n";
2024 m_refreshOut << m_indent << varName << "->header()->setLabel(" << i << ", " << txt << ");\n";
2025
2026 if (pixmap) {
2027 m_output << m_indent << varName << "->header()->setLabel("
2028 << varName << "->header()->count() - 1, " << pixCall(pixmap) << ", " << txt << ");\n";
2029 }
2030
2031 if (clickable != 0) {
2032 m_output << m_indent << varName << "->header()->setClickEnabled(" << clickable->elementBool() << ", " << varName << "->header()->count() - 1);\n";
2033 }
2034
2035 if (resizable != 0) {
2036 m_output << m_indent << varName << "->header()->setResizeEnabled(" << resizable->elementBool() << ", " << varName << "->header()->count() - 1);\n";
2037 }
2038 }
2039
2040 if (w->elementItem().size()) {
2041 m_refreshOut << m_indent << varName << "->clear();\n";
2042
2043 initializeQ3ListViewItems(className, varName, w->elementItem());
2044 }
2045 }
2046
initializeQ3ListViewItems(const QString & className,const QString & varName,const QList<DomItem * > & items)2047 void WriteInitialization::initializeQ3ListViewItems(const QString &className, const QString &varName, const QList<DomItem *> &items)
2048 {
2049 if (items.isEmpty())
2050 return;
2051
2052 // items
2053 for (int i=0; i<items.size(); ++i) {
2054 const DomItem *item = items.at(i);
2055
2056 const QString itemName = m_driver->unique(QLatin1String("__item"));
2057 m_refreshOut << "\n";
2058 m_refreshOut << m_indent << "Q3ListViewItem *" << itemName << " = new Q3ListViewItem(" << varName << ");\n";
2059
2060 int textCount = 0, pixCount = 0;
2061 const DomPropertyList properties = item->elementProperty();
2062 for (int i=0; i<properties.size(); ++i) {
2063 const DomProperty *p = properties.at(i);
2064 if (p->attributeName() == QLatin1String("text"))
2065 m_refreshOut << m_indent << itemName << "->setText(" << textCount++ << ", "
2066 << trCall(p->elementString()) << ");\n";
2067
2068 if (p->attributeName() == QLatin1String("pixmap"))
2069 m_refreshOut << m_indent << itemName << "->setPixmap(" << pixCount++ << ", "
2070 << pixCall(p) << ");\n";
2071 }
2072
2073 if (item->elementItem().size()) {
2074 m_refreshOut << m_indent << itemName << "->setOpen(true);\n";
2075 initializeQ3ListViewItems(className, itemName, item->elementItem());
2076 }
2077 }
2078 }
2079
2080
initializeQ3Table(DomWidget * w)2081 void WriteInitialization::initializeQ3Table(DomWidget *w)
2082 {
2083 const QString varName = m_driver->findOrInsertWidget(w);
2084 const QString className = w->attributeClass();
2085
2086 // columns
2087 const QList<DomColumn*> columns = w->elementColumn();
2088
2089 for (int i=0; i<columns.size(); ++i) {
2090 const DomColumn *column = columns.at(i);
2091
2092 const DomPropertyMap properties = propertyMap(column->elementProperty());
2093 const DomProperty *text = properties.value(QLatin1String("text"));
2094 const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
2095
2096 m_refreshOut << m_indent << varName << "->horizontalHeader()->setLabel(" << i << ", ";
2097 if (pixmap) {
2098 m_refreshOut << pixCall(pixmap) << ", ";
2099 }
2100 m_refreshOut << trCall(text->elementString()) << ");\n";
2101 }
2102
2103 // rows
2104 const QList<DomRow*> rows = w->elementRow();
2105 for (int i=0; i<rows.size(); ++i) {
2106 const DomRow *row = rows.at(i);
2107
2108 const DomPropertyMap properties = propertyMap(row->elementProperty());
2109 const DomProperty *text = properties.value(QLatin1String("text"));
2110 const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
2111
2112 m_refreshOut << m_indent << varName << "->verticalHeader()->setLabel(" << i << ", ";
2113 if (pixmap) {
2114 m_refreshOut << pixCall(pixmap) << ", ";
2115 }
2116 m_refreshOut << trCall(text->elementString()) << ");\n";
2117 }
2118
2119
2120 //initializeQ3TableItems(className, varName, w->elementItem());
2121 }
2122
initializeQ3TableItems(const QString & className,const QString & varName,const QList<DomItem * > & items)2123 void WriteInitialization::initializeQ3TableItems(const QString &className, const QString &varName, const QList<DomItem *> &items)
2124 {
2125 Q_UNUSED(className);
2126 Q_UNUSED(varName);
2127 Q_UNUSED(items);
2128 }
2129
iconCall(const DomProperty * icon)2130 QString WriteInitialization::iconCall(const DomProperty *icon)
2131 {
2132 if (icon->kind() == DomProperty::IconSet)
2133 return writeIconProperties(icon->elementIconSet());
2134 return pixCall(icon);
2135 }
2136
pixCall(const DomProperty * p) const2137 QString WriteInitialization::pixCall(const DomProperty *p) const
2138 {
2139 QString type, s;
2140 switch (p->kind()) {
2141 case DomProperty::IconSet:
2142 type = QLatin1String("QIcon");
2143 s = p->elementIconSet()->text();
2144 break;
2145 case DomProperty::Pixmap:
2146 type = QLatin1String("QPixmap");
2147 s = p->elementPixmap()->text();
2148 break;
2149 default:
2150 qWarning("%s: Warning: Unknown icon format encountered. The ui-file was generated with a too-recent version of Designer.",
2151 qPrintable(m_option.messagePrefix()));
2152 return QLatin1String("QIcon()");
2153 break;
2154 }
2155 return pixCall(type, s);
2156 }
2157
pixCall(const QString & t,const QString & text) const2158 QString WriteInitialization::pixCall(const QString &t, const QString &text) const
2159 {
2160 QString type = t;
2161 if (text.isEmpty()) {
2162 type += QLatin1String("()");
2163 return type;
2164 }
2165 if (const DomImage *image = findImage(text)) {
2166 if (m_option.extractImages) {
2167 const QString format = image->elementData()->attributeFormat();
2168 const QString extension = format.left(format.indexOf(QLatin1Char('.'))).toLower();
2169 QString rc = QLatin1String("QPixmap(QString::fromUtf8(\":/");
2170 rc += m_generatedClass;
2171 rc += QLatin1String("/images/");
2172 rc += text;
2173 rc += QLatin1Char('.');
2174 rc += extension;
2175 rc += QLatin1String("\"))");
2176 return rc;
2177 }
2178 QString rc = WriteIconInitialization::iconFromDataFunction();
2179 rc += QLatin1Char('(');
2180 rc += text;
2181 rc += QLatin1String("_ID)");
2182 return rc;
2183 }
2184
2185 QString pixFunc = m_uic->pixmapFunction();
2186 if (pixFunc.isEmpty())
2187 pixFunc = QLatin1String("QString::fromUtf8");
2188
2189 type += QLatin1Char('(');
2190 type += pixFunc;
2191 type += QLatin1Char('(');
2192 type += fixString(text, m_dindent);
2193 type += QLatin1String("))");
2194 return type;
2195 }
2196
initializeComboBox3(DomWidget * w)2197 void WriteInitialization::initializeComboBox3(DomWidget *w)
2198 {
2199 const QList<DomItem*> items = w->elementItem();
2200 if (items.empty())
2201 return;
2202 // Basic legacy Qt3 support, write out translatable text items, ignore pixmaps
2203 const QString varName = m_driver->findOrInsertWidget(w);
2204 const QString textProperty = QLatin1String("text");
2205
2206 m_refreshOut << m_indent << varName << "->clear();\n";
2207 m_refreshOut << m_indent << varName << "->insertStringList(QStringList()" << '\n';
2208 const int itemCount = items.size();
2209 for (int i = 0; i< itemCount; ++i) {
2210 const DomItem *item = items.at(i);
2211 if (const DomProperty *text = propertyMap(item->elementProperty()).value(textProperty))
2212 m_refreshOut << m_indent << " << " << autoTrCall(text->elementString()) << "\n";
2213 }
2214 m_refreshOut << m_indent << ", 0);\n";
2215 }
2216
initializeComboBox(DomWidget * w)2217 void WriteInitialization::initializeComboBox(DomWidget *w)
2218 {
2219 const QString varName = m_driver->findOrInsertWidget(w);
2220 const QString className = w->attributeClass();
2221
2222 const QList<DomItem*> items = w->elementItem();
2223
2224 if (items.isEmpty())
2225 return;
2226
2227 // If possible use qcombobox's addItems() which is much faster then a bunch of addItem() calls
2228 bool makeStringListCall = true;
2229 bool translatable = false;
2230 QStringList list;
2231 for (int i=0; i<items.size(); ++i) {
2232 const DomItem *item = items.at(i);
2233 const DomPropertyMap properties = propertyMap(item->elementProperty());
2234 const DomProperty *text = properties.value(QLatin1String("text"));
2235 const DomProperty *pixmap = properties.value(QLatin1String("icon"));
2236 bool needsTr = needsTranslation(text->elementString());
2237 if (pixmap != 0 || (i > 0 && translatable != needsTr)) {
2238 makeStringListCall = false;
2239 break;
2240 }
2241 translatable = needsTr;
2242 list.append(autoTrCall(text->elementString())); // fix me here
2243 }
2244
2245 if (makeStringListCall) {
2246 QTextStream &o = translatable ? m_refreshOut : m_output;
2247 if (translatable)
2248 o << m_indent << varName << "->clear();\n";
2249 o << m_indent << varName << "->insertItems(0, QStringList()" << '\n';
2250 for (int i = 0; i < list.size(); ++i)
2251 o << m_indent << " << " << list.at(i) << "\n";
2252 o << m_indent << ");\n";
2253 } else {
2254 for (int i = 0; i < items.size(); ++i) {
2255 const DomItem *item = items.at(i);
2256 const DomPropertyMap properties = propertyMap(item->elementProperty());
2257 const DomProperty *text = properties.value(QLatin1String("text"));
2258 const DomProperty *icon = properties.value(QLatin1String("icon"));
2259
2260 QString iconValue;
2261 if (icon)
2262 iconValue = iconCall(icon);
2263
2264 m_output << m_indent << varName << "->addItem(";
2265 if (icon)
2266 m_output << iconValue << ", ";
2267
2268 if (needsTranslation(text->elementString())) {
2269 m_output << "QString());\n";
2270 m_refreshOut << m_indent << varName << "->setItemText(" << i << ", " << trCall(text->elementString()) << ");\n";
2271 } else {
2272 m_output << noTrCall(text->elementString()) << ");\n";
2273 }
2274 }
2275 m_refreshOut << "\n";
2276 }
2277 }
2278
disableSorting(DomWidget * w,const QString & varName)2279 QString WriteInitialization::disableSorting(DomWidget *w, const QString &varName)
2280 {
2281 // turn off sortingEnabled to force programmatic item order (setItem())
2282 QString tempName;
2283 if (!w->elementItem().isEmpty()) {
2284 tempName = m_driver->unique(QLatin1String("__sortingEnabled"));
2285 m_refreshOut << "\n";
2286 m_refreshOut << m_indent << "const bool " << tempName
2287 << " = " << varName << "->isSortingEnabled();\n";
2288 m_refreshOut << m_indent << varName << "->setSortingEnabled(false);\n";
2289 }
2290 return tempName;
2291 }
2292
enableSorting(DomWidget * w,const QString & varName,const QString & tempName)2293 void WriteInitialization::enableSorting(DomWidget *w, const QString &varName, const QString &tempName)
2294 {
2295 if (!w->elementItem().isEmpty()) {
2296 m_refreshOut << m_indent << varName << "->setSortingEnabled(" << tempName << ");\n\n";
2297 }
2298 }
2299
2300 /*
2301 * Initializers are just strings containing the function call and need to be prepended
2302 * the line indentation and the object they are supposed to initialize.
2303 * String initializers come with a preprocessor conditional (ifdef), so the code
2304 * compiles with QT_NO_xxx. A null pointer means no conditional. String initializers
2305 * are written to the retranslateUi() function, others to setupUi().
2306 */
2307
2308
2309 /*!
2310 Create non-string inititializer.
2311 \param value the value to initialize the attribute with. May be empty, in which case
2312 the initializer is omitted.
2313 See above for other parameters.
2314 */
addInitializer(Item * item,const QString & name,int column,const QString & value,const QString & directive,bool translatable) const2315 void WriteInitialization::addInitializer(Item *item,
2316 const QString &name, int column, const QString &value, const QString &directive, bool translatable) const
2317 {
2318 if (!value.isEmpty())
2319 item->addSetter(QLatin1String("->set") + name.at(0).toUpper() + name.mid(1) +
2320 QLatin1Char('(') + (column < 0 ? QString() : QString::number(column) +
2321 QLatin1String(", ")) + value + QLatin1String(");"), directive, translatable);
2322 }
2323
2324 /*!
2325 Create string inititializer.
2326 \param initializers in/out list of inializers
2327 \param properties map property name -> property to extract data from
2328 \param name the property to extract
2329 \param col the item column to generate the initializer for. This is relevant for
2330 tree widgets only. If it is -1, no column index will be generated.
2331 \param ifdef preprocessor symbol for disabling compilation of this initializer
2332 */
addStringInitializer(Item * item,const DomPropertyMap & properties,const QString & name,int column,const QString & directive) const2333 void WriteInitialization::addStringInitializer(Item *item,
2334 const DomPropertyMap &properties, const QString &name, int column, const QString &directive) const
2335 {
2336 if (const DomProperty *p = properties.value(name)) {
2337 DomString *str = p->elementString();
2338 QString text = toString(str);
2339 if (!text.isEmpty()) {
2340 bool translatable = needsTranslation(str);
2341 QString value = autoTrCall(str);
2342 addInitializer(item, name, column, value, directive, translatable);
2343 }
2344 }
2345 }
2346
addBrushInitializer(Item * item,const DomPropertyMap & properties,const QString & name,int column)2347 void WriteInitialization::addBrushInitializer(Item *item,
2348 const DomPropertyMap &properties, const QString &name, int column)
2349 {
2350 if (const DomProperty *p = properties.value(name)) {
2351 if (p->elementBrush())
2352 addInitializer(item, name, column, writeBrushInitialization(p->elementBrush()));
2353 else if (p->elementColor())
2354 addInitializer(item, name, column, domColor2QString(p->elementColor()));
2355 }
2356 }
2357
2358 /*!
2359 Create inititializer for a flag value in the Qt namespace.
2360 If the named property is not in the map, the initializer is omitted.
2361 */
addQtFlagsInitializer(Item * item,const DomPropertyMap & properties,const QString & name,int column) const2362 void WriteInitialization::addQtFlagsInitializer(Item *item,
2363 const DomPropertyMap &properties, const QString &name, int column) const
2364 {
2365 if (const DomProperty *p = properties.value(name)) {
2366 QString v = p->elementSet();
2367 if (!v.isEmpty()) {
2368 v.replace(QLatin1Char('|'), QLatin1String("|Qt::"));
2369 addInitializer(item, name, column, QLatin1String("Qt::") + v);
2370 }
2371 }
2372 }
2373
2374 /*!
2375 Create inititializer for an enum value in the Qt namespace.
2376 If the named property is not in the map, the initializer is omitted.
2377 */
addQtEnumInitializer(Item * item,const DomPropertyMap & properties,const QString & name,int column) const2378 void WriteInitialization::addQtEnumInitializer(Item *item,
2379 const DomPropertyMap &properties, const QString &name, int column) const
2380 {
2381 if (const DomProperty *p = properties.value(name)) {
2382 QString v = p->elementEnum();
2383 if (!v.isEmpty())
2384 addInitializer(item, name, column, QLatin1String("Qt::") + v);
2385 }
2386 }
2387
2388 /*!
2389 Create inititializers for all common properties that may be bound to a column.
2390 */
addCommonInitializers(Item * item,const DomPropertyMap & properties,int column)2391 void WriteInitialization::addCommonInitializers(Item *item,
2392 const DomPropertyMap &properties, int column)
2393 {
2394 if (const DomProperty *icon = properties.value(QLatin1String("icon")))
2395 addInitializer(item, QLatin1String("icon"), column, iconCall(icon));
2396 addBrushInitializer(item, properties, QLatin1String("foreground"), column);
2397 addBrushInitializer(item, properties, QLatin1String("background"), column);
2398 if (const DomProperty *font = properties.value(QLatin1String("font")))
2399 addInitializer(item, QLatin1String("font"), column, writeFontProperties(font->elementFont()));
2400 addQtFlagsInitializer(item, properties, QLatin1String("textAlignment"), column);
2401 addQtEnumInitializer(item, properties, QLatin1String("checkState"), column);
2402 addStringInitializer(item, properties, QLatin1String("text"), column);
2403 addStringInitializer(item, properties, QLatin1String("toolTip"), column, QLatin1String(toolTipDefineC));
2404 addStringInitializer(item, properties, QLatin1String("whatsThis"), column, QLatin1String(whatsThisDefineC));
2405 addStringInitializer(item, properties, QLatin1String("statusTip"), column, QLatin1String(statusTipDefineC));
2406 }
2407
initializeListWidget(DomWidget * w)2408 void WriteInitialization::initializeListWidget(DomWidget *w)
2409 {
2410 const QString varName = m_driver->findOrInsertWidget(w);
2411 const QString className = w->attributeClass();
2412
2413 const QList<DomItem*> items = w->elementItem();
2414
2415 if (items.isEmpty())
2416 return;
2417
2418 QString tempName = disableSorting(w, varName);
2419 // items
2420 // TODO: the generated code should be data-driven to reduce its size
2421 for (int i = 0; i < items.size(); ++i) {
2422 const DomItem *domItem = items.at(i);
2423
2424 const DomPropertyMap properties = propertyMap(domItem->elementProperty());
2425
2426 Item item(QLatin1String("QListWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
2427 addQtFlagsInitializer(&item, properties, QLatin1String("flags"));
2428 addCommonInitializers(&item, properties);
2429
2430 item.writeSetupUi(varName);
2431 item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(i) + QLatin1Char(')'));
2432 }
2433 enableSorting(w, varName, tempName);
2434 }
2435
initializeTreeWidget(DomWidget * w)2436 void WriteInitialization::initializeTreeWidget(DomWidget *w)
2437 {
2438 const QString varName = m_driver->findOrInsertWidget(w);
2439
2440 // columns
2441 Item item(QLatin1String("QTreeWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
2442
2443 const QList<DomColumn*> columns = w->elementColumn();
2444 for (int i = 0; i < columns.size(); ++i) {
2445 const DomColumn *column = columns.at(i);
2446
2447 const DomPropertyMap properties = propertyMap(column->elementProperty());
2448 addCommonInitializers(&item, properties, i);
2449 }
2450 const QString itemName = item.writeSetupUi(QString(), Item::DontConstruct);
2451 item.writeRetranslateUi(varName + QLatin1String("->headerItem()"));
2452 if (!itemName.isNull())
2453 m_output << m_indent << varName << "->setHeaderItem(" << itemName << ");\n";
2454
2455 if (w->elementItem().size() == 0)
2456 return;
2457
2458 QString tempName = disableSorting(w, varName);
2459
2460 QList<Item *> items = initializeTreeWidgetItems(w->elementItem());
2461 for (int i = 0; i < items.count(); i++) {
2462 Item *itm = items[i];
2463 itm->writeSetupUi(varName);
2464 itm->writeRetranslateUi(varName + QLatin1String("->topLevelItem(") + QString::number(i) + QLatin1Char(')'));
2465 delete itm;
2466 }
2467
2468 enableSorting(w, varName, tempName);
2469 }
2470
2471 /*!
2472 Create and write out initializers for tree widget items.
2473 This function makes sure that only needed items are fetched (subject to preprocessor
2474 conditionals), that each item is fetched from its parent widget/item exactly once
2475 and that no temporary variables are created for items that are needed only once. As
2476 fetches are built top-down from the root, but determining how often and under which
2477 conditions an item is needed needs to be done bottom-up, the whole process makes
2478 two passes, storing the intermediate result in a recursive StringInitializerListMap.
2479 */
initializeTreeWidgetItems(const QList<DomItem * > & domItems)2480 QList<WriteInitialization::Item *> WriteInitialization::initializeTreeWidgetItems(const QList<DomItem *> &domItems)
2481 {
2482 // items
2483 QList<Item *> items;
2484
2485 for (int i = 0; i < domItems.size(); ++i) {
2486 const DomItem *domItem = domItems.at(i);
2487
2488 Item *item = new Item(QLatin1String("QTreeWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
2489 items << item;
2490
2491 QHash<QString, DomProperty *> map;
2492
2493 int col = -1;
2494 const DomPropertyList properties = domItem->elementProperty();
2495 for (int j = 0; j < properties.size(); ++j) {
2496 DomProperty *p = properties.at(j);
2497 if (p->attributeName() == QLatin1String("text")) {
2498 if (!map.isEmpty()) {
2499 addCommonInitializers(item, map, col);
2500 map.clear();
2501 }
2502 col++;
2503 }
2504 map.insert(p->attributeName(), p);
2505 }
2506 addCommonInitializers(item, map, col);
2507 // AbstractFromBuilder saves flags last, so they always end up in the last column's map.
2508 addQtFlagsInitializer(item, map, QLatin1String("flags"));
2509
2510 QList<Item *> subItems = initializeTreeWidgetItems(domItem->elementItem());
2511 foreach (Item *subItem, subItems)
2512 item->addChild(subItem);
2513 }
2514 return items;
2515 }
2516
initializeTableWidget(DomWidget * w)2517 void WriteInitialization::initializeTableWidget(DomWidget *w)
2518 {
2519 const QString varName = m_driver->findOrInsertWidget(w);
2520
2521 // columns
2522 const QList<DomColumn *> columns = w->elementColumn();
2523
2524 if (columns.size() != 0) {
2525 m_output << m_indent << "if (" << varName << "->columnCount() < " << columns.size() << ")\n"
2526 << m_dindent << varName << "->setColumnCount(" << columns.size() << ");\n";
2527 }
2528
2529 for (int i = 0; i < columns.size(); ++i) {
2530 const DomColumn *column = columns.at(i);
2531 if (!column->elementProperty().isEmpty()) {
2532 const DomPropertyMap properties = propertyMap(column->elementProperty());
2533
2534 Item item(QLatin1String("QTableWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
2535 addCommonInitializers(&item, properties);
2536
2537 QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
2538 item.writeRetranslateUi(varName + QLatin1String("->horizontalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
2539 m_output << m_indent << varName << "->setHorizontalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n";
2540 }
2541 }
2542
2543 // rows
2544 const QList<DomRow *> rows = w->elementRow();
2545
2546 if (rows.size() != 0) {
2547 m_output << m_indent << "if (" << varName << "->rowCount() < " << rows.size() << ")\n"
2548 << m_dindent << varName << "->setRowCount(" << rows.size() << ");\n";
2549 }
2550
2551 for (int i = 0; i < rows.size(); ++i) {
2552 const DomRow *row = rows.at(i);
2553 if (!row->elementProperty().isEmpty()) {
2554 const DomPropertyMap properties = propertyMap(row->elementProperty());
2555
2556 Item item(QLatin1String("QTableWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
2557 addCommonInitializers(&item, properties);
2558
2559 QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
2560 item.writeRetranslateUi(varName + QLatin1String("->verticalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
2561 m_output << m_indent << varName << "->setVerticalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n";
2562 }
2563 }
2564
2565 // items
2566 QString tempName = disableSorting(w, varName);
2567
2568 const QList<DomItem *> items = w->elementItem();
2569
2570 for (int i = 0; i < items.size(); ++i) {
2571 const DomItem *cell = items.at(i);
2572 if (cell->hasAttributeRow() && cell->hasAttributeColumn() && !cell->elementProperty().isEmpty()) {
2573 const int r = cell->attributeRow();
2574 const int c = cell->attributeColumn();
2575 const DomPropertyMap properties = propertyMap(cell->elementProperty());
2576
2577 Item item(QLatin1String("QTableWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
2578 addQtFlagsInitializer(&item, properties, QLatin1String("flags"));
2579 addCommonInitializers(&item, properties);
2580
2581 QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
2582 item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(r) + QLatin1String(", ") + QString::number(c) + QLatin1Char(')'));
2583 m_output << m_indent << varName << "->setItem(" << QString::number(r) << ", " << QString::number(c) << ", " << itemName << ");\n";
2584 }
2585 }
2586 enableSorting(w, varName, tempName);
2587 }
2588
trCall(const QString & str,const QString & commentHint) const2589 QString WriteInitialization::trCall(const QString &str, const QString &commentHint) const
2590 {
2591 if (str.isEmpty())
2592 return QLatin1String("QString()");
2593
2594 QString result;
2595 const QString comment = commentHint.isEmpty() ? QString(QLatin1Char('0')) : fixString(commentHint, m_dindent);
2596
2597 if (m_option.translateFunction.isEmpty()) {
2598 result = QLatin1String("QApplication::translate(\"");
2599 result += m_generatedClass;
2600 result += QLatin1Char('"');
2601 result += QLatin1String(", ");
2602 } else {
2603 result = m_option.translateFunction;
2604 result += QLatin1Char('(');
2605 }
2606
2607 result += fixString(str, m_dindent);
2608 result += QLatin1String(", ");
2609 result += comment;
2610
2611 if (m_option.translateFunction.isEmpty()) {
2612 result += QLatin1String(", ");
2613 result += QLatin1String("QApplication::UnicodeUTF8");
2614 }
2615
2616 result += QLatin1Char(')');
2617 return result;
2618 }
2619
initializeQ3SqlDataTable(DomWidget * w)2620 void WriteInitialization::initializeQ3SqlDataTable(DomWidget *w)
2621 {
2622 const DomPropertyMap properties = propertyMap(w->elementProperty());
2623
2624 const DomProperty *frameworkCode = properties.value(QLatin1String("frameworkCode"), 0);
2625 if (frameworkCode && toBool(frameworkCode->elementBool()) == false)
2626 return;
2627
2628 QString connection;
2629 QString table;
2630 QString field;
2631
2632 const DomProperty *db = properties.value(QLatin1String("database"), 0);
2633 if (db && db->elementStringList()) {
2634 const QStringList info = db->elementStringList()->elementString();
2635 connection = info.size() > 0 ? info.at(0) : QString();
2636 table = info.size() > 1 ? info.at(1) : QString();
2637 field = info.size() > 2 ? info.at(2) : QString();
2638 }
2639
2640 if (table.isEmpty() || connection.isEmpty()) {
2641 fprintf(stderr, "%s: Warning: Invalid database connection\n", qPrintable(m_option.messagePrefix()));
2642 return;
2643 }
2644
2645 const QString varName = m_driver->findOrInsertWidget(w);
2646
2647 m_output << m_indent << "if (!" << varName << "->sqlCursor()) {\n";
2648
2649 m_output << m_dindent << varName << "->setSqlCursor(";
2650
2651 if (connection == QLatin1String("(default)")) {
2652 m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << "), false, true);\n";
2653 } else {
2654 m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << ", true, " << connection << "Connection" << "), false, true);\n";
2655 }
2656 m_output << m_dindent << varName << "->refresh(Q3DataTable::RefreshAll);\n";
2657 m_output << m_indent << "}\n";
2658 }
2659
initializeQ3SqlDataBrowser(DomWidget * w)2660 void WriteInitialization::initializeQ3SqlDataBrowser(DomWidget *w)
2661 {
2662 const DomPropertyMap properties = propertyMap(w->elementProperty());
2663
2664 const DomProperty *frameworkCode = properties.value(QLatin1String("frameworkCode"), 0);
2665 if (frameworkCode && toBool(frameworkCode->elementBool()) == false)
2666 return;
2667
2668 QString connection;
2669 QString table;
2670 QString field;
2671
2672 const DomProperty *db = properties.value(QLatin1String("database"), 0);
2673 if (db && db->elementStringList()) {
2674 const QStringList info = db->elementStringList()->elementString();
2675 connection = info.size() > 0 ? info.at(0) : QString();
2676 table = info.size() > 1 ? info.at(1) : QString();
2677 field = info.size() > 2 ? info.at(2) : QString();
2678 }
2679
2680 if (table.isEmpty() || connection.isEmpty()) {
2681 fprintf(stderr, "%s: Warning: Invalid database connection\n", qPrintable(m_option.messagePrefix()));
2682 return;
2683 }
2684
2685 const QString varName = m_driver->findOrInsertWidget(w);
2686
2687 m_output << m_indent << "if (!" << varName << "->sqlCursor()) {\n";
2688
2689 m_output << m_dindent << varName << "->setSqlCursor(";
2690
2691 if (connection == QLatin1String("(default)")) {
2692 m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << "), true);\n";
2693 } else {
2694 m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << ", true, " << connection << "Connection" << "), false, true);\n";
2695 }
2696 m_output << m_dindent << varName << "->refresh();\n";
2697 m_output << m_indent << "}\n";
2698 }
2699
initializeMenu(DomWidget * w,const QString &)2700 void WriteInitialization::initializeMenu(DomWidget *w, const QString &/*parentWidget*/)
2701 {
2702 const QString menuName = m_driver->findOrInsertWidget(w);
2703 const QString menuAction = menuName + QLatin1String("Action");
2704
2705 const DomAction *action = m_driver->actionByName(menuAction);
2706 if (action && action->hasAttributeMenu()) {
2707 m_output << m_indent << menuAction << " = " << menuName << "->menuAction();\n";
2708 }
2709 }
2710
trCall(DomString * str,const QString & defaultString) const2711 QString WriteInitialization::trCall(DomString *str, const QString &defaultString) const
2712 {
2713 QString value = defaultString;
2714 QString comment;
2715 if (str) {
2716 value = toString(str);
2717 comment = str->attributeComment();
2718 }
2719 return trCall(value, comment);
2720 }
2721
noTrCall(DomString * str,const QString & defaultString) const2722 QString WriteInitialization::noTrCall(DomString *str, const QString &defaultString) const
2723 {
2724 QString value = defaultString;
2725 if (!str && defaultString.isEmpty())
2726 return QString();
2727 if (str)
2728 value = str->text();
2729 QString ret = QLatin1String("QString::fromUtf8(");
2730 ret += fixString(value, m_dindent);
2731 ret += QLatin1Char(')');
2732 return ret;
2733 }
2734
autoTrCall(DomString * str,const QString & defaultString) const2735 QString WriteInitialization::autoTrCall(DomString *str, const QString &defaultString) const
2736 {
2737 if ((!str && !defaultString.isEmpty()) || needsTranslation(str))
2738 return trCall(str, defaultString);
2739 return noTrCall(str, defaultString);
2740 }
2741
autoTrOutput(DomString * str,const QString & defaultString)2742 QTextStream &WriteInitialization::autoTrOutput(DomString *str, const QString &defaultString)
2743 {
2744 if ((!str && !defaultString.isEmpty()) || needsTranslation(str))
2745 return m_refreshOut;
2746 return m_output;
2747 }
2748
isValidObject(const QString & name) const2749 bool WriteInitialization::isValidObject(const QString &name) const
2750 {
2751 return m_registeredWidgets.contains(name)
2752 || m_registeredActions.contains(name);
2753 }
2754
findDeclaration(const QString & name)2755 QString WriteInitialization::findDeclaration(const QString &name)
2756 {
2757 const QString normalized = Driver::normalizedName(name);
2758
2759 if (DomWidget *widget = m_driver->widgetByName(normalized))
2760 return m_driver->findOrInsertWidget(widget);
2761 if (DomAction *action = m_driver->actionByName(normalized))
2762 return m_driver->findOrInsertAction(action);
2763 if (const DomButtonGroup *group = m_driver->findButtonGroup(normalized))
2764 return m_driver->findOrInsertButtonGroup(group);
2765 return QString();
2766 }
2767
acceptConnection(DomConnection * connection)2768 void WriteInitialization::acceptConnection(DomConnection *connection)
2769 {
2770 const QString sender = findDeclaration(connection->elementSender());
2771 const QString receiver = findDeclaration(connection->elementReceiver());
2772
2773 if (sender.isEmpty() || receiver.isEmpty())
2774 return;
2775
2776 m_output << m_indent << "QObject::connect("
2777 << sender
2778 << ", "
2779 << "SIGNAL("<<connection->elementSignal()<<')'
2780 << ", "
2781 << receiver
2782 << ", "
2783 << "SLOT("<<connection->elementSlot()<<')'
2784 << ");\n";
2785 }
2786
findImage(const QString & name) const2787 DomImage *WriteInitialization::findImage(const QString &name) const
2788 {
2789 return m_registeredImages.value(name);
2790 }
2791
findWidget(const QLatin1String & widgetClass)2792 DomWidget *WriteInitialization::findWidget(const QLatin1String &widgetClass)
2793 {
2794 for (int i = m_widgetChain.count() - 1; i >= 0; --i) {
2795 DomWidget *widget = m_widgetChain.at(i);
2796
2797 if (widget && m_uic->customWidgetsInfo()->extends(widget->attributeClass(), widgetClass))
2798 return widget;
2799 }
2800
2801 return 0;
2802 }
2803
acceptImage(DomImage * image)2804 void WriteInitialization::acceptImage(DomImage *image)
2805 {
2806 if (!image->hasAttributeName())
2807 return;
2808
2809 m_registeredImages.insert(image->attributeName(), image);
2810 }
2811
acceptWidgetScripts(const DomScripts & widgetScripts,DomWidget * node,const DomWidgets & childWidgets)2812 void WriteInitialization::acceptWidgetScripts(const DomScripts &widgetScripts, DomWidget *node, const DomWidgets &childWidgets)
2813 {
2814 // Add the per-class custom scripts to the per-widget ones.
2815 DomScripts scripts(widgetScripts);
2816
2817 if (DomScript *customWidgetScript = m_uic->customWidgetsInfo()->customWidgetScript(node->attributeClass()))
2818 scripts.push_front(customWidgetScript);
2819
2820 if (scripts.empty())
2821 return;
2822
2823 // concatenate script snippets
2824 QString script;
2825 foreach (const DomScript *domScript, scripts) {
2826 const QString snippet = domScript->text();
2827 if (!snippet.isEmpty()) {
2828 script += snippet.trimmed();
2829 script += QLatin1Char('\n');
2830 }
2831 }
2832 if (script.isEmpty())
2833 return;
2834
2835 // Build the list of children and insert call
2836 m_output << m_indent << "childWidgets.clear();\n";
2837 if (!childWidgets.empty()) {
2838 m_output << m_indent << "childWidgets";
2839 foreach (DomWidget *child, childWidgets) {
2840 m_output << " << " << m_driver->findOrInsertWidget(child);
2841 }
2842 m_output << ";\n";
2843 }
2844 m_output << m_indent << "scriptContext.run(QString::fromUtf8("
2845 << fixString(script, m_dindent) << "), "
2846 << m_driver->findOrInsertWidget(node) << ", childWidgets);\n";
2847 }
2848
2849
generateMultiDirectiveBegin(QTextStream & outputStream,const QSet<QString> & directives)2850 static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QString> &directives)
2851 {
2852 if (directives.isEmpty())
2853 return;
2854
2855 QMap<QString, bool> map; // bool is dummy. The idea is to sort that (always generate in the same order) by putting a set into a map
2856 foreach (const QString &str, directives)
2857 map.insert(str, true);
2858
2859 if (map.size() == 1) {
2860 outputStream << "#ifndef " << map.constBegin().key() << endl;
2861 return;
2862 }
2863
2864 outputStream << "#if";
2865 bool doOr = false;
2866 foreach (const QString &str, map.keys()) {
2867 if (doOr)
2868 outputStream << " ||";
2869 outputStream << " !defined(" << str << ')';
2870 doOr = true;
2871 }
2872 outputStream << endl;
2873 }
2874
generateMultiDirectiveEnd(QTextStream & outputStream,const QSet<QString> & directives)2875 static void generateMultiDirectiveEnd(QTextStream &outputStream, const QSet<QString> &directives)
2876 {
2877 if (directives.isEmpty())
2878 return;
2879
2880 outputStream << "#endif" << endl;
2881 }
2882
Item(const QString & itemClassName,const QString & indent,QTextStream & setupUiStream,QTextStream & retranslateUiStream,Driver * driver)2883 WriteInitialization::Item::Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver)
2884 :
2885 m_parent(0),
2886 m_itemClassName(itemClassName),
2887 m_indent(indent),
2888 m_setupUiStream(setupUiStream),
2889 m_retranslateUiStream(retranslateUiStream),
2890 m_driver(driver)
2891 {
2892
2893 }
2894
~Item()2895 WriteInitialization::Item::~Item()
2896 {
2897 foreach (Item *child, m_children)
2898 delete child;
2899 }
2900
writeSetupUi(const QString & parent,Item::EmptyItemPolicy emptyItemPolicy)2901 QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::EmptyItemPolicy emptyItemPolicy)
2902 {
2903 if (emptyItemPolicy == Item::DontConstruct && m_setupUiData.policy == ItemData::DontGenerate)
2904 return QString();
2905
2906 bool generateMultiDirective = false;
2907 if (emptyItemPolicy == Item::ConstructItemOnly && m_children.size() == 0) {
2908 if (m_setupUiData.policy == ItemData::DontGenerate) {
2909 m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
2910 return QString();
2911 } else if (m_setupUiData.policy == ItemData::GenerateWithMultiDirective) {
2912 generateMultiDirective = true;
2913 }
2914 }
2915
2916 if (generateMultiDirective)
2917 generateMultiDirectiveBegin(m_setupUiStream, m_setupUiData.directives);
2918
2919 const QString uniqueName = m_driver->unique(QLatin1String("__") + m_itemClassName.toLower());
2920 m_setupUiStream << m_indent << m_itemClassName << " *" << uniqueName << " = new " << m_itemClassName << '(' << parent << ");\n";
2921
2922 if (generateMultiDirective) {
2923 m_setupUiStream << "#else\n";
2924 m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
2925 generateMultiDirectiveEnd(m_setupUiStream, m_setupUiData.directives);
2926 }
2927
2928 QMultiMap<QString, QString>::ConstIterator it = m_setupUiData.setters.constBegin();
2929 while (it != m_setupUiData.setters.constEnd()) {
2930 openIfndef(m_setupUiStream, it.key());
2931 m_setupUiStream << m_indent << uniqueName << it.value() << endl;
2932 closeIfndef(m_setupUiStream, it.key());
2933 ++it;
2934 }
2935 foreach (Item *child, m_children)
2936 child->writeSetupUi(uniqueName);
2937 return uniqueName;
2938 }
2939
writeRetranslateUi(const QString & parentPath)2940 void WriteInitialization::Item::writeRetranslateUi(const QString &parentPath)
2941 {
2942 if (m_retranslateUiData.policy == ItemData::DontGenerate)
2943 return;
2944
2945 if (m_retranslateUiData.policy == ItemData::GenerateWithMultiDirective)
2946 generateMultiDirectiveBegin(m_retranslateUiStream, m_retranslateUiData.directives);
2947
2948 const QString uniqueName = m_driver->unique(QLatin1String("___") + m_itemClassName.toLower());
2949 m_retranslateUiStream << m_indent << m_itemClassName << " *" << uniqueName << " = " << parentPath << ";\n";
2950
2951 if (m_retranslateUiData.policy == ItemData::GenerateWithMultiDirective)
2952 generateMultiDirectiveEnd(m_retranslateUiStream, m_retranslateUiData.directives);
2953
2954 QString oldDirective;
2955 QMultiMap<QString, QString>::ConstIterator it = m_retranslateUiData.setters.constBegin();
2956 while (it != m_retranslateUiData.setters.constEnd()) {
2957 const QString newDirective = it.key();
2958 if (oldDirective != newDirective) {
2959 closeIfndef(m_retranslateUiStream, oldDirective);
2960 openIfndef(m_retranslateUiStream, newDirective);
2961 oldDirective = newDirective;
2962 }
2963 m_retranslateUiStream << m_indent << uniqueName << it.value() << endl;
2964 ++it;
2965 }
2966 closeIfndef(m_retranslateUiStream, oldDirective);
2967
2968 for (int i = 0; i < m_children.size(); i++)
2969 m_children[i]->writeRetranslateUi(uniqueName + QLatin1String("->child(") + QString::number(i) + QLatin1Char(')'));
2970 }
2971
addSetter(const QString & setter,const QString & directive,bool translatable)2972 void WriteInitialization::Item::addSetter(const QString &setter, const QString &directive, bool translatable)
2973 {
2974 const ItemData::TemporaryVariableGeneratorPolicy newPolicy = directive.isNull() ? ItemData::Generate : ItemData::GenerateWithMultiDirective;
2975 if (translatable) {
2976 m_retranslateUiData.setters.insert(directive, setter);
2977 if (ItemData::GenerateWithMultiDirective == newPolicy)
2978 m_retranslateUiData.directives << directive;
2979 if (m_retranslateUiData.policy < newPolicy)
2980 m_retranslateUiData.policy = newPolicy;
2981 } else {
2982 m_setupUiData.setters.insert(directive, setter);
2983 if (ItemData::GenerateWithMultiDirective == newPolicy)
2984 m_setupUiData.directives << directive;
2985 if (m_setupUiData.policy < newPolicy)
2986 m_setupUiData.policy = newPolicy;
2987 }
2988 }
2989
addChild(Item * child)2990 void WriteInitialization::Item::addChild(Item *child)
2991 {
2992 m_children << child;
2993 child->m_parent = this;
2994
2995 Item *c = child;
2996 Item *p = this;
2997 while (p) {
2998 p->m_setupUiData.directives |= c->m_setupUiData.directives;
2999 p->m_retranslateUiData.directives |= c->m_retranslateUiData.directives;
3000 if (p->m_setupUiData.policy < c->m_setupUiData.policy)
3001 p->m_setupUiData.policy = c->m_setupUiData.policy;
3002 if (p->m_retranslateUiData.policy < c->m_retranslateUiData.policy)
3003 p->m_retranslateUiData.policy = c->m_retranslateUiData.policy;
3004 c = p;
3005 p = p->m_parent;
3006 }
3007 }
3008
3009
3010 } // namespace CPP
3011
3012 QT_END_NAMESPACE
3013