~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/tools/uic3/form.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

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