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

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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