source: trunk/src/tools/uic/uic.cpp@ 160

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

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

File size: 11.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "uic.h"
43#include "ui4.h"
44#include "driver.h"
45#include "option.h"
46#include "treewalker.h"
47#include "validator.h"
48
49#ifdef QT_UIC_CPP_GENERATOR
50#include "cppwriteincludes.h"
51#include "cppwritedeclaration.h"
52#endif
53
54#ifdef QT_UIC_JAVA_GENERATOR
55#include "javawriteincludes.h"
56#include "javawritedeclaration.h"
57#endif
58
59#include <QtCore/QXmlStreamReader>
60#include <QtCore/QFileInfo>
61#include <QtCore/QRegExp>
62#include <QtCore/QTextStream>
63#include <QtCore/QDateTime>
64
65#if defined Q_WS_WIN
66#include <qt_windows.h>
67#endif
68
69QT_BEGIN_NAMESPACE
70
71Uic::Uic(Driver *d)
72 : drv(d),
73 out(d->output()),
74 opt(d->option()),
75 info(d),
76 externalPix(true)
77{
78}
79
80Uic::~Uic()
81{
82}
83
84bool Uic::printDependencies()
85{
86 QString fileName = opt.inputFile;
87
88 QFile f;
89 if (fileName.isEmpty())
90 f.open(stdin, QIODevice::ReadOnly);
91 else {
92 f.setFileName(fileName);
93 if (!f.open(QIODevice::ReadOnly))
94 return false;
95 }
96
97 DomUI *ui = 0;
98 {
99 QXmlStreamReader reader;
100 reader.setDevice(&f);
101 ui = parseUiFile(reader);
102 if (!ui)
103 return false;
104 }
105
106 if (DomIncludes *includes = ui->elementIncludes()) {
107 foreach (DomInclude *incl, includes->elementInclude()) {
108 QString file = incl->text();
109 if (file.isEmpty())
110 continue;
111
112 fprintf(stdout, "%s\n", file.toLocal8Bit().constData());
113 }
114 }
115
116 if (DomCustomWidgets *customWidgets = ui->elementCustomWidgets()) {
117 foreach (DomCustomWidget *customWidget, customWidgets->elementCustomWidget()) {
118 if (DomHeader *header = customWidget->elementHeader()) {
119 QString file = header->text();
120 if (file.isEmpty())
121 continue;
122
123 fprintf(stdout, "%s\n", file.toLocal8Bit().constData());
124 }
125 }
126 }
127
128 delete ui;
129
130 return true;
131}
132
133void Uic::writeCopyrightHeader(DomUI *ui)
134{
135 QString comment = ui->elementComment();
136 if (comment.size())
137 out << "/*\n" << comment << "\n*/\n\n";
138
139 out << "/********************************************************************************\n";
140 out << "** Form generated from reading ui file '" << QFileInfo(opt.inputFile).fileName() << "'\n";
141 out << "**\n";
142 out << "** Created: " << QDateTime::currentDateTime().toString() << "\n";
143 out << "** " << QString::fromLatin1("by: Qt User Interface Compiler version %1\n").arg(QLatin1String(QT_VERSION_STR));
144 out << "**\n";
145 out << "** WARNING! All changes made in this file will be lost when recompiling ui file!\n";
146 out << "********************************************************************************/\n\n";
147}
148
149// Check the version with a stream reader at the <ui> element.
150
151static double versionFromUiAttribute(QXmlStreamReader &reader)
152{
153 const QXmlStreamAttributes attributes = reader.attributes();
154 const QString versionAttribute = QLatin1String("version");
155 if (!attributes.hasAttribute(versionAttribute))
156 return 4.0;
157 const QString version = attributes.value(versionAttribute).toString();
158 return version.toDouble();
159}
160
161DomUI *Uic::parseUiFile(QXmlStreamReader &reader)
162{
163 DomUI *ui = 0;
164
165 const QString uiElement = QLatin1String("ui");
166 while (!reader.atEnd()) {
167 if (reader.readNext() == QXmlStreamReader::StartElement) {
168 if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0
169 && !ui) {
170 const double version = versionFromUiAttribute(reader);
171 if (version < 4.0) {
172 const QString msg = QString::fromLatin1("uic: File generated with too old version of Qt Designer (%1)").arg(version);
173 fprintf(stderr, "%s\n", qPrintable(msg));
174 return 0;
175 }
176
177 ui = new DomUI();
178 ui->read(reader);
179 } else {
180 reader.raiseError(QLatin1String("Unexpected element ") + reader.name().toString());
181 }
182 }
183 }
184 if (reader.hasError()) {
185 delete ui;
186 ui = 0;
187 fprintf(stderr, "uic: Error in line %llu, column %llu : %s\n",
188 reader.lineNumber(), reader.columnNumber(),
189 reader.errorString().toAscii().constData());
190 }
191
192 return ui;
193}
194
195bool Uic::write(QIODevice *in)
196{
197 if (option().generator == Option::JavaGenerator) {
198 // the Java generator ignores header protection
199 opt.headerProtection = false;
200 }
201
202 DomUI *ui = 0;
203 {
204 QXmlStreamReader reader;
205 reader.setDevice(in);
206 ui = parseUiFile(reader);
207
208 if (!ui)
209 return false;
210 }
211
212 double version = ui->attributeVersion().toDouble();
213 if (version < 4.0) {
214 delete ui;
215
216 fprintf(stderr, "uic: File generated with too old version of Qt Designer\n");
217 return false;
218 }
219
220 QString language = ui->attributeLanguage();
221
222
223 bool rtn = false;
224
225 if (option().generator == Option::JavaGenerator) {
226#ifdef QT_UIC_JAVA_GENERATOR
227 if (language.toLower() != QLatin1String("jambi")) {
228 fprintf(stderr, "uic: File is not a 'jambi' form\n");
229 return false;
230 }
231 rtn = jwrite (ui);
232#else
233 fprintf(stderr, "uic: option to generate java code not compiled in\n");
234#endif
235 } else {
236#ifdef QT_UIC_CPP_GENERATOR
237 if (!language.isEmpty() && language.toLower() != QLatin1String("c++")) {
238 fprintf(stderr, "uic: File is not a 'c++' ui file, language=%s\n", qPrintable(language));
239 return false;
240 }
241
242 rtn = write (ui);
243#else
244 fprintf(stderr, "uic: option to generate cpp code not compiled in\n");
245#endif
246 }
247
248 delete ui;
249
250 return rtn;
251}
252
253#ifdef QT_UIC_CPP_GENERATOR
254bool Uic::write(DomUI *ui)
255{
256 using namespace CPP;
257
258 if (!ui || !ui->elementWidget())
259 return false;
260
261 if (opt.copyrightHeader)
262 writeCopyrightHeader(ui);
263
264 if (opt.headerProtection) {
265 writeHeaderProtectionStart();
266 out << "\n";
267 }
268
269 pixFunction = ui->elementPixmapFunction();
270 if (pixFunction == QLatin1String("QPixmap::fromMimeSource"))
271 pixFunction = QLatin1String("qPixmapFromMimeSource");
272
273 externalPix = ui->elementImages() == 0;
274
275 info.acceptUI(ui);
276 cWidgetsInfo.acceptUI(ui);
277 WriteIncludes writeIncludes(this);
278 writeIncludes.acceptUI(ui);
279
280 Validator(this).acceptUI(ui);
281 WriteDeclaration(this, writeIncludes.scriptsActivated()).acceptUI(ui);
282
283 if (opt.headerProtection)
284 writeHeaderProtectionEnd();
285
286 return true;
287}
288#endif
289
290#ifdef QT_UIC_JAVA_GENERATOR
291bool Uic::jwrite(DomUI *ui)
292{
293 using namespace Java;
294
295 if (!ui || !ui->elementWidget())
296 return false;
297
298 if (opt.copyrightHeader)
299 writeCopyrightHeader(ui);
300
301 pixFunction = ui->elementPixmapFunction();
302 if (pixFunction == QLatin1String("QPixmap::fromMimeSource"))
303 pixFunction = QLatin1String("qPixmapFromMimeSource");
304
305 externalPix = ui->elementImages() == 0;
306
307 info.acceptUI(ui);
308 cWidgetsInfo.acceptUI(ui);
309 WriteIncludes(this).acceptUI(ui);
310
311 Validator(this).acceptUI(ui);
312 WriteDeclaration(this).acceptUI(ui);
313
314 return true;
315}
316#endif
317
318#ifdef QT_UIC_CPP_GENERATOR
319
320void Uic::writeHeaderProtectionStart()
321{
322 QString h = drv->headerFileName();
323 out << "#ifndef " << h << "\n"
324 << "#define " << h << "\n";
325}
326
327void Uic::writeHeaderProtectionEnd()
328{
329 QString h = drv->headerFileName();
330 out << "#endif // " << h << "\n";
331}
332#endif
333
334bool Uic::isMainWindow(const QString &className) const
335{
336 return customWidgetsInfo()->extends(className, QLatin1String("Q3MainWindow"))
337 || customWidgetsInfo()->extends(className, QLatin1String("QMainWindow"));
338}
339
340bool Uic::isToolBar(const QString &className) const
341{
342 return customWidgetsInfo()->extends(className, QLatin1String("Q3ToolBar"))
343 || customWidgetsInfo()->extends(className, QLatin1String("QToolBar"));
344}
345
346bool Uic::isButton(const QString &className) const
347{
348 return customWidgetsInfo()->extends(className, QLatin1String("QRadioButton"))
349 || customWidgetsInfo()->extends(className, QLatin1String("QToolButton"))
350 || customWidgetsInfo()->extends(className, QLatin1String("QCheckBox"))
351 || customWidgetsInfo()->extends(className, QLatin1String("QPushButton"))
352 || customWidgetsInfo()->extends(className, QLatin1String("QCommandLinkButton"));
353}
354
355bool Uic::isContainer(const QString &className) const
356{
357 return customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
358 || customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))
359 || customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
360 || customWidgetsInfo()->extends(className, QLatin1String("QScrollArea"))
361 || customWidgetsInfo()->extends(className, QLatin1String("QMdiArea"))
362 || customWidgetsInfo()->extends(className, QLatin1String("QWizard"))
363 || customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"));
364}
365
366bool Uic::isStatusBar(const QString &className) const
367{
368 return customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"));
369}
370
371bool Uic::isMenuBar(const QString &className) const
372{
373 return customWidgetsInfo()->extends(className, QLatin1String("QMenuBar"));
374}
375
376bool Uic::isMenu(const QString &className) const
377{
378 return customWidgetsInfo()->extends(className, QLatin1String("QMenu"))
379 || customWidgetsInfo()->extends(className, QLatin1String("QPopupMenu"));
380}
381
382QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.