source: trunk/src/tools/uic3/form.cpp@ 1031

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

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

File size: 36.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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 [email protected].
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)
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 (m_options & CustomWidgetForwardDeclarations)
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(QLatin1Char(';')))
249 fd += QLatin1Char(';');
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().limitXPM_LineLength = (m_options & LimitXPM_LineLength) ? 1 : 0;
260 d.option().qrcOutputFile = m_qrcOutputFile;
261 d.option().implicitIncludes = (m_options & ImplicitIncludes) ? 1 : 0;
262 if (trmacro.size())
263 d.option().translateFunction = trmacro;
264 DomUI *ui = generateUi4(e);
265 d.uic(fileName, ui, &out);
266 delete ui;
267
268 createWrapperDeclContents(e);
269
270 out << "#endif // " << protector << endl;
271}
272
273void Ui3Reader::createWrapperDecl(const QDomElement &e, const QString &convertedUiFile)
274{
275 QString objName = getObjectName(e);
276
277 objName = registerObject(objName);
278 QString protector = objName.toUpper() + QLatin1String("_H");
279 protector.replace(QLatin1String("::"), QLatin1String("_"));
280 out << "#ifndef " << protector << endl;
281 out << "#define " << protector << endl;
282 out << endl;
283 out << "#include \"" << convertedUiFile << '\"' << endl;
284
285 createWrapperDeclContents(e);
286 out << endl;
287 out << "#endif // " << protector << endl;
288}
289
290void Ui3Reader::createWrapperDeclContents(const QDomElement &e)
291{
292 QString objClass = getClassName(e);
293 if (objClass.isEmpty())
294 return;
295
296 QDomNodeList nl;
297 QString exportMacro;
298 int i;
299 QDomElement n;
300 QStringList::ConstIterator it;
301 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("exportmacro"));
302 if (nl.length() == 1)
303 exportMacro = nl.item(0).firstChild().toText().data();
304
305 QStringList::ConstIterator ns = namespaces.constBegin();
306 while (ns != namespaces.constEnd()) {
307 out << "namespace " << *ns << " {" << endl;
308 ++ns;
309 }
310
311 out << "class ";
312 if (!exportMacro.isEmpty())
313 out << exportMacro << ' ';
314 out << bareNameOfClass << " : public " << objClass << ", public Ui::" << bareNameOfClass << endl << '{' << endl;
315
316 /* qmake ignore Q_OBJECT */
317 out << " Q_OBJECT" << endl;
318 out << endl;
319 out << "public:" << endl;
320
321 // constructor
322 if (objClass == QLatin1String("QDialog") || objClass == QLatin1String("QWizard")) {
323 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0, bool modal = false, Qt::WindowFlags fl = 0);" << endl;
324 } else if (objClass == QLatin1String("QWidget")) {
325 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0, Qt::WindowFlags fl = 0);" << endl;
326 } else if (objClass == QLatin1String("QMainWindow") || objClass == QLatin1String("Q3MainWindow")) {
327 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0, Qt::WindowFlags fl = Qt::WType_TopLevel);" << endl;
328 isMainWindow = true;
329 } else {
330 out << " " << bareNameOfClass << "(QWidget* parent = 0, const char* name = 0);" << endl;
331 }
332
333 // destructor
334 out << " ~" << bareNameOfClass << "();" << endl;
335 out << endl;
336
337 // database connections
338 dbConnections = unique(dbConnections);
339 bool hadOutput = false;
340 for (it = dbConnections.constBegin(); it != dbConnections.constEnd(); ++it) {
341 if (!(*it).isEmpty()) {
342 // only need pointers to non-default connections
343 if ((*it) != QLatin1String("(default)") && !(*it).isEmpty()) {
344 out << indent << "QSqlDatabase* " << *it << "Connection;" << endl;
345 hadOutput = true;
346 }
347 }
348 }
349 if (hadOutput)
350 out << endl;
351
352 QStringList publicSlots, protectedSlots, privateSlots;
353 QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes;
354 QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier;
355
356 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("slot"));
357 for (i = 0; i < (int) nl.length(); i++) {
358 n = nl.item(i).toElement();
359 if (n.parentNode().toElement().tagName() != QLatin1String("slots")
360 && n.parentNode().toElement().tagName() != QLatin1String("connections"))
361 continue;
362 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
363 continue;
364 QString returnType = n.attribute(QLatin1String("returnType"), QLatin1String("void"));
365 QString functionName = n.firstChild().toText().data().trimmed();
366 if (functionName.endsWith(QLatin1Char(';')))
367 functionName.chop(1);
368 QString specifier = n.attribute(QLatin1String("specifier"));
369 QString access = n.attribute(QLatin1String("access"));
370 if (access == QLatin1String(QLatin1String("protected"))) {
371 protectedSlots += functionName;
372 protectedSlotTypes += returnType;
373 protectedSlotSpecifier += specifier;
374 } else if (access == QLatin1String("private")) {
375 privateSlots += functionName;
376 privateSlotTypes += returnType;
377 privateSlotSpecifier += specifier;
378 } else {
379 publicSlots += functionName;
380 publicSlotTypes += returnType;
381 publicSlotSpecifier += specifier;
382 }
383 }
384
385 QStringList publicFuncts, protectedFuncts, privateFuncts;
386 QStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp;
387 QStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec;
388
389 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("function"));
390 for (i = 0; i < (int) nl.length(); i++) {
391 n = nl.item(i).toElement();
392 if (n.parentNode().toElement().tagName() != QLatin1String("functions"))
393 continue;
394 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
395 continue;
396 QString returnType = n.attribute(QLatin1String("returnType"), QLatin1String("void"));
397 QString functionName = n.firstChild().toText().data().trimmed();
398 if (functionName.endsWith(QLatin1Char(';')))
399 functionName.chop(1);
400 QString specifier = n.attribute(QLatin1String("specifier"));
401 QString access = n.attribute(QLatin1String("access"));
402 if (access == QLatin1String("protected")) {
403 protectedFuncts += functionName;
404 protectedFunctRetTyp += returnType;
405 protectedFunctSpec += specifier;
406 } else if (access == QLatin1String("private")) {
407 privateFuncts += functionName;
408 privateFunctRetTyp += returnType;
409 privateFunctSpec += specifier;
410 } else {
411 publicFuncts += functionName;
412 publicFunctRetTyp += returnType;
413 publicFunctSpec += specifier;
414 }
415 }
416
417 QStringList publicVars, protectedVars, privateVars;
418 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("variable"));
419 for (i = 0; i < (int)nl.length(); i++) {
420 n = nl.item(i).toElement();
421 // Because of compatibility the next lines have to be commented out.
422 // Someday it should be uncommented.
423 //if (n.parentNode().toElement().tagName() != QLatin1String("variables"))
424 // continue;
425 QString access = n.attribute(QLatin1String("access"), QLatin1String("protected"));
426 QString var = fixDeclaration(n.firstChild().toText().data().trimmed());
427 if (!var.endsWith(QLatin1Char(';')))
428 var += QLatin1Char(';');
429 if (access == QLatin1String("public"))
430 publicVars += var;
431 else if (access == QLatin1String("private"))
432 privateVars += var;
433 else
434 protectedVars += var;
435 }
436
437 if (!publicVars.isEmpty()) {
438 for (it = publicVars.constBegin(); it != publicVars.constEnd(); ++it)
439 out << indent << *it << endl;
440 out << endl;
441 }
442 if (!publicFuncts.isEmpty())
443 writeFunctionsDecl(publicFuncts, publicFunctRetTyp, publicFunctSpec);
444
445 if (!publicSlots.isEmpty()) {
446 out << "public slots:" << endl;
447 if (!publicSlots.isEmpty())
448 writeFunctionsDecl(publicSlots, publicSlotTypes, publicSlotSpecifier);
449 }
450
451 // find signals
452 QStringList extraSignals;
453 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("signal"));
454 for (i = 0; i < (int) nl.length(); i++) {
455 n = nl.item(i).toElement();
456 if (n.parentNode().toElement().tagName() != QLatin1String("signals")
457 && n.parentNode().toElement().tagName() != QLatin1String("connections"))
458 continue;
459 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
460 continue;
461 QString sigName = n.firstChild().toText().data().trimmed();
462 if (sigName.endsWith(QLatin1Char(';')))
463 sigName = sigName.left(sigName.length() - 1);
464 extraSignals += fixDeclaration(sigName);
465 }
466
467 // create signals
468 if (!extraSignals.isEmpty()) {
469 out << "signals:" << endl;
470 for (it = extraSignals.constBegin(); it != extraSignals.constEnd(); ++it)
471 out << " void " << (*it) << ';' << endl;
472 out << endl;
473 }
474
475 if (!protectedVars.isEmpty()) {
476 out << "protected:" << endl;
477 for (it = protectedVars.constBegin(); it != protectedVars.constEnd(); ++it)
478 out << indent << *it << endl;
479 out << endl;
480 }
481
482 if (!protectedFuncts.isEmpty()) {
483 if (protectedVars.isEmpty())
484 out << "protected:" << endl;
485
486 writeFunctionsDecl(protectedFuncts, protectedFunctRetTyp, protectedFunctSpec);
487 }
488
489 out << "protected slots:" << endl;
490 out << " virtual void languageChange();" << endl;
491
492 if (!protectedSlots.isEmpty()) {
493 out << endl;
494 writeFunctionsDecl(protectedSlots, protectedSlotTypes, protectedSlotSpecifier);
495 }
496 out << endl;
497
498 // create all private stuff
499 if (!privateFuncts.isEmpty() || !privateVars.isEmpty()) {
500 out << "private:" << endl;
501 if (!privateVars.isEmpty()) {
502 for (it = privateVars.constBegin(); it != privateVars.constEnd(); ++it)
503 out << indent << *it << endl;
504 out << endl;
505 }
506 if (!privateFuncts.isEmpty())
507 writeFunctionsDecl(privateFuncts, privateFunctRetTyp, privateFunctSpec);
508 }
509
510 if (!privateSlots.isEmpty()) {
511 out << "private slots:" << endl;
512 writeFunctionsDecl(privateSlots, privateSlotTypes, privateSlotSpecifier);
513 }
514
515 out << "};" << endl;
516 for (i = 0; i < (int) namespaces.count(); i++)
517 out << '}' << endl;
518
519 out << endl;
520}
521
522void Ui3Reader::writeFunctionsDecl(const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst)
523{
524 QStringList::ConstIterator it, it2, it3;
525 for (it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin();
526 it != fuLst.end(); ++it, ++it2, ++it3) {
527 QString signature = *it;
528 QString specifier;
529 QString pure;
530 QString type = *it2;
531 if (type.isEmpty())
532 type = QLatin1String("void");
533 if (*it3 == QLatin1String("static")) {
534 specifier = QLatin1String("static ");
535 } else {
536 if (*it3 != QLatin1String("non virtual") && *it3 != QLatin1String("nonVirtual"))
537 specifier = QLatin1String("virtual ");
538 if (*it3 == QLatin1String("pure virtual") || *it3 == QLatin1String("pureVirtual"))
539 pure = QLatin1String(" = 0");
540 }
541 type.replace(QLatin1String(">>"), QLatin1String("> >"));
542 if (!signature.contains(QLatin1String("operator")))
543 signature.replace(QLatin1String(">>"), QLatin1String("> >"));
544
545 signature = fixDeclaration(signature);
546 type = fixType(type);
547 out << " " << specifier << type << ' ' << signature << pure << ';' << endl;
548 }
549 out << endl;
550}
551
552/*!
553 Creates an implementation (cpp-file) for the form given in \a e.
554
555 \sa createFormDecl(), createObjectImpl()
556 */
557void Ui3Reader::createFormImpl(const QDomElement &e)
558{
559 QDomElement n;
560 QDomNodeList nl;
561 int i;
562 QString objClass = getClassName(e);
563 if (objClass.isEmpty())
564 return;
565 QString objName = getObjectName(e);
566
567 // generate local and local includes required
568 QStringList globalIncludes, localIncludes;
569 QStringList::Iterator it;
570
571 QMap<QString, CustomInclude> customWidgetIncludes;
572
573 // find additional slots and functions
574 QStringList extraFuncts;
575 QStringList extraFunctTyp;
576 QStringList extraFunctSpecifier;
577
578 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("slot"));
579 for (i = 0; i < (int) nl.length(); i++) {
580 n = nl.item(i).toElement();
581 if (n.parentNode().toElement().tagName() != QLatin1String("slots")
582 && n.parentNode().toElement().tagName() != QLatin1String("connections"))
583 continue;
584 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
585 continue;
586 QString functionName = n.firstChild().toText().data().trimmed();
587 if (functionName.endsWith(QLatin1Char(';')))
588 functionName.chop(1);
589 extraFuncts += functionName;
590 extraFunctTyp += n.attribute(QLatin1String("returnType"), QLatin1String("void"));
591 extraFunctSpecifier += n.attribute(QLatin1String("specifier"), QLatin1String("virtual"));
592 }
593
594 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("function"));
595 for (i = 0; i < (int) nl.length(); i++) {
596 n = nl.item(i).toElement();
597 if (n.parentNode().toElement().tagName() != QLatin1String("functions"))
598 continue;
599 if (n.attribute(QLatin1String("language"), QLatin1String("C++")) != QLatin1String("C++"))
600 continue;
601 QString functionName = n.firstChild().toText().data().trimmed();
602 if (functionName.endsWith(QLatin1Char(';')))
603 functionName.chop(1);
604 extraFuncts += functionName;
605 extraFunctTyp += n.attribute(QLatin1String("returnType"), QLatin1String("void"));
606 extraFunctSpecifier += n.attribute(QLatin1String("specifier"), QLatin1String("virtual"));
607 }
608
609 // additional includes (local or global) and forward declaractions
610 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("include"));
611 for (i = 0; i < (int) nl.length(); i++) {
612 QDomElement n2 = nl.item(i).toElement();
613 QString s = n2.firstChild().toText().data();
614 if (n2.attribute(QLatin1String("location")) != QLatin1String("local")) {
615 if (s.right(5) == QLatin1String(".ui.h") && !QFile::exists(s))
616 continue;
617 if (n2.attribute(QLatin1String("impldecl"), QLatin1String("in implementation")) != QLatin1String("in implementation"))
618 continue;
619 globalIncludes += s;
620 }
621 }
622
623 registerDatabases(e);
624 dbConnections = unique(dbConnections);
625 bool dbForm = false;
626 if (dbForms[QLatin1String("(default)")].count())
627 dbForm = true;
628 bool subDbForms = false;
629 for (it = dbConnections.begin(); it != dbConnections.end(); ++it) {
630 if (!(*it).isEmpty() && (*it) != QLatin1String("(default)")) {
631 if (dbForms[(*it)].count()) {
632 subDbForms = true;
633 break;
634 }
635 }
636 }
637
638 // do the local includes afterwards, since global includes have priority on clashes
639 for (i = 0; i < (int) nl.length(); i++) {
640 QDomElement n2 = nl.item(i).toElement();
641 QString s = n2.firstChild().toText().data();
642 if (n2.attribute(QLatin1String("location")) == QLatin1String("local") && !globalIncludes.contains(s)) {
643 if (s.right(5) == QLatin1String(".ui.h") && !QFile::exists(s))
644 continue;
645 if (n2.attribute(QLatin1String("impldecl"), QLatin1String("in implementation")) != QLatin1String("in implementation"))
646 continue;
647 localIncludes += s;
648 }
649 }
650
651 // additional custom widget headers
652 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("header"));
653 for (i = 0; i < (int) nl.length(); i++) {
654 QDomElement n2 = nl.item(i).toElement();
655 QString s = n2.firstChild().toText().data();
656 if (n2.attribute(QLatin1String("location")) != QLatin1String("local"))
657 globalIncludes += s;
658 else
659 localIncludes += s;
660 }
661
662 out << "#include <qvariant.h>" << endl; // first for gcc 2.7.2
663
664 globalIncludes = unique(globalIncludes);
665 for (it = globalIncludes.begin(); it != globalIncludes.end(); ++it) {
666 if (!(*it).isEmpty())
667 out << "#include <" << fixHeaderName(*it) << '>' << endl;
668 }
669
670 if (externPixmaps) {
671 out << "#include <qimage.h>" << endl;
672 out << "#include <qpixmap.h>" << endl << endl;
673 }
674
675 /*
676 Put local includes after all global includes
677 */
678 localIncludes = unique(localIncludes);
679 for (it = localIncludes.begin(); it != localIncludes.end(); ++it) {
680 if (!(*it).isEmpty() && *it != QFileInfo(fileName + QLatin1String(".h")).fileName())
681 out << "#include \"" << fixHeaderName(*it) << '\"' << endl;
682 }
683
684 QString uiDotH = fileName + QLatin1String(".h");
685 if (QFile::exists(uiDotH)) {
686 if (!outputFileName.isEmpty())
687 uiDotH = QString::fromUtf8(combinePath(uiDotH.ascii(), outputFileName.ascii()));
688 out << "#include \"" << uiDotH << '\"' << endl;
689 writeFunctImpl = false;
690 }
691
692 // register the object and unify its name
693 objName = registerObject(objName);
694
695 if (externPixmaps) {
696 pixmapLoaderFunction = QLatin1String("QPixmap::fromMimeSource");
697 }
698
699 // constructor
700 if (objClass == QLatin1String("QDialog") || objClass == QLatin1String("QWizard")) {
701 out << "/*" << endl;
702 out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl;
703 out << " * name 'name' and widget flags set to 'f'." << endl;
704 out << " *" << endl;
705 out << " * The " << objClass.mid(1).toLower() << " will by default be modeless, unless you set 'modal' to" << endl;
706 out << " * true to construct a modal " << objClass.mid(1).toLower() << '.' << endl;
707 out << " */" << endl;
708 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name, bool modal, Qt::WindowFlags fl)" << endl;
709 out << " : " << objClass << "(parent, name, modal, fl)";
710 } else if (objClass == QLatin1String("QWidget")) {
711 out << "/*" << endl;
712 out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl;
713 out << " * name 'name' and widget flags set to 'f'." << endl;
714 out << " */" << endl;
715 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name, Qt::WindowFlags fl)" << endl;
716 out << " : " << objClass << "(parent, name, fl)";
717 } else if (objClass == QLatin1String("QMainWindow") || objClass == QLatin1String("Q3MainWindow")) {
718 out << "/*" << endl;
719 out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl;
720 out << " * name 'name' and widget flags set to 'f'." << endl;
721 out << " *" << endl;
722 out << " */" << endl;
723 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name, Qt::WindowFlags fl)" << endl;
724 out << " : " << objClass << "(parent, name, fl)";
725 isMainWindow = true;
726 } else {
727 out << "/*" << endl;
728 out << " * Constructs a " << nameOfClass << " which is a child of 'parent', with the" << endl;
729 out << " * name 'name'.' " << endl;
730 out << " */" << endl;
731 out << nameOfClass << "::" << bareNameOfClass << "(QWidget* parent, const char* name)" << endl;
732 out << " : " << objClass << "(parent, name)";
733 }
734
735 out << endl;
736
737 out << '{' << endl;
738
739//
740// setup the gui
741//
742 out << indent << "setupUi(this);" << endl << endl;
743
744
745 if (isMainWindow)
746 out << indent << "(void)statusBar();" << endl;
747
748 // database support
749 dbConnections = unique(dbConnections);
750 if (dbConnections.count())
751 out << endl;
752 for (it = dbConnections.begin(); it != dbConnections.end(); ++it) {
753 if (!(*it).isEmpty() && (*it) != QLatin1String("(default)")) {
754 out << indent << (*it) << "Connection = QSqlDatabase::database(\"" <<(*it) << "\");" << endl;
755 }
756 }
757
758 nl = e.parentNode().toElement().elementsByTagName(QLatin1String("widget"));
759 for (i = 1; i < (int) nl.length(); i++) { // start at 1, 0 is the toplevel widget
760 n = nl.item(i).toElement();
761 QString s = getClassName(n);
762 if ((dbForm || subDbForms) && (s == QLatin1String("QDataBrowser") || s == QLatin1String("QDataView"))) {
763 QString objName = getObjectName(n);
764 QString tab = getDatabaseInfo(n, QLatin1String("table"));
765 QString con = getDatabaseInfo(n, QLatin1String("connection"));
766 out << indent << "QSqlForm* " << objName << "Form = new QSqlForm(this);" << endl;
767 out << indent << objName << "Form->setObjectName(\"" << objName << "Form\");" << endl;
768 QDomElement n2;
769 for (n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement())
770 createFormImpl(n2, objName, con, tab);
771 out << indent << objName << "->setForm(" << objName << "Form);" << endl;
772 }
773 }
774
775 if (extraFuncts.contains(QLatin1String("init()")))
776 out << indent << "init();" << endl;
777
778 // end of constructor
779 out << '}' << endl;
780 out << endl;
781
782 // destructor
783 out << "/*" << endl;
784 out << " * Destroys the object and frees any allocated resources" << endl;
785 out << " */" << endl;
786 out << nameOfClass << "::~" << bareNameOfClass << "()" << endl;
787 out << '{' << endl;
788 if (extraFuncts.contains(QLatin1String("destroy()")))
789 out << indent << "destroy();" << endl;
790 out << indent << "// no need to delete child widgets, Qt does it all for us" << endl;
791 out << '}' << endl;
792 out << endl;
793
794 // handle application events if required
795 bool needFontEventHandler = false;
796 bool needSqlTableEventHandler = false;
797 bool needSqlDataBrowserEventHandler = false;
798 nl = e.elementsByTagName(QLatin1String("widget"));
799 for (i = 0; i < (int) nl.length(); i++) {
800 if (!DomTool::propertiesOfType(nl.item(i).toElement() , QLatin1String("font")).isEmpty())
801 needFontEventHandler = true;
802 QString s = getClassName(nl.item(i).toElement());
803 if (s == QLatin1String("QDataTable") || s == QLatin1String("QDataBrowser")) {
804 if (!isFrameworkCodeGenerated(nl.item(i).toElement()))
805 continue;
806 if (s == QLatin1String("QDataTable"))
807 needSqlTableEventHandler = true;
808 if (s == QLatin1String("QDataBrowser"))
809 needSqlDataBrowserEventHandler = true;
810 }
811 if (needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler)
812 break;
813 }
814
815 out << "/*" << endl;
816 out << " * Sets the strings of the subwidgets using the current" << endl;
817 out << " * language." << endl;
818 out << " */" << endl;
819 out << "void " << nameOfClass << "::languageChange()" << endl;
820 out << '{' << endl;
821 out << " retranslateUi(this);" << endl;
822 out << '}' << endl;
823 out << endl;
824
825 // create stubs for additional slots if necessary
826 if (!extraFuncts.isEmpty() && writeFunctImpl) {
827 it = extraFuncts.begin();
828 QStringList::Iterator it2 = extraFunctTyp.begin();
829 QStringList::Iterator it3 = extraFunctSpecifier.begin();
830 while (it != extraFuncts.end()) {
831 QString type = fixDeclaration(*it2);
832 if (type.isEmpty())
833 type = QLatin1String("void");
834 type = type.simplified();
835 QString fname = fixDeclaration(Parser::cleanArgs(*it));
836 if (!(*it3).startsWith(QLatin1String("pure"))) { // "pure virtual" or "pureVirtual"
837 out << type << ' ' << nameOfClass << "::" << fname << endl;
838 out << '{' << endl;
839 if (*it != QLatin1String("init()") && *it != QLatin1String("destroy()")) {
840 QRegExp numeric(QLatin1String("^(?:signed|unsigned|u?char|u?short|u?int"
841 "|u?long|Q_U?INT(?:8|16|32)|Q_U?LONG|float"
842 "|double)$"));
843 QString retVal;
844
845 /*
846 We return some kind of dummy value to shut the
847 compiler up.
848
849 1. If the type is 'void', we return nothing.
850
851 2. If the type is 'bool', we return 'false'.
852
853 3. If the type is 'unsigned long' or
854 'quint16' or 'double' or similar, we
855 return '0'.
856
857 4. If the type is 'Foo *', we return '0'.
858
859 5. If the type is 'Foo &', we create a static
860 variable of type 'Foo' and return it.
861
862 6. If the type is 'Foo', we assume there's a
863 default constructor and use it.
864 */
865 if (type != QLatin1String("void")) {
866 QStringList toks = type.split(QLatin1String(" "));
867 bool isBasicNumericType =
868 (toks.filter(numeric).count() == toks.count());
869
870 if (type == QLatin1String("bool")) {
871 retVal = QLatin1String("false");
872 } else if (isBasicNumericType || type.endsWith(QLatin1Char('*'))) {
873 retVal = QLatin1String("0");
874 } else if (type.endsWith(QLatin1Char('&'))) {
875 do {
876 type.chop(1);
877 } while (type.endsWith(QLatin1Char(' ')));
878 retVal = QLatin1String("uic_temp_var");
879 out << indent << "static " << type << ' ' << retVal << ';' << endl;
880 } else {
881 retVal = type + QLatin1String("()");
882 }
883 }
884
885 out << indent << "qWarning(\"" << nameOfClass << "::" << fname << ": Not implemented yet\");" << endl;
886 if (!retVal.isEmpty())
887 out << indent << "return " << retVal << ';' << endl;
888 }
889 out << '}' << endl;
890 out << endl;
891 }
892 ++it;
893 ++it2;
894 ++it3;
895 }
896 }
897}
898
899
900/*! Creates form support implementation code for the widgets given
901 in \a e.
902
903 Traverses recursively over all children.
904 */
905
906void Ui3Reader::createFormImpl(const QDomElement& e, const QString& form, const QString& connection, const QString& table)
907{
908 if (e.tagName() == QLatin1String("widget")
909 && e.attribute(QLatin1String("class")) != QLatin1String("QDataTable")) {
910 QString field = getDatabaseInfo(e, QLatin1String("field"));
911 if (!field.isEmpty()) {
912 if (isWidgetInTable(e, connection, table))
913 out << indent << form << "Form->insert(" << getObjectName(e) << ", " << fixString(field) << ");" << endl;
914 }
915 }
916 QDomElement n;
917 for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
918 createFormImpl(n, form, connection, table);
919 }
920}
921
922QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.