source: trunk/src/tools/uic/cpp/cppwriteinitialization.cpp@ 477

Last change on this file since 477 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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