source: branches/4.5.1/src/tools/uic3/form.cpp

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

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

File size: 36.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "ui3reader.h"
43#include "parser.h"
44#include "domtool.h"
45#include "globaldefs.h"
46
47// uic4
48#include "uic.h"
49#include "ui4.h"
50#include "driver.h"
51#include "option.h"
52
53#include <QStringList>
54#include <QFile>
55#include <QFileInfo>
56#include <QDir>
57#include <QRegExp>
58#include <QtDebug>
59
60QT_BEGIN_NAMESPACE
61
62QByteArray combinePath(const char *infile, const char *outfile)
63{
64 QFileInfo inFileInfo(QDir::current(), QFile::decodeName(infile));
65 QFileInfo outFileInfo(QDir::current(), QFile::decodeName(outfile));
66 int numCommonComponents = 0;
67
68 QStringList inSplitted = inFileInfo.dir().canonicalPath().split(QLatin1Char('/'));
69 QStringList outSplitted = outFileInfo.dir().canonicalPath().split(QLatin1Char('/'));
70
71 while (!inSplitted.isEmpty() && !outSplitted.isEmpty() &&
72 inSplitted.first() == outSplitted.first()) {
73 inSplitted.erase(inSplitted.begin());
74 outSplitted.erase(outSplitted.begin());
75 numCommonComponents++;
76 }
77
78 if (numCommonComponents < 2) {
79 /*
80 The paths don't have the same drive, or they don't have the
81 same root directory. Use an absolute path.
82 */
83 return QFile::encodeName(inFileInfo.absoluteFilePath());
84 } else {
85 /*
86 The paths have something in common. Use a path relative to
87 the output file.
88 */
89 while (!outSplitted.isEmpty()) {
90 outSplitted.erase(outSplitted.begin());
91 inSplitted.prepend(QLatin1String(".."));
92 }
93 inSplitted.append(inFileInfo.fileName());
94 return QFile::encodeName(inSplitted.join(QLatin1String("/")));
95 }
96}
97
98/*!
99 Creates a declaration (header file) for the form given in \a e
100
101 \sa createFormImpl()
102*/
103void Ui3Reader::createFormDecl(const QDomElement &e, bool implicitIncludes)
104{
105 QDomElement body = e;
106
107 QDomElement n;
108 QDomNodeList nl;
109 int i;
110 QString objClass = getClassName(e);
111 if (objClass.isEmpty())
112 return;
113 QString objName = getObjectName(e);
114
115 QStringList typeDefs;
116
117 QMap<QString, CustomInclude> customWidgetIncludes;
118
119 /*
120 We are generating a few QImage members that are not strictly
121 necessary in some cases. Ideally, we would use requiredImage,
122 which is computed elsewhere, to keep the generated .h and .cpp
123 files synchronized.
124 */
125
126 // at first the images
127 QMap<QString, int> customWidgets;
128 QStringList forwardDecl;
129 QStringList forwardDecl2;
130 for (n = e; !n.isNull(); n = n.nextSibling().toElement()) {
131 if (n.tagName().toLower() == QLatin1String("customwidgets")) {
132 QDomElement n2 = n.firstChild().toElement();
133 while (!n2.isNull()) {
134 if (n2.tagName().toLower() == QLatin1String("customwidget")) {
135 QDomElement n3 = n2.firstChild().toElement();
136 QString cl;
137 while (!n3.isNull()) {
138 QString tagName = n3.tagName().toLower();
139 if (tagName == QLatin1String("class")) {
140 cl = n3.firstChild().toText().data();
141 if (!nofwd)
142 forwardDecl << cl;
143 customWidgets.insert(cl, 0);
144 } else if (tagName == QLatin1String("header")) {
145 CustomInclude ci;
146 ci.header = n3.firstChild().toText().data();
147 ci.location = n3.attribute(QLatin1String("location"), QLatin1String("global"));
148 if (!ci.header.isEmpty())
149 forwardDecl.removeAll(cl);
150 customWidgetIncludes.insert(cl, ci);
151 }
152 n3 = n3.nextSibling().toElement();
153 }
154 }
155 n2 = n2.nextSibling().toElement();
156 }
157 }
158 }
159
160 // register the object and unify its name
161 objName = registerObject(objName);
162 QString protector = objName.toUpper() + QLatin1String("_H");
163 protector.replace(QLatin1String("::"), QLatin1String("_"));
164 out << "#ifndef " << protector << endl;
165 out << "#define " << protector << endl;
166 out << endl;
167
168 out << "#include <qvariant.h>" << endl; // for broken HP-UX compilers
169
170 QStringList globalIncludes, localIncludes;
171
172 {
173 QMap<QString, CustomInclude>::Iterator it = customWidgetIncludes.find(objClass);
174 if (it != customWidgetIncludes.end()) {
175 if ((*it).location == QLatin1String("global"))
176 globalIncludes += (*it).header;
177 else
178 localIncludes += (*it).header;
179 }
180 }
181
182 QStringList::ConstIterator it;
183
184 globalIncludes = unique(globalIncludes);
185 for (it = globalIncludes.constBegin(); it != globalIncludes.constEnd(); ++it) {
186 if (!(*it).isEmpty()) {
187 QString header = fixHeaderName(*it);
188 out << "#include <" << header << ">" << endl;
189 }
190 }
191 localIncludes = unique(localIncludes);
192 for (it = localIncludes.constBegin(); it != localIncludes.constEnd(); ++it) {
193 if (!(*it).isEmpty()) {
194 QString header = fixHeaderName(*it);
195 out << "#include \"" << header << "\"" << endl;
196 }
197 }
198 out << endl;
199
200 bool dbForm = false;
201 registerDatabases(e);
202 dbConnections = unique(dbConnections);
203 if (dbForms[QLatin1String("(default)")].count())
204 dbForm = true;
205 bool subDbForms = false;
206 for (it = dbConnections.constBegin(); it != dbConnections.constEnd(); ++it) {
207 if (!(*it).isEmpty() && (*it) != QLatin1String("(default)")) {
208 if (dbForms[(*it)].count()) {
209 subDbForms = true;
210 break;
211 }
212 }
213 }
214
215 // some typedefs, maybe
216 typeDefs = unique(typeDefs);
217 for (it = typeDefs.constBegin(); it != typeDefs.constEnd(); ++it) {
218 if (!(*it).isEmpty())
219 out << "typedef " << *it << ";" << endl;
220 }
221
222 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("forward"));
223 for (i = 0; i < (int) nl.length(); i++)
224 forwardDecl2 << fixDeclaration(nl.item(i).toElement().firstChild().toText().data());
225
226 forwardDecl = unique(forwardDecl);
227 for (it = forwardDecl.constBegin(); it != forwardDecl.constEnd(); ++it) {
228 if (!(*it).isEmpty() && (*it) != objClass) {
229 QString forwardName = *it;
230 QStringList forwardNamespaces = forwardName.split(QLatin1String("::"));
231 forwardName = forwardNamespaces.last();
232 forwardNamespaces.removeAt(forwardNamespaces.size()-1);
233
234 QStringList::ConstIterator ns = forwardNamespaces.constBegin();
235 while (ns != forwardNamespaces.constEnd()) {
236 out << "namespace " << *ns << " {" << endl;
237 ++ns;
238 }
239 out << "class " << forwardName << ";" << endl;
240 for (int i = 0; i < (int) forwardNamespaces.count(); i++)
241 out << "}" << endl;
242 }
243 }
244
245 for (it = forwardDecl2.constBegin(); it != forwardDecl2.constEnd(); ++it) {
246 QString fd = *it;
247 fd = fd.trimmed();
248 if (!fd.endsWith(QLatin1String(";")))
249 fd += QLatin1String(";");
250 out << fd << endl;
251 }
252
253 out << endl;
254
255 Driver d;
256 d.option().headerProtection = false;
257 d.option().copyrightHeader = false;
258 d.option().extractImages = m_extractImages;
259 d.option().qrcOutputFile = m_qrcOutputFile;
260 d.option().implicitIncludes = implicitIncludes;
261 if (trmacro.size())
262 d.option().translateFunction = trmacro;
263 DomUI *ui = generateUi4(e, implicitIncludes);
264 d.uic(fileName, ui, &out);
265 delete ui;
266
267 createWrapperDeclContents(e);
268
269 out << "#endif // " << protector << endl;
270}
271
272void Ui3Reader::createWrapperDecl(const QDomElement &e, const QString &convertedUiFile)
273{
274 QString objName = getObjectName(e);
275
276 objName = registerObject(objName);
277 QString protector = objName.toUpper() + QLatin1String("_H");
278 protector.replace(QLatin1String("::"), QLatin1String("_"));
279 out << "#ifndef " << protector << endl;
280 out << "#define " << protector << endl;
281 out << endl;
282 out << "#include \"" << convertedUiFile << "\"" << endl;
283
284 createWrapperDeclContents(e);
285 out << endl;
286 out << "#endif // " << protector << endl;
287}
288
289void Ui3Reader::createWrapperDeclContents(const QDomElement &e)
290{
291 QString objClass = getClassName(e);
292 if (objClass.isEmpty())
293 return;
294
295 QDomNodeList nl;
296 QString exportMacro;
297 int i;
298 QDomElement n;
299 QStringList::ConstIterator it;
300 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("exportmacro"));
301 if (nl.length() == 1)
302 exportMacro = nl.item(0).firstChild().toText().data();
303
304 QStringList::ConstIterator ns = namespaces.constBegin();
305 while (ns != namespaces.constEnd()) {
306 out << "namespace " << *ns << " {" << endl;
307 ++ns;
308 }
309
310 out << "class ";
311 if (!exportMacro.isEmpty())
312 out << exportMacro << " ";
313 out << bareNameOfClass << " : public " << objClass << ", public Ui::" << bareNameOfClass << endl << "{" << endl;
314
315 /* qmake ignore Q_OBJECT */
316 out << " Q_OBJECT" << endl;
317 out << endl;
318 out << "public:" << endl;
319
320 // constructor
321 if (objClass == QLatin1String("QDialog") || objClass == QLatin1String("QWizard")) {
322 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0, bool modal = false, Qt::WindowFlags fl = 0);" << endl;
323 } else if (objClass == QLatin1String("QWidget")) {
324 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0, Qt::WindowFlags fl = 0);" << endl;
325 } else if (objClass == QLatin1String("QMainWindow") || objClass == QLatin1String("Q3MainWindow")) {
326 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0, Qt::WindowFlags fl = Qt::WType_TopLevel);" << endl;
327 isMainWindow = true;
328 } else {
329 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0);" << endl;
330 }
331
332 // destructor
333 out << " ~" << bareNameOfClass << "();" << endl;
334 out << endl;
335
336 // database connections
337 dbConnections = unique(dbConnections);
338 bool hadOutput = false;
339 for (it = dbConnections.constBegin(); it != dbConnections.constEnd(); ++it) {
340 if (!(*it).isEmpty()) {
341 // only need pointers to non-default connections
342 if ((*it) != QLatin1String("(default)") && !(*it).isEmpty()) {
343 out << indent << "QSqlDatabase* " << *it << "Connection;" << endl;
344 hadOutput = true;
345 }
346 }
347 }
348 if (hadOutput)
349 out << endl;
350
351 QStringList publicSlots, protectedSlots, privateSlots;
352 QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes;
353 QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier;
354
355 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("slot"));
356 for (i = 0; i < (int) nl.length(); i++) {
357 n = nl.item(i).toElement();
358 if (n.parentNode().toElement().tagName() != QLatin1String("slots")
359 && n.parentNode().toElement().tagName() != QLatin1String("connections"))
360 continue;
361 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
362 continue;
363 QString returnType = n.attribute(QLatin1String("returnType"), QLatin1String("void"));
364 QString functionName = n.firstChild().toText().data().trimmed();
365 if (functionName.endsWith(QLatin1String(";")))
366 functionName = functionName.left(functionName.length() - 1);
367 QString specifier = n.attribute(QLatin1String("specifier"));
368 QString access = n.attribute(QLatin1String("access"));
369 if (access == QLatin1String(QLatin1String("protected"))) {
370 protectedSlots += functionName;
371 protectedSlotTypes += returnType;
372 protectedSlotSpecifier += specifier;
373 } else if (access == QLatin1String("private")) {
374 privateSlots += functionName;
375 privateSlotTypes += returnType;
376 privateSlotSpecifier += specifier;
377 } else {
378 publicSlots += functionName;
379 publicSlotTypes += returnType;
380 publicSlotSpecifier += specifier;
381 }
382 }
383
384 QStringList publicFuncts, protectedFuncts, privateFuncts;
385 QStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp;
386 QStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec;
387
388 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("function"));
389 for (i = 0; i < (int) nl.length(); i++) {
390 n = nl.item(i).toElement();
391 if (n.parentNode().toElement().tagName() != QLatin1String("functions"))
392 continue;
393 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
394 continue;
395 QString returnType = n.attribute(QLatin1String("returnType"), QLatin1String("void"));
396 QString functionName = n.firstChild().toText().data().trimmed();
397 if (functionName.endsWith(QLatin1String(";")))
398 functionName = functionName.left(functionName.length() - 1);
399 QString specifier = n.attribute(QLatin1String("specifier"));
400 QString access = n.attribute(QLatin1String("access"));
401 if (access == QLatin1String("protected")) {
402 protectedFuncts += functionName;
403 protectedFunctRetTyp += returnType;
404 protectedFunctSpec += specifier;
405 } else if (access == QLatin1String("private")) {
406 privateFuncts += functionName;
407 privateFunctRetTyp += returnType;
408 privateFunctSpec += specifier;
409 } else {
410 publicFuncts += functionName;
411 publicFunctRetTyp += returnType;
412 publicFunctSpec += specifier;
413 }
414 }
415
416 QStringList publicVars, protectedVars, privateVars;
417 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("variable"));
418 for (i = 0; i < (int)nl.length(); i++) {
419 n = nl.item(i).toElement();
420 // Because of compatibility the next lines have to be commented out.
421 // Someday it should be uncommented.
422 //if (n.parentNode().toElement().tagName() != QLatin1String("variables"))
423 // continue;
424 QString access = n.attribute(QLatin1String("access"), QLatin1String("protected"));
425 QString var = fixDeclaration(n.firstChild().toText().data().trimmed());
426 if (!var.endsWith(QLatin1String(";")))
427 var += QLatin1String(";");
428 if (access == QLatin1String("public"))
429 publicVars += var;
430 else if (access == QLatin1String("private"))
431 privateVars += var;
432 else
433 protectedVars += var;
434 }
435
436 if (!publicVars.isEmpty()) {
437 for (it = publicVars.constBegin(); it != publicVars.constEnd(); ++it)
438 out << indent << *it << endl;
439 out << endl;
440 }
441 if (!publicFuncts.isEmpty())
442 writeFunctionsDecl(publicFuncts, publicFunctRetTyp, publicFunctSpec);
443
444 if (!publicSlots.isEmpty()) {
445 out << "public slots:" << endl;
446 if (!publicSlots.isEmpty())
447 writeFunctionsDecl(publicSlots, publicSlotTypes, publicSlotSpecifier);
448 }
449
450 // find signals
451 QStringList extraSignals;
452 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("signal"));
453 for (i = 0; i < (int) nl.length(); i++) {
454 n = nl.item(i).toElement();
455 if (n.parentNode().toElement().tagName() != QLatin1String("signals")
456 && n.parentNode().toElement().tagName() != QLatin1String("connections"))
457 continue;
458 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
459 continue;
460 QString sigName = n.firstChild().toText().data().trimmed();
461 if (sigName.endsWith(QLatin1String(";")))
462 sigName = sigName.left(sigName.length() - 1);
463 extraSignals += fixDeclaration(sigName);
464 }
465
466 // create signals
467 if (!extraSignals.isEmpty()) {
468 out << "signals:" << endl;
469 for (it = extraSignals.constBegin(); it != extraSignals.constEnd(); ++it)
470 out << " void " << (*it) << ";" << endl;
471 out << endl;
472 }
473
474 if (!protectedVars.isEmpty()) {
475 out << "protected:" << endl;
476 for (it = protectedVars.constBegin(); it != protectedVars.constEnd(); ++it)
477 out << indent << *it << endl;
478 out << endl;
479 }
480
481 if (!protectedFuncts.isEmpty()) {
482 if (protectedVars.isEmpty())
483 out << "protected:" << endl;
484
485 writeFunctionsDecl(protectedFuncts, protectedFunctRetTyp, protectedFunctSpec);
486 }
487
488 out << "protected slots:" << endl;
489 out << " virtual void languageChange();" << endl;
490
491 if (!protectedSlots.isEmpty()) {
492 out << endl;
493 writeFunctionsDecl(protectedSlots, protectedSlotTypes, protectedSlotSpecifier);
494 }
495 out << endl;
496
497 // create all private stuff
498 if (!privateFuncts.isEmpty() || !privateVars.isEmpty()) {
499 out << "private:" << endl;
500 if (!privateVars.isEmpty()) {
501 for (it = privateVars.constBegin(); it != privateVars.constEnd(); ++it)
502 out << indent << *it << endl;
503 out << endl;
504 }
505 if (!privateFuncts.isEmpty())
506 writeFunctionsDecl(privateFuncts, privateFunctRetTyp, privateFunctSpec);
507 }
508
509 if (!privateSlots.isEmpty()) {
510 out << "private slots:" << endl;
511 writeFunctionsDecl(privateSlots, privateSlotTypes, privateSlotSpecifier);
512 }
513
514 out << "};" << endl;
515 for (i = 0; i < (int) namespaces.count(); i++)
516 out << "}" << endl;
517
518 out << endl;
519}
520
521void Ui3Reader::writeFunctionsDecl(const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst)
522{
523 QStringList::ConstIterator it, it2, it3;
524 for (it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin();
525 it != fuLst.end(); ++it, ++it2, ++it3) {
526 QString signature = *it;
527 QString specifier;
528 QString pure;
529 QString type = *it2;
530 if (type.isEmpty())
531 type = QLatin1String("void");
532 if (*it3 == QLatin1String("static")) {
533 specifier = QLatin1String("static ");
534 } else {
535 if (*it3 != QLatin1String("non virtual") && *it3 != QLatin1String("nonVirtual"))
536 specifier = QLatin1String("virtual ");
537 if (*it3 == QLatin1String("pure virtual") || *it3 == QLatin1String("pureVirtual"))
538 pure = QLatin1String(" = 0");
539 }
540 type.replace(QLatin1String(">>"), QLatin1String("> >"));
541 if (!signature.contains(QLatin1String("operator")))
542 signature.replace(QLatin1String(">>"), QLatin1String("> >"));
543
544 signature = fixDeclaration(signature);
545 type = fixType(type);
546 out << " " << specifier << type << " " << signature << pure << ";" << endl;
547 }
548 out << endl;
549}
550
551/*!
552 Creates an implementation (cpp-file) for the form given in \a e.
553
554 \sa createFormDecl(), createObjectImpl()
555 */
556void Ui3Reader::createFormImpl(const QDomElement &e)
557{
558 QDomElement n;
559 QDomNodeList nl;
560 int i;
561 QString objClass = getClassName(e);
562 if (objClass.isEmpty())
563 return;
564 QString objName = getObjectName(e);
565
566 // generate local and local includes required
567 QStringList globalIncludes, localIncludes;
568 QStringList::Iterator it;
569
570 QMap<QString, CustomInclude> customWidgetIncludes;
571
572 // find additional slots and functions
573 QStringList extraFuncts;
574 QStringList extraFunctTyp;
575 QStringList extraFunctSpecifier;
576
577 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("slot"));
578 for (i = 0; i < (int) nl.length(); i++) {
579 n = nl.item(i).toElement();
580 if (n.parentNode().toElement().tagName() != QLatin1String("slots")
581 && n.parentNode().toElement().tagName() != QLatin1String("connections"))
582 continue;
583 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
584 continue;
585 QString functionName = n.firstChild().toText().data().trimmed();
586 if (functionName.endsWith(QLatin1String(";")))
587 functionName = functionName.left(functionName.length() - 1);
588 extraFuncts += functionName;
589 extraFunctTyp += n.attribute(QLatin1String("returnType"), QLatin1String("void"));
590 extraFunctSpecifier += n.attribute(QLatin1String("specifier"), QLatin1String("virtual"));
591 }
592
593 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("function"));
594 for (i = 0; i < (int) nl.length(); i++) {
595 n = nl.item(i).toElement();
596 if (n.parentNode().toElement().tagName() != QLatin1String("functions"))
597 continue;
598 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
599 continue;
600 QString functionName = n.firstChild().toText().data().trimmed();
601 if (functionName.endsWith(QLatin1String(";")))
602 functionName = functionName.left(functionName.length() - 1);
603 extraFuncts += functionName;
604 extraFunctTyp += n.attribute(QLatin1String("returnType"), QLatin1String("void"));
605 extraFunctSpecifier += n.attribute(QLatin1String("specifier"), QLatin1String("virtual"));
606 }
607
608 // additional includes (local or global) and forward declaractions
609 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("include"));
610 for (i = 0; i < (int) nl.length(); i++) {
611 QDomElement n2 = nl.item(i).toElement();
612 QString s = n2.firstChild().toText().data();
613 if (n2.attribute(QLatin1String("location")) != QLatin1String("local")) {
614 if (s.right(5) == QLatin1String(".ui.h") && !QFile::exists(s))
615 continue;
616 if (n2.attribute(QLatin1String("impldecl"), QLatin1String("in implementation")) != QLatin1String("in implementation"))
617 continue;
618 globalIncludes += s;
619 }
620 }
621
622 registerDatabases(e);
623 dbConnections = unique(dbConnections);
624 bool dbForm = false;
625 if (dbForms[QLatin1String("(default)")].count())
626 dbForm = true;
627 bool subDbForms = false;
628 for (it = dbConnections.begin(); it != dbConnections.end(); ++it) {
629 if (!(*it).isEmpty() && (*it) != QLatin1String("(default)")) {
630 if (dbForms[(*it)].count()) {
631 subDbForms = true;
632 break;
633 }
634 }
635 }
636
637 // do the local includes afterwards, since global includes have priority on clashes
638 for (i = 0; i < (int) nl.length(); i++) {
639 QDomElement n2 = nl.item(i).toElement();
640 QString s = n2.firstChild().toText().data();
641 if (n2.attribute(QLatin1String("location")) == QLatin1String("local") && !globalIncludes.contains(s)) {
642 if (s.right(5) == QLatin1String(".ui.h") && !QFile::exists(s))
643 continue;
644 if (n2.attribute(QLatin1String("impldecl"), QLatin1String("in implementation")) != QLatin1String("in implementation"))
645 continue;
646 localIncludes += s;
647 }
648 }
649
650 // additional custom widget headers
651 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("header"));
652 for (i = 0; i < (int) nl.length(); i++) {
653 QDomElement n2 = nl.item(i).toElement();
654 QString s = n2.firstChild().toText().data();
655 if (n2.attribute(QLatin1String("location")) != QLatin1String("local"))
656 globalIncludes += s;
657 else
658 localIncludes += s;
659 }
660
661 out << "#include <qvariant.h>" << endl; // first for gcc 2.7.2
662
663 globalIncludes = unique(globalIncludes);
664 for (it = globalIncludes.begin(); it != globalIncludes.end(); ++it) {
665 if (!(*it).isEmpty())
666 out << "#include <" << fixHeaderName(*it) << ">" << endl;
667 }
668
669 if (externPixmaps) {
670 out << "#include <qimage.h>" << endl;
671 out << "#include <qpixmap.h>" << endl << endl;
672 }
673
674 /*
675 Put local includes after all global includes
676 */
677 localIncludes = unique(localIncludes);
678 for (it = localIncludes.begin(); it != localIncludes.end(); ++it) {
679 if (!(*it).isEmpty() && *it != QFileInfo(fileName + QLatin1String(".h")).fileName())
680 out << "#include \"" << fixHeaderName(*it) << "\"" << endl;
681 }
682
683 QString uiDotH = fileName + QLatin1String(".h");
684 if (QFile::exists(uiDotH)) {
685 if (!outputFileName.isEmpty())
686 uiDotH = QString::fromUtf8(combinePath(uiDotH.ascii(), outputFileName.ascii()));
687 out << "#include \"" << uiDotH << "\"" << endl;
688 writeFunctImpl = false;
689 }
690
691 // register the object and unify its name
692 objName = registerObject(objName);
693
694 if (externPixmaps) {
695 pixmapLoaderFunction = QLatin1String("QPixmap::fromMimeSource");
696 }
697
698 // constructor
699 if (objClass == QLatin1String("QDialog") || objClass == QLatin1String("QWizard")) {
700 out << "/*" << endl;
701 out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl;
702 out << " * name 'name' and widget flags set to 'f'." << endl;
703 out << " *" << endl;
704 out << " * The " << objClass.mid(1).toLower() << " will by default be modeless, unless you set 'modal' to" << endl;
705 out << " * true to construct a modal " << objClass.mid(1).toLower() << "." << endl;
706 out << " */" << endl;
707 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name, bool modal, Qt::WindowFlags fl)" << endl;
708 out << " : " << objClass << "(parent, name, modal, fl)";
709 } else if (objClass == QLatin1String("QWidget")) {
710 out << "/*" << endl;
711 out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl;
712 out << " * name 'name' and widget flags set to 'f'." << endl;
713 out << " */" << endl;
714 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name, Qt::WindowFlags fl)" << endl;
715 out << " : " << objClass << "(parent, name, fl)";
716 } else if (objClass == QLatin1String("QMainWindow") || objClass == QLatin1String("Q3MainWindow")) {
717 out << "/*" << endl;
718 out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl;
719 out << " * name 'name' and widget flags set to 'f'." << endl;
720 out << " *" << endl;
721 out << " */" << endl;
722 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name, Qt::WindowFlags fl)" << endl;
723 out << " : " << objClass << "(parent, name, fl)";
724 isMainWindow = true;
725 } else {
726 out << "/*" << endl;
727 out << " * Constructs a " << nameOfClass << " which is a child of 'parent', with the" << endl;
728 out << " * name 'name'.' " << endl;
729 out << " */" << endl;
730 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name)" << endl;
731 out << " : " << objClass << "(parent, name)";
732 }
733
734 out << endl;
735
736 out << "{" << endl;
737
738//
739// setup the gui
740//
741 out << indent << "setupUi(this);" << endl << endl;
742
743
744 if (isMainWindow)
745 out << indent << "(void)statusBar();" << endl;
746
747 // database support
748 dbConnections = unique(dbConnections);
749 if (dbConnections.count())
750 out << endl;
751 for (it = dbConnections.begin(); it != dbConnections.end(); ++it) {
752 if (!(*it).isEmpty() && (*it) != QLatin1String("(default)")) {
753 out << indent << (*it) << "Connection = QSqlDatabase::database(\"" <<(*it) << "\");" << endl;
754 }
755 }
756
757 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("widget"));
758 for (i = 1; i < (int) nl.length(); i++) { // start at 1, 0 is the toplevel widget
759 n = nl.item(i).toElement();
760 QString s = getClassName(n);
761 if ((dbForm || subDbForms) && (s == QLatin1String("QDataBrowser") || s == QLatin1String("QDataView"))) {
762 QString objName = getObjectName(n);
763 QString tab = getDatabaseInfo(n, QLatin1String("table"));
764 QString con = getDatabaseInfo(n, QLatin1String("connection"));
765 out << indent << "QSqlForm* " << objName << "Form = new QSqlForm(this);" << endl;
766 out << indent << objName << "Form->setObjectName(\"" << objName << "Form\");" << endl;
767 QDomElement n2;
768 for (n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement())
769 createFormImpl(n2, objName, con, tab);
770 out << indent << objName << "->setForm(" << objName << "Form);" << endl;
771 }
772 }
773
774 if (extraFuncts.contains(QLatin1String("init()")))
775 out << indent << "init();" << endl;
776
777 // end of constructor
778 out << "}" << endl;
779 out << endl;
780
781 // destructor
782 out << "/*" << endl;
783 out << " * Destroys the object and frees any allocated resources" << endl;
784 out << " */" << endl;
785 out << nameOfClass << "::~" << bareNameOfClass << "()" << endl;
786 out << "{" << endl;
787 if (extraFuncts.contains(QLatin1String("destroy()")))
788 out << indent << "destroy();" << endl;
789 out << indent << "// no need to delete child widgets, Qt does it all for us" << endl;
790 out << "}" << endl;
791 out << endl;
792
793 // handle application events if required
794 bool needFontEventHandler = false;
795 bool needSqlTableEventHandler = false;
796 bool needSqlDataBrowserEventHandler = false;
797 nl = e.elementsByTagName(QLatin1String("widget"));
798 for (i = 0; i < (int) nl.length(); i++) {
799 if (!DomTool::propertiesOfType(nl.item(i).toElement() , QLatin1String("font")).isEmpty())
800 needFontEventHandler = true;
801 QString s = getClassName(nl.item(i).toElement());
802 if (s == QLatin1String("QDataTable") || s == QLatin1String("QDataBrowser")) {
803 if (!isFrameworkCodeGenerated(nl.item(i).toElement()))
804 continue;
805 if (s == QLatin1String("QDataTable"))
806 needSqlTableEventHandler = true;
807 if (s == QLatin1String("QDataBrowser"))
808 needSqlDataBrowserEventHandler = true;
809 }
810 if (needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler)
811 break;
812 }
813
814 out << "/*" << endl;
815 out << " * Sets the strings of the subwidgets using the current" << endl;
816 out << " * language." << endl;
817 out << " */" << endl;
818 out << "void " << nameOfClass << "::languageChange()" << endl;
819 out << "{" << endl;
820 out << " retranslateUi(this);" << endl;
821 out << "}" << endl;
822 out << endl;
823
824 // create stubs for additional slots if necessary
825 if (!extraFuncts.isEmpty() && writeFunctImpl) {
826 it = extraFuncts.begin();
827 QStringList::Iterator it2 = extraFunctTyp.begin();
828 QStringList::Iterator it3 = extraFunctSpecifier.begin();
829 while (it != extraFuncts.end()) {
830 QString type = fixDeclaration(*it2);
831 if (type.isEmpty())
832 type = QLatin1String("void");
833 type = type.simplified();
834 QString fname = fixDeclaration(Parser::cleanArgs(*it));
835 if (!(*it3).startsWith(QLatin1String("pure"))) { // "pure virtual" or "pureVirtual"
836 out << type << " " << nameOfClass << "::" << fname << endl;
837 out << "{" << endl;
838 if (*it != QLatin1String("init()") && *it != QLatin1String("destroy()")) {
839 QRegExp numeric(QLatin1String("^(?:signed|unsigned|u?char|u?short|u?int"
840 "|u?long|Q_U?INT(?:8|16|32)|Q_U?LONG|float"
841 "|double)$"));
842 QString retVal;
843
844 /*
845 We return some kind of dummy value to shut the
846 compiler up.
847
848 1. If the type is 'void', we return nothing.
849
850 2. If the type is 'bool', we return 'false'.
851
852 3. If the type is 'unsigned long' or
853 'quint16' or 'double' or similar, we
854 return '0'.
855
856 4. If the type is 'Foo *', we return '0'.
857
858 5. If the type is 'Foo &', we create a static
859 variable of type 'Foo' and return it.
860
861 6. If the type is 'Foo', we assume there's a
862 default constructor and use it.
863 */
864 if (type != QLatin1String("void")) {
865 QStringList toks = type.split(QLatin1String(" "));
866 bool isBasicNumericType =
867 (toks.filter(numeric).count() == toks.count());
868
869 if (type == QLatin1String("bool")) {
870 retVal = QLatin1String("false");
871 } else if (isBasicNumericType || type.endsWith(QLatin1String("*"))) {
872 retVal = QLatin1String("0");
873 } else if (type.endsWith(QLatin1String("&"))) {
874 do {
875 type.chop(1);
876 } while (type.endsWith(QLatin1String(" ")));
877 retVal = QLatin1String("uic_temp_var");
878 out << indent << "static " << type << " " << retVal << ";" << endl;
879 } else {
880 retVal = type + QLatin1String("()");
881 }
882 }
883
884 out << indent << "qWarning(\"" << nameOfClass << "::" << fname << ": Not implemented yet\");" << endl;
885 if (!retVal.isEmpty())
886 out << indent << "return " << retVal << ";" << endl;
887 }
888 out << "}" << endl;
889 out << endl;
890 }
891 ++it;
892 ++it2;
893 ++it3;
894 }
895 }
896}
897
898
899/*! Creates form support implementation code for the widgets given
900 in \a e.
901
902 Traverses recursively over all children.
903 */
904
905void Ui3Reader::createFormImpl(const QDomElement& e, const QString& form, const QString& connection, const QString& table)
906{
907 if (e.tagName() == QLatin1String("widget")
908 && e.attribute(QLatin1String("class")) != QLatin1String("QDataTable")) {
909 QString field = getDatabaseInfo(e, QLatin1String("field"));
910 if (!field.isEmpty()) {
911 if (isWidgetInTable(e, connection, table))
912 out << indent << form << "Form->insert(" << getObjectName(e) << ", " << fixString(field) << ");" << endl;
913 }
914 }
915 QDomElement n;
916 for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
917 createFormImpl(n, form, connection, table);
918 }
919}
920
921QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.