summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/tools
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/bootstrap/bootstrap.pri76
-rw-r--r--src/tools/bootstrap/bootstrap.pro127
-rw-r--r--src/tools/idc/idc.pro14
-rw-r--r--src/tools/idc/main.cpp335
-rw-r--r--src/tools/moc/generator.cpp1333
-rw-r--r--src/tools/moc/generator.h82
-rw-r--r--src/tools/moc/keywords.cpp1003
-rw-r--r--src/tools/moc/main.cpp448
-rw-r--r--src/tools/moc/moc.cpp1453
-rw-r--r--src/tools/moc/moc.h264
-rw-r--r--src/tools/moc/moc.pri16
-rw-r--r--src/tools/moc/moc.pro18
-rw-r--r--src/tools/moc/mwerks_mac.cpp240
-rw-r--r--src/tools/moc/mwerks_mac.h67
-rw-r--r--src/tools/moc/outputrevision.h48
-rw-r--r--src/tools/moc/parser.cpp87
-rw-r--r--src/tools/moc/parser.h110
-rw-r--r--src/tools/moc/ppkeywords.cpp248
-rw-r--r--src/tools/moc/preprocessor.cpp978
-rw-r--r--src/tools/moc/preprocessor.h102
-rw-r--r--src/tools/moc/symbols.h147
-rw-r--r--src/tools/moc/token.cpp224
-rw-r--r--src/tools/moc/token.h276
-rwxr-xr-xsrc/tools/moc/util/generate.sh48
-rw-r--r--src/tools/moc/util/generate_keywords.cpp469
-rw-r--r--src/tools/moc/util/generate_keywords.pro12
-rw-r--r--src/tools/moc/util/licenseheader.txt41
-rw-r--r--src/tools/moc/utils.h111
-rw-r--r--src/tools/rcc/main.cpp262
-rw-r--r--src/tools/rcc/rcc.cpp987
-rw-r--r--src/tools/rcc/rcc.h153
-rw-r--r--src/tools/rcc/rcc.pri3
-rw-r--r--src/tools/rcc/rcc.pro16
-rw-r--r--src/tools/tools.pro73
-rw-r--r--src/tools/uic/cpp/cpp.pri20
-rw-r--r--src/tools/uic/cpp/cppextractimages.cpp150
-rw-r--r--src/tools/uic/cpp/cppextractimages.h77
-rw-r--r--src/tools/uic/cpp/cppwritedeclaration.cpp279
-rw-r--r--src/tools/uic/cpp/cppwritedeclaration.h81
-rw-r--r--src/tools/uic/cpp/cppwriteicondata.cpp185
-rw-r--r--src/tools/uic/cpp/cppwriteicondata.h81
-rw-r--r--src/tools/uic/cpp/cppwriteicondeclaration.cpp80
-rw-r--r--src/tools/uic/cpp/cppwriteicondeclaration.h76
-rw-r--r--src/tools/uic/cpp/cppwriteiconinitialization.cpp115
-rw-r--r--src/tools/uic/cpp/cppwriteiconinitialization.h81
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.cpp342
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.h116
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp3012
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.h373
-rw-r--r--src/tools/uic/customwidgetsinfo.cpp127
-rw-r--r--src/tools/uic/customwidgetsinfo.h91
-rw-r--r--src/tools/uic/databaseinfo.cpp96
-rw-r--r--src/tools/uic/databaseinfo.h79
-rw-r--r--src/tools/uic/driver.cpp381
-rw-r--r--src/tools/uic/driver.h140
-rw-r--r--src/tools/uic/globaldefs.h54
-rw-r--r--src/tools/uic/main.cpp182
-rw-r--r--src/tools/uic/option.h106
-rw-r--r--src/tools/uic/treewalker.cpp328
-rw-r--r--src/tools/uic/treewalker.h137
-rw-r--r--src/tools/uic/ui4.cpp11154
-rw-r--r--src/tools/uic/ui4.h3807
-rw-r--r--src/tools/uic/uic.cpp387
-rw-r--r--src/tools/uic/uic.h145
-rw-r--r--src/tools/uic/uic.pri21
-rw-r--r--src/tools/uic/uic.pro23
-rw-r--r--src/tools/uic/utils.h128
-rw-r--r--src/tools/uic/validator.cpp94
-rw-r--r--src/tools/uic/validator.h74
69 files changed, 32493 insertions, 0 deletions
diff --git a/src/tools/bootstrap/bootstrap.pri b/src/tools/bootstrap/bootstrap.pri
new file mode 100644
index 0000000000..f48c8c12ff
--- /dev/null
+++ b/src/tools/bootstrap/bootstrap.pri
@@ -0,0 +1,76 @@
+CONFIG += console qtinc
+CONFIG -= qt
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+CONFIG -= app_bundle
+
+DEFINES += \
+ QT_BOOTSTRAPPED \
+ QT_LITE_UNICODE \
+ QT_TEXTCODEC \
+ QT_NO_CAST_FROM_ASCII \
+ QT_NO_CAST_TO_ASCII \
+ QT_NO_CODECS \
+ QT_NO_DATASTREAM \
+ QT_NO_GEOM_VARIANT \
+ QT_NO_LIBRARY \
+ QT_NO_QOBJECT \
+ QT_NO_STL \
+ QT_NO_SYSTEMLOCALE \
+ QT_NO_TEXTSTREAM \
+ QT_NO_THREAD \
+ QT_NO_UNICODETABLES \
+ QT_NO_USING_NAMESPACE \
+ QT_NO_DEPRECATED
+
+win32:DEFINES += QT_NODLL
+
+INCLUDEPATH += $$QT_BUILD_TREE/include \
+ $$QT_BUILD_TREE/include/QtCore \
+ $$QT_BUILD_TREE/include/QtXml \
+ $$QT_SOURCE_TREE/src/xml
+DEPENDPATH += $$INCLUDEPATH \
+ $$QT_SOURCE_TREE/src/corelib/global \
+ $$QT_SOURCE_TREE/src/corelib/kernel \
+ $$QT_SOURCE_TREE/src/corelib/tools \
+ $$QT_SOURCE_TREE/src/corelib/io \
+ $$QT_SOURCE_TREE/src/corelib/codecs \
+ $$QT_SOURCE_TREE/src/xml
+
+hpux-acc*|hpuxi-acc* {
+ LIBS += $$QT_BUILD_TREE/src/tools/bootstrap/libbootstrap.a
+} else {
+ contains(CONFIG, debug_and_release_target) {
+ CONFIG(debug, debug|release) {
+ QMAKE_LIBDIR += $$QT_BUILD_TREE/src/tools/bootstrap/debug
+ } else {
+ QMAKE_LIBDIR += $$QT_BUILD_TREE/src/tools/bootstrap/release
+ }
+ } else {
+ QMAKE_LIBDIR += $$QT_BUILD_TREE/src/tools/bootstrap
+ }
+ LIBS += -lbootstrap
+}
+!contains(QT_CONFIG, zlib):!contains(QT_CONFIG, no-zlib):!cross_compile {
+ symbian:LIBS_PRIVATE += -llibz
+ else:if(unix|win32-g++*):LIBS_PRIVATE += -lz
+ else:LIBS += zdll.lib
+}
+win32:LIBS += -luser32
+
+mac {
+ CONFIG -= incremental
+ LIBS += -framework CoreServices
+}
+
+# Make dummy "sis" and "freeze" target to keep recursive "make sis/freeze" working.
+sis_target.target = sis
+sis_target.commands =
+sis_target.depends = first
+QMAKE_EXTRA_TARGETS += sis_target
+freeze_target.target = freeze
+freeze_target.commands =
+freeze_target.depends = first
+QMAKE_EXTRA_TARGETS += freeze_target
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
new file mode 100644
index 0000000000..50ae2cff16
--- /dev/null
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -0,0 +1,127 @@
+TEMPLATE = lib
+TARGET = bootstrap
+CONFIG += staticlib
+
+CONFIG += console qtinc
+CONFIG -= qt
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+mac:CONFIG -= app_bundle incremental
+
+DEFINES += \
+ QT_BOOTSTRAPPED \
+ QT_LITE_UNICODE \
+ QT_NO_CAST_FROM_ASCII \
+ QT_NO_CAST_TO_ASCII \
+ QT_NO_CODECS \
+ QT_NO_DATASTREAM \
+ QT_NO_GEOM_VARIANT \
+ QT_NO_LIBRARY \
+ QT_NO_QOBJECT \
+ QT_NO_STL \
+ QT_NO_SYSTEMLOCALE \
+ QT_NO_TEXTSTREAM \
+ QT_NO_THREAD \
+ QT_NO_UNICODETABLES \
+ QT_NO_USING_NAMESPACE \
+ QT_NO_DEPRECATED
+
+win32:DEFINES += QT_NODLL
+
+INCLUDEPATH += $$QT_BUILD_TREE/include \
+ $$QT_BUILD_TREE/include/QtCore \
+ $$QT_BUILD_TREE/include/QtXml
+
+DEPENDPATH += $$INCLUDEPATH \
+ ../../corelib/global \
+ ../../corelib/kernel \
+ ../../corelib/tools \
+ ../../corelib/io \
+ ../../corelib/codecs \
+ ../../xml
+
+SOURCES += \
+ ../../corelib/codecs/qisciicodec.cpp \
+ ../../corelib/codecs/qlatincodec.cpp \
+ ../../corelib/codecs/qsimplecodec.cpp \
+ ../../corelib/codecs/qtextcodec.cpp \
+ ../../corelib/codecs/qtsciicodec.cpp \
+ ../../corelib/codecs/qutfcodec.cpp \
+ ../../corelib/global/qglobal.cpp \
+ ../../corelib/global/qmalloc.cpp \
+ ../../corelib/global/qnumeric.cpp \
+ ../../corelib/io/qabstractfileengine.cpp \
+ ../../corelib/io/qbuffer.cpp \
+ ../../corelib/io/qdatastream.cpp \
+ ../../corelib/io/qdir.cpp \
+ ../../corelib/io/qdiriterator.cpp \
+ ../../corelib/io/qfile.cpp \
+ ../../corelib/io/qfileinfo.cpp \
+ ../../corelib/io/qfilesystementry.cpp \
+ ../../corelib/io/qfilesystemengine.cpp \
+ ../../corelib/io/qfsfileengine.cpp \
+ ../../corelib/io/qfsfileengine_iterator.cpp \
+ ../../corelib/io/qiodevice.cpp \
+ ../../corelib/io/qtemporaryfile.cpp \
+ ../../corelib/io/qtextstream.cpp \
+ ../../corelib/io/qurl.cpp \
+ ../../corelib/kernel/qmetatype.cpp \
+ ../../corelib/kernel/qvariant.cpp \
+ ../../corelib/kernel/qsystemerror.cpp \
+ ../../corelib/tools/qbitarray.cpp \
+ ../../corelib/tools/qbytearray.cpp \
+ ../../corelib/tools/qbytearraymatcher.cpp \
+ ../../corelib/tools/qdatetime.cpp \
+ ../../corelib/tools/qhash.cpp \
+ ../../corelib/tools/qlist.cpp \
+ ../../corelib/tools/qlocale.cpp \
+ ../../corelib/tools/qlocale_tools.cpp \
+ ../../corelib/tools/qmap.cpp \
+ ../../corelib/tools/qregexp.cpp \
+ ../../corelib/tools/qstring.cpp \
+ ../../corelib/tools/qstringlist.cpp \
+ ../../corelib/tools/qvector.cpp \
+ ../../corelib/tools/qvsnprintf.cpp \
+ ../../corelib/xml/qxmlutils.cpp \
+ ../../corelib/xml/qxmlstream.cpp \
+ ../../xml/dom/qdom.cpp \
+ ../../xml/sax/qxml.cpp
+
+unix:SOURCES += ../../corelib/io/qfilesystemengine_unix.cpp \
+ ../../corelib/io/qfilesystemiterator_unix.cpp \
+ ../../corelib/io/qfsfileengine_unix.cpp
+
+win32:SOURCES += ../../corelib/io/qfilesystemengine_win.cpp \
+ ../../corelib/io/qfilesystemiterator_win.cpp \
+ ../../corelib/io/qfsfileengine_win.cpp \
+ ../../corelib/plugin/qsystemlibrary.cpp \
+
+mac: OBJECTIVE_SOURCES += ../../corelib/tools/qlocale_mac.mm
+else:symbian:SOURCES += ../../corelib/tools/qlocale_symbian.cpp
+else:unix:SOURCES += ../../corelib/tools/qlocale_unix.cpp
+else:win32:SOURCES += ../../corelib/tools/qlocale_win.cpp
+
+macx: {
+ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported)
+ SOURCES += ../../corelib/io/qfilesystemengine_mac.cpp
+ SOURCES += ../../corelib/kernel/qcore_mac.cpp
+ LIBS += -framework CoreServices
+}
+
+if(contains(QT_CONFIG, zlib)|cross_compile):include(../../3rdparty/zlib.pri)
+else:include(../../3rdparty/zlib_dependency.pri)
+
+lib.CONFIG = dummy_install
+INSTALLS += lib
+
+# Make dummy "sis" and "freeze" target to keep recursive "make sis/freeze" working.
+sis_target.target = sis
+sis_target.commands =
+sis_target.depends = first
+QMAKE_EXTRA_TARGETS += sis_target
+freeze_target.target = freeze
+freeze_target.commands =
+freeze_target.depends = first
+QMAKE_EXTRA_TARGETS += freeze_target
diff --git a/src/tools/idc/idc.pro b/src/tools/idc/idc.pro
new file mode 100644
index 0000000000..c33de6797c
--- /dev/null
+++ b/src/tools/idc/idc.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+CONFIG += console
+CONFIG -= app_bundle
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+DESTDIR = ../../../bin
+
+SOURCES = main.cpp
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/src/tools/idc/main.cpp b/src/tools/idc/main.cpp
new file mode 100644
index 0000000000..1b51a68c5e
--- /dev/null
+++ b/src/tools/idc/main.cpp
@@ -0,0 +1,335 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QFile>
+#include <QProcess>
+#include <QLibraryInfo>
+#include <qt_windows.h>
+#include <io.h>
+
+QT_BEGIN_NAMESPACE
+
+static QString quotePath(const QString &s)
+{
+ if (!s.startsWith(QLatin1Char('\"')) && s.contains(QLatin1Char(' ')))
+ return QLatin1Char('\"') + s + QLatin1Char('\"');
+ return s;
+}
+
+
+static bool runWithQtInEnvironment(const QString &cmd)
+{
+ QProcess proc;
+
+ // prepend the qt binary directory to the path
+ QStringList env = QProcess::systemEnvironment();
+ for (int i=0; i<env.count(); ++i) {
+ QString var = env.at(i);
+ int setidx = var.indexOf(QLatin1Char('='));
+ if (setidx != -1) {
+ QString varname = var.left(setidx).trimmed().toUpper();
+ if (varname == QLatin1String("PATH")) {
+ var = var.mid(setidx + 1);
+ var = QLatin1String("PATH=") +
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) +
+ QLatin1Char(';') + var;
+ env[i] = var;
+ break;
+ }
+ }
+ }
+
+ proc.setEnvironment(env);
+ proc.start(cmd);
+ proc.waitForFinished(-1);
+
+ return (proc.exitCode() == 0);
+}
+
+static bool attachTypeLibrary(const QString &applicationName, int resource, const QByteArray &data, QString *errorMessage)
+{
+ HANDLE hExe = BeginUpdateResource((const wchar_t *)applicationName.utf16(), false);
+ if (hExe == 0) {
+ if (errorMessage)
+ *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not open file.").arg(applicationName);
+ return false;
+ }
+ if (!UpdateResource(hExe, L"TYPELIB", MAKEINTRESOURCE(resource), 0, (void*)data.data(), data.count())) {
+ EndUpdateResource(hExe, true);
+ if (errorMessage)
+ *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not update file.").arg(applicationName);
+ return false;
+ }
+
+ if (!EndUpdateResource(hExe,false)) {
+ if (errorMessage)
+ *errorMessage = QString::fromLatin1("Failed to attach type library to binary %1 - could not write file.").arg(applicationName);
+ return false;
+ }
+
+ if (errorMessage)
+ *errorMessage = QString::fromLatin1("Type library attached to %1.").arg(applicationName);
+ return true;
+}
+
+static bool registerServer(const QString &input)
+{
+ bool ok = false;
+ if (input.endsWith(QLatin1String(".exe"))) {
+ ok = runWithQtInEnvironment(quotePath(input) + QLatin1String(" -regserver"));
+ } else {
+ HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16());
+ if (!hdll) {
+ fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data());
+ return false;
+ }
+ typedef HRESULT(__stdcall* RegServerProc)();
+ RegServerProc DllRegisterServer = (RegServerProc)GetProcAddress(hdll, "DllRegisterServer");
+ if (!DllRegisterServer) {
+ fprintf(stderr, "Library file %s doesn't appear to be a COM library\n", (const char*)input.toLocal8Bit().data());
+ return false;
+ }
+ ok = DllRegisterServer() == S_OK;
+ }
+ return ok;
+}
+
+static bool unregisterServer(const QString &input)
+{
+ bool ok = false;
+ if (input.endsWith(QLatin1String(".exe"))) {
+ ok = runWithQtInEnvironment(quotePath(input) + QLatin1String(" -unregserver"));
+ } else {
+ HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16());
+ if (!hdll) {
+ fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data());
+ return false;
+ }
+ typedef HRESULT(__stdcall* RegServerProc)();
+ RegServerProc DllUnregisterServer = (RegServerProc)GetProcAddress(hdll, "DllUnregisterServer");
+ if (!DllUnregisterServer) {
+ fprintf(stderr, "Library file %s doesn't appear to be a COM library\n", (const char*)input.toLocal8Bit().data());
+ return false;
+ }
+ ok = DllUnregisterServer() == S_OK;
+ }
+ return ok;
+}
+
+static HRESULT dumpIdl(const QString &input, const QString &idlfile, const QString &version)
+{
+ HRESULT res = E_FAIL;
+
+ if (input.endsWith(QLatin1String(".exe"))) {
+ if (runWithQtInEnvironment(quotePath(input) + QLatin1String(" -dumpidl ") + idlfile + QLatin1String(" -version ") + version))
+ res = S_OK;
+ } else {
+ HMODULE hdll = LoadLibrary((const wchar_t *)input.utf16());
+ if (!hdll) {
+ fprintf(stderr, "Couldn't load library file %s\n", (const char*)input.toLocal8Bit().data());
+ return 3;
+ }
+ typedef HRESULT(__stdcall* DumpIDLProc)(const QString&, const QString&);
+ DumpIDLProc DumpIDL = (DumpIDLProc)GetProcAddress(hdll, "DumpIDL");
+ if (!DumpIDL) {
+ fprintf(stderr, "Couldn't resolve 'DumpIDL' symbol in %s\n", (const char*)input.toLocal8Bit().data());
+ return 3;
+ }
+ res = DumpIDL(idlfile, version);
+ FreeLibrary(hdll);
+ }
+
+ return res;
+}
+
+static void slashify(QString &s)
+{
+ if (!s.contains(QLatin1Char('/')))
+ return;
+
+ int i = 0;
+ while (i < (int)s.length()) {
+ if (s[i] == QLatin1Char('/'))
+ s[i] = QLatin1Char('\\');
+ ++i;
+ }
+}
+
+int runIdc(int argc, char **argv)
+{
+ QString error;
+ QString tlbfile;
+ QString idlfile;
+ QString input;
+ QString version = QLatin1String("1.0");
+
+ int i = 1;
+ while (i < argc) {
+ QString p = QString::fromLocal8Bit(argv[i]).toLower();
+
+ if (p == QLatin1String("/idl") || p == QLatin1String("-idl")) {
+ ++i;
+ if (i > argc) {
+ error = QLatin1String("Missing name for interface definition file!");
+ break;
+ }
+ idlfile = QLatin1String(argv[i]);
+ idlfile = idlfile.trimmed().toLower();
+ } else if (p == QLatin1String("/version") || p == QLatin1String("-version")) {
+ ++i;
+ if (i > argc)
+ version = QLatin1String("1.0");
+ else
+ version = QLatin1String(argv[i]);
+ } else if (p == QLatin1String("/tlb") || p == QLatin1String("-tlb")) {
+ ++i;
+ if (i > argc) {
+ error = QLatin1String("Missing name for type library file!");
+ break;
+ }
+ tlbfile = QLatin1String(argv[i]);
+ tlbfile = tlbfile.trimmed().toLower();
+ } else if (p == QLatin1String("/v") || p == QLatin1String("-v")) {
+ fprintf(stdout, "Qt Interface Definition Compiler version 1.0\n");
+ return 0;
+ } else if (p == QLatin1String("/regserver") || p == QLatin1String("-regserver")) {
+ if (!registerServer(input)) {
+ fprintf(stderr, "Failed to register server!\n");
+ return 1;
+ }
+ fprintf(stderr, "Server registered successfully!\n");
+ return 0;
+ } else if (p == QLatin1String("/unregserver") || p == QLatin1String("-unregserver")) {
+ if (!unregisterServer(input)) {
+ fprintf(stderr, "Failed to unregister server!\n");
+ return 1;
+ }
+ fprintf(stderr, "Server unregistered successfully!\n");
+ return 0;
+ } else if (p[0] == QLatin1Char('/') || p[0] == QLatin1Char('-')) {
+ error = QLatin1String("Unknown option \"") + p + QLatin1Char('\"');
+ break;
+ } else {
+ input = QLatin1String(argv[i]);
+ input = input.trimmed().toLower();
+ }
+ i++;
+ }
+ if (!error.isEmpty()) {
+ fprintf(stderr, "%s", error.toLatin1().data());
+ fprintf(stderr, "\n");
+ return 5;
+ }
+ if (input.isEmpty()) {
+ fprintf(stderr, "No input file specified!\n");
+ return 1;
+ }
+ if (input.endsWith(QLatin1String(".exe")) && tlbfile.isEmpty() && idlfile.isEmpty()) {
+ fprintf(stderr, "No type output file specified!\n");
+ return 2;
+ }
+ if (input.endsWith(QLatin1String(".dll")) && idlfile.isEmpty() && tlbfile.isEmpty()) {
+ fprintf(stderr, "No interface definition file and no type library file specified!\n");
+ return 3;
+ }
+ slashify(input);
+ if (!tlbfile.isEmpty()) {
+ slashify(tlbfile);
+ QFile file(tlbfile);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Couldn't open %s for read\n", (const char*)tlbfile.toLocal8Bit().data());
+ return 4;
+ }
+ QByteArray data = file.readAll();
+ QString error;
+ bool ok = attachTypeLibrary(input, 1, data, &error);
+ fprintf(stderr, "%s", error.toLatin1().data());
+ fprintf(stderr, "\n");
+ return ok ? 0 : 4;
+ } else if (!idlfile.isEmpty()) {
+ slashify(idlfile);
+ idlfile = quotePath(idlfile);
+ fprintf(stderr, "\n\n%s\n\n", (const char*)idlfile.toLocal8Bit().data());
+ quotePath(input);
+ HRESULT res = dumpIdl(input, idlfile, version);
+
+ switch(res) {
+ case S_OK:
+ break;
+ case E_FAIL:
+ fprintf(stderr, "IDL generation failed trying to run program %s!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+ case -1:
+ fprintf(stderr, "Couldn't open %s for writing!\n", (const char*)idlfile.toLocal8Bit().data());
+ return res;
+ case 1:
+ fprintf(stderr, "Malformed appID value in %s!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+ case 2:
+ fprintf(stderr, "Malformed typeLibID value in %s!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+ case 3:
+ fprintf(stderr, "Class has no metaobject information (error in %s)!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+ case 4:
+ fprintf(stderr, "Malformed classID value in %s!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+ case 5:
+ fprintf(stderr, "Malformed interfaceID value in %s!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+ case 6:
+ fprintf(stderr, "Malformed eventsID value in %s!\n", (const char*)input.toLocal8Bit().data());
+ return res;
+
+ default:
+ fprintf(stderr, "Unknown error writing IDL from %s\n", (const char*)input.toLocal8Bit().data());
+ return 7;
+ }
+ }
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ return QT_PREPEND_NAMESPACE(runIdc)(argc, argv);
+}
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
new file mode 100644
index 0000000000..aea156da18
--- /dev/null
+++ b/src/tools/moc/generator.cpp
@@ -0,0 +1,1333 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "generator.h"
+#include "outputrevision.h"
+#include "utils.h"
+#include <QtCore/qmetatype.h>
+#include <stdio.h>
+
+#include <private/qmetaobject_p.h> //for the flags.
+
+QT_BEGIN_NAMESPACE
+
+uint qvariant_nameToType(const char* name)
+{
+ if (!name)
+ return 0;
+
+ if (strcmp(name, "QVariant") == 0)
+ return 0xffffffff;
+ if (strcmp(name, "QCString") == 0)
+ return QMetaType::QByteArray;
+ if (strcmp(name, "Q_LLONG") == 0)
+ return QMetaType::LongLong;
+ if (strcmp(name, "Q_ULLONG") == 0)
+ return QMetaType::ULongLong;
+ if (strcmp(name, "QIconSet") == 0)
+ return QMetaType::QIcon;
+
+ uint tp = QMetaType::type(name);
+ return tp < QMetaType::User ? tp : 0;
+}
+
+/*
+ Returns true if the type is a QVariant types.
+*/
+bool isVariantType(const char* type)
+{
+ return qvariant_nameToType(type) != 0;
+}
+
+/*!
+ Returns true if the type is qreal.
+*/
+static bool isQRealType(const char *type)
+{
+ return strcmp(type, "qreal") == 0;
+}
+
+Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile)
+ : out(outfile), cdef(classDef), metaTypes(metaTypes)
+{
+ if (cdef->superclassList.size())
+ purestSuperClass = cdef->superclassList.first().first;
+}
+
+static inline int lengthOfEscapeSequence(const QByteArray &s, int i)
+{
+ if (s.at(i) != '\\' || i >= s.length() - 1)
+ return 1;
+ const int startPos = i;
+ ++i;
+ char ch = s.at(i);
+ if (ch == 'x') {
+ ++i;
+ while (i < s.length() && is_hex_char(s.at(i)))
+ ++i;
+ } else if (is_octal_char(ch)) {
+ while (i < startPos + 4
+ && i < s.length()
+ && is_octal_char(s.at(i))) {
+ ++i;
+ }
+ } else { // single character escape sequence
+ i = qMin(i + 1, s.length());
+ }
+ return i - startPos;
+}
+
+int Generator::strreg(const char *s)
+{
+ int idx = 0;
+ if (!s)
+ s = "";
+ for (int i = 0; i < strings.size(); ++i) {
+ const QByteArray &str = strings.at(i);
+ if (str == s)
+ return idx;
+ idx += str.length() + 1;
+ for (int i = 0; i < str.length(); ++i) {
+ if (str.at(i) == '\\') {
+ int cnt = lengthOfEscapeSequence(str, i) - 1;
+ idx -= cnt;
+ i += cnt;
+ }
+ }
+ }
+ strings.append(s);
+ return idx;
+}
+
+void Generator::generateCode()
+{
+ bool isQt = (cdef->classname == "Qt");
+ bool isQObject = (cdef->classname == "QObject");
+ bool isConstructible = !cdef->constructorList.isEmpty();
+
+//
+// build the data array
+//
+ int i = 0;
+
+
+ // filter out undeclared enumerators and sets
+ {
+ QList<EnumDef> enumList;
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ EnumDef def = cdef->enumList.at(i);
+ if (cdef->enumDeclarations.contains(def.name)) {
+ enumList += def;
+ }
+ QByteArray alias = cdef->flagAliases.value(def.name);
+ if (cdef->enumDeclarations.contains(alias)) {
+ def.name = alias;
+ enumList += def;
+ }
+ }
+ cdef->enumList = enumList;
+ }
+
+
+ QByteArray qualifiedClassNameIdentifier = cdef->qualified;
+ qualifiedClassNameIdentifier.replace(':', '_');
+
+ int index = 14;
+ fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
+ fprintf(out, "\n // content:\n");
+ fprintf(out, " %4d, // revision\n", 6);
+ fprintf(out, " %4d, // classname\n", strreg(cdef->qualified));
+ fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0);
+ index += cdef->classInfoList.count() * 2;
+
+ int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
+ fprintf(out, " %4d, %4d, // methods\n", methodCount, methodCount ? index : 0);
+ index += methodCount * 5;
+ if (cdef->revisionedMethods)
+ index += methodCount;
+ fprintf(out, " %4d, %4d, // properties\n", cdef->propertyList.count(), cdef->propertyList.count() ? index : 0);
+ index += cdef->propertyList.count() * 3;
+ if(cdef->notifyableProperties)
+ index += cdef->propertyList.count();
+ if (cdef->revisionedProperties)
+ index += cdef->propertyList.count();
+ fprintf(out, " %4d, %4d, // enums/sets\n", cdef->enumList.count(), cdef->enumList.count() ? index : 0);
+
+ int enumsIndex = index;
+ for (i = 0; i < cdef->enumList.count(); ++i)
+ index += 4 + (cdef->enumList.at(i).values.count() * 2);
+ fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0,
+ isConstructible ? index : 0);
+
+ fprintf(out, " %4d, // flags\n", 0);
+ fprintf(out, " %4d, // signalCount\n", cdef->signalList.count());
+
+
+//
+// Build classinfo array
+//
+ generateClassInfos();
+
+//
+// Build signals array first, otherwise the signal indices would be wrong
+//
+ generateFunctions(cdef->signalList, "signal", MethodSignal);
+
+//
+// Build slots array
+//
+ generateFunctions(cdef->slotList, "slot", MethodSlot);
+
+//
+// Build method array
+//
+ generateFunctions(cdef->methodList, "method", MethodMethod);
+
+//
+// Build method version arrays
+//
+ if (cdef->revisionedMethods) {
+ generateFunctionRevisions(cdef->signalList, "signal");
+ generateFunctionRevisions(cdef->slotList, "slot");
+ generateFunctionRevisions(cdef->methodList, "method");
+ }
+
+//
+// Build property array
+//
+ generateProperties();
+
+//
+// Build enums array
+//
+ generateEnums(enumsIndex);
+
+//
+// Build constructors array
+//
+ if (isConstructible)
+ generateFunctions(cdef->constructorList, "constructor", MethodConstructor);
+
+//
+// Terminate data array
+//
+ fprintf(out, "\n 0 // eod\n};\n\n");
+
+//
+// Build stringdata array
+//
+ fprintf(out, "static const char qt_meta_stringdata_%s[] = {\n", qualifiedClassNameIdentifier.constData());
+ fprintf(out, " \"");
+ int col = 0;
+ int len = 0;
+ for (i = 0; i < strings.size(); ++i) {
+ QByteArray s = strings.at(i);
+ len = s.length();
+ if (col && col + len >= 72) {
+ fprintf(out, "\"\n \"");
+ col = 0;
+ } else if (len && s.at(0) >= '0' && s.at(0) <= '9') {
+ fprintf(out, "\"\"");
+ len += 2;
+ }
+ int idx = 0;
+ while (idx < s.length()) {
+ if (idx > 0) {
+ col = 0;
+ fprintf(out, "\"\n \"");
+ }
+ int spanLen = qMin(70, s.length() - idx);
+ // don't cut escape sequences at the end of a line
+ int backSlashPos = s.lastIndexOf('\\', idx + spanLen - 1);
+ if (backSlashPos >= idx) {
+ int escapeLen = lengthOfEscapeSequence(s, backSlashPos);
+ spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, s.length() - idx);
+ }
+ fwrite(s.constData() + idx, 1, spanLen, out);
+ idx += spanLen;
+ col += spanLen;
+ }
+
+ fputs("\\0", out);
+ col += len + 2;
+ }
+ fprintf(out, "\"\n};\n\n");
+
+//
+// Generate internal qt_static_metacall() function
+//
+ if (cdef->hasQObject && !isQt)
+ generateStaticMetacall();
+
+//
+// Build extra array
+//
+ QList<QByteArray> extraList;
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ if (!isVariantType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') &&
+ !p.type.contains('<') && !p.type.contains('>')) {
+ int s = p.type.lastIndexOf("::");
+ if (s > 0) {
+ QByteArray scope = p.type.left(s);
+ if (scope != "Qt" && scope != cdef->classname && !extraList.contains(scope))
+ extraList += scope;
+ }
+ }
+ }
+ if (!extraList.isEmpty()) {
+ fprintf(out, "#ifdef Q_NO_DATA_RELOCATION\n");
+ fprintf(out, "static const QMetaObjectAccessor qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
+ for (int i = 0; i < extraList.count(); ++i) {
+ fprintf(out, " %s::getStaticMetaObject,\n", extraList.at(i).constData());
+ }
+ fprintf(out, "#else\n");
+ fprintf(out, "static const QMetaObject *qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
+ for (int i = 0; i < extraList.count(); ++i) {
+ fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData());
+ }
+ fprintf(out, "#endif //Q_NO_DATA_RELOCATION\n");
+ fprintf(out, " 0\n};\n\n");
+ }
+
+ bool hasExtraData = (cdef->hasQObject && !isQt) || !extraList.isEmpty();
+ if (hasExtraData) {
+ fprintf(out, "const QMetaObjectExtraData %s::staticMetaObjectExtraData = {\n ",
+ cdef->qualified.constData());
+ if (extraList.isEmpty())
+ fprintf(out, "0, ");
+ else
+ fprintf(out, "qt_meta_extradata_%s, ", qualifiedClassNameIdentifier.constData());
+
+ if (cdef->hasQObject && !isQt)
+ fprintf(out, " qt_static_metacall");
+ else
+ fprintf(out, " 0");
+ fprintf(out, " \n};\n\n");
+ }
+
+//
+// Finally create and initialize the static meta object
+//
+ if (isQt)
+ fprintf(out, "const QMetaObject QObject::staticQtMetaObject = {\n");
+ else
+ fprintf(out, "const QMetaObject %s::staticMetaObject = {\n", cdef->qualified.constData());
+
+ if (isQObject)
+ fprintf(out, " { 0, ");
+ else if (cdef->superclassList.size())
+ fprintf(out, " { &%s::staticMetaObject, ", purestSuperClass.constData());
+ else
+ fprintf(out, " { 0, ");
+ fprintf(out, "qt_meta_stringdata_%s,\n qt_meta_data_%s, ",
+ qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
+ if (!hasExtraData)
+ fprintf(out, "0 }\n");
+ else
+ fprintf(out, "&staticMetaObjectExtraData }\n");
+ fprintf(out, "};\n");
+
+ if(isQt)
+ return;
+
+//
+// Generate static meta object accessor (needed for symbian, because DLLs do not support data imports.
+//
+ fprintf(out, "\n#ifdef Q_NO_DATA_RELOCATION\n");
+ fprintf(out, "const QMetaObject &%s::getStaticMetaObject() { return staticMetaObject; }\n", cdef->qualified.constData());
+ fprintf(out, "#endif //Q_NO_DATA_RELOCATION\n");
+
+ if (!cdef->hasQObject)
+ return;
+
+ fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;\n}\n",
+ cdef->qualified.constData());
+
+//
+// Generate smart cast function
+//
+ fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
+ fprintf(out, " if (!_clname) return 0;\n");
+ fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s))\n"
+ " return static_cast<void*>(const_cast< %s*>(this));\n",
+ qualifiedClassNameIdentifier.constData(), cdef->classname.constData());
+ for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one
+ if (cdef->superclassList.at(i).second == FunctionDef::Private)
+ continue;
+ const char *cname = cdef->superclassList.at(i).first;
+ fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(const_cast< %s*>(this));\n",
+ cname, cname, cdef->classname.constData());
+ }
+ for (int i = 0; i < cdef->interfaceList.size(); ++i) {
+ const QList<ClassDef::Interface> &iface = cdef->interfaceList.at(i);
+ for (int j = 0; j < iface.size(); ++j) {
+ fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
+ for (int k = j; k >= 0; --k)
+ fprintf(out, "static_cast< %s*>(", iface.at(k).className.constData());
+ fprintf(out, "const_cast< %s*>(this)%s;\n",
+ cdef->classname.constData(), QByteArray(j+1, ')').constData());
+ }
+ }
+ if (!purestSuperClass.isEmpty() && !isQObject) {
+ QByteArray superClass = purestSuperClass;
+ // workaround for VC6
+ if (superClass.contains("::")) {
+ fprintf(out, " typedef %s QMocSuperClass;\n", superClass.constData());
+ superClass = "QMocSuperClass";
+ }
+ fprintf(out, " return %s::qt_metacast(_clname);\n", superClass.constData());
+ } else {
+ fprintf(out, " return 0;\n");
+ }
+ fprintf(out, "}\n");
+
+//
+// Generate internal qt_metacall() function
+//
+ generateMetacall();
+
+//
+// Generate internal signal functions
+//
+ for (int signalindex = 0; signalindex < cdef->signalList.size(); ++signalindex)
+ generateSignal(&cdef->signalList[signalindex], signalindex);
+}
+
+
+void Generator::generateClassInfos()
+{
+ if (cdef->classInfoList.isEmpty())
+ return;
+
+ fprintf(out, "\n // classinfo: key, value\n");
+
+ for (int i = 0; i < cdef->classInfoList.size(); ++i) {
+ const ClassInfoDef &c = cdef->classInfoList.at(i);
+ fprintf(out, " %4d, %4d,\n", strreg(c.name), strreg(c.value));
+ }
+}
+
+void Generator::generateFunctions(QList<FunctionDef>& list, const char *functype, int type)
+{
+ if (list.isEmpty())
+ return;
+ fprintf(out, "\n // %ss: signature, parameters, type, tag, flags\n", functype);
+
+ for (int i = 0; i < list.count(); ++i) {
+ const FunctionDef &f = list.at(i);
+
+ QByteArray sig = f.name + '(';
+ QByteArray arguments;
+
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j) {
+ sig += ",";
+ arguments += ",";
+ }
+ sig += a.normalizedType;
+ arguments += a.name;
+ }
+ sig += ')';
+
+ unsigned char flags = type;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.isCompat)
+ flags |= MethodCompatibility;
+ if (f.wasCloned)
+ flags |= MethodCloned;
+ if (f.isScriptable)
+ flags |= MethodScriptable;
+ if (f.revision > 0)
+ flags |= MethodRevisioned;
+ fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x,\n", strreg(sig),
+ strreg(arguments), strreg(f.normalizedType), strreg(f.tag), flags);
+ }
+}
+
+void Generator::generateFunctionRevisions(QList<FunctionDef>& list, const char *functype)
+{
+ if (list.count())
+ fprintf(out, "\n // %ss: revision\n", functype);
+ for (int i = 0; i < list.count(); ++i) {
+ const FunctionDef &f = list.at(i);
+ fprintf(out, " %4d,\n", f.revision);
+ }
+}
+
+void Generator::generateProperties()
+{
+ //
+ // Create meta data
+ //
+
+ if (cdef->propertyList.count())
+ fprintf(out, "\n // properties: name, type, flags\n");
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ uint flags = Invalid;
+ if (!isVariantType(p.type)) {
+ flags |= EnumOrFlag;
+ } else if (!isQRealType(p.type)) {
+ flags |= qvariant_nameToType(p.type) << 24;
+ }
+ if (!p.read.isEmpty())
+ flags |= Readable;
+ if (!p.write.isEmpty()) {
+ flags |= Writable;
+ if (p.stdCppSet())
+ flags |= StdCppSet;
+ }
+ if (!p.reset.isEmpty())
+ flags |= Resettable;
+
+// if (p.override)
+// flags |= Override;
+
+ if (p.designable.isEmpty())
+ flags |= ResolveDesignable;
+ else if (p.designable != "false")
+ flags |= Designable;
+
+ if (p.scriptable.isEmpty())
+ flags |= ResolveScriptable;
+ else if (p.scriptable != "false")
+ flags |= Scriptable;
+
+ if (p.stored.isEmpty())
+ flags |= ResolveStored;
+ else if (p.stored != "false")
+ flags |= Stored;
+
+ if (p.editable.isEmpty())
+ flags |= ResolveEditable;
+ else if (p.editable != "false")
+ flags |= Editable;
+
+ if (p.user.isEmpty())
+ flags |= ResolveUser;
+ else if (p.user != "false")
+ flags |= User;
+
+ if (p.notifyId != -1)
+ flags |= Notify;
+
+ if (p.revision > 0)
+ flags |= Revisioned;
+
+ if (p.constant)
+ flags |= Constant;
+ if (p.final)
+ flags |= Final;
+
+ fprintf(out, " %4d, %4d, ",
+ strreg(p.name),
+ strreg(p.type));
+ if (!(flags >> 24) && isQRealType(p.type))
+ fprintf(out, "(QMetaType::QReal << 24) | ");
+ fprintf(out, "0x%.8x,\n", flags);
+ }
+
+ if(cdef->notifyableProperties) {
+ fprintf(out, "\n // properties: notify_signal_id\n");
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ if(p.notifyId == -1)
+ fprintf(out, " %4d,\n",
+ 0);
+ else
+ fprintf(out, " %4d,\n",
+ p.notifyId);
+ }
+ }
+ if (cdef->revisionedProperties) {
+ fprintf(out, "\n // properties: revision\n");
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ fprintf(out, " %4d,\n", p.revision);
+ }
+ }
+}
+
+void Generator::generateEnums(int index)
+{
+ if (cdef->enumDeclarations.isEmpty())
+ return;
+
+ fprintf(out, "\n // enums: name, flags, count, data\n");
+ index += 4 * cdef->enumList.count();
+ int i;
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ fprintf(out, " %4d, 0x%.1x, %4d, %4d,\n",
+ strreg(e.name),
+ cdef->enumDeclarations.value(e.name) ? 1 : 0,
+ e.values.count(),
+ index);
+ index += e.values.count() * 2;
+ }
+
+ fprintf(out, "\n // enum data: key, value\n");
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ for (int j = 0; j < e.values.count(); ++j) {
+ const QByteArray &val = e.values.at(j);
+ fprintf(out, " %4d, uint(%s::%s),\n",
+ strreg(val),
+ cdef->qualified.constData(),
+ val.constData());
+ }
+ }
+}
+
+void Generator::generateMetacall()
+{
+ bool isQObject = (cdef->classname == "QObject");
+
+ fprintf(out, "\nint %s::qt_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n",
+ cdef->qualified.constData());
+
+ if (!purestSuperClass.isEmpty() && !isQObject) {
+ QByteArray superClass = purestSuperClass;
+ // workaround for VC6
+ if (superClass.contains("::")) {
+ fprintf(out, " typedef %s QMocSuperClass;\n", superClass.constData());
+ superClass = "QMocSuperClass";
+ }
+ fprintf(out, " _id = %s::qt_metacall(_c, _id, _a);\n", superClass.constData());
+ }
+
+ fprintf(out, " if (_id < 0)\n return _id;\n");
+ fprintf(out, " ");
+
+ bool needElse = false;
+ QList<FunctionDef> methodList;
+ methodList += cdef->signalList;
+ methodList += cdef->slotList;
+ methodList += cdef->methodList;
+
+ if (methodList.size()) {
+ needElse = true;
+ fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n");
+ fprintf(out, " if (_id < %d)\n", methodList.size());
+ fprintf(out, " qt_static_metacall(this, _c, _id, _a);\n");
+ fprintf(out, " _id -= %d;\n }", methodList.size());
+ }
+
+ if (cdef->propertyList.size()) {
+ bool needGet = false;
+ bool needTempVarForGet = false;
+ bool needSet = false;
+ bool needReset = false;
+ bool needDesignable = false;
+ bool needScriptable = false;
+ bool needStored = false;
+ bool needEditable = false;
+ bool needUser = false;
+ for (int i = 0; i < cdef->propertyList.size(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ needGet |= !p.read.isEmpty();
+ if (!p.read.isEmpty())
+ needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec
+ && p.gspec != PropertyDef::ReferenceSpec);
+
+ needSet |= !p.write.isEmpty();
+ needReset |= !p.reset.isEmpty();
+ needDesignable |= p.designable.endsWith(')');
+ needScriptable |= p.scriptable.endsWith(')');
+ needStored |= p.stored.endsWith(')');
+ needEditable |= p.editable.endsWith(')');
+ needUser |= p.user.endsWith(')');
+ }
+ fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n ");
+
+ if (needElse)
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::ReadProperty) {\n");
+ if (needGet) {
+ if (needTempVarForGet)
+ fprintf(out, " void *_v = _a[0];\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (p.read.isEmpty())
+ continue;
+ QByteArray prefix;
+ if (p.inPrivateClass.size()) {
+ prefix = p.inPrivateClass;
+ prefix.append("->");
+ }
+ if (p.gspec == PropertyDef::PointerSpec)
+ fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s%s())); break;\n",
+ propindex, prefix.constData(), p.read.constData());
+ else if (p.gspec == PropertyDef::ReferenceSpec)
+ fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
+ propindex, prefix.constData(), p.read.constData());
+ else if (cdef->enumDeclarations.value(p.type, false))
+ fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
+ propindex, prefix.constData(), p.read.constData());
+ else
+ fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
+ propindex, p.type.constData(), prefix.constData(), p.read.constData());
+ }
+ fprintf(out, " }\n");
+ }
+
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::WriteProperty) {\n");
+
+ if (needSet) {
+ fprintf(out, " void *_v = _a[0];\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (p.write.isEmpty())
+ continue;
+ QByteArray prefix;
+ if (p.inPrivateClass.size()) {
+ prefix = p.inPrivateClass;
+ prefix.append("->");
+ }
+ if (cdef->enumDeclarations.value(p.type, false)) {
+ fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
+ propindex, prefix.constData(), p.write.constData());
+ } else {
+ fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
+ propindex, prefix.constData(), p.write.constData(), p.type.constData());
+ }
+ }
+ fprintf(out, " }\n");
+ }
+
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::ResetProperty) {\n");
+ if (needReset) {
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.reset.endsWith(')'))
+ continue;
+ QByteArray prefix;
+ if (p.inPrivateClass.size()) {
+ prefix = p.inPrivateClass;
+ prefix.append("->");
+ }
+ fprintf(out, " case %d: %s%s; break;\n",
+ propindex, prefix.constData(), p.reset.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyDesignable) {\n");
+ if (needDesignable) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.designable.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.designable.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyScriptable) {\n");
+ if (needScriptable) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.scriptable.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.scriptable.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyStored) {\n");
+ if (needStored) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.stored.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.stored.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyEditable) {\n");
+ if (needEditable) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.editable.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.editable.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+
+ fprintf(out, " else ");
+ fprintf(out, "if (_c == QMetaObject::QueryPropertyUser) {\n");
+ if (needUser) {
+ fprintf(out, " bool *_b = reinterpret_cast<bool*>(_a[0]);\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) {
+ const PropertyDef &p = cdef->propertyList.at(propindex);
+ if (!p.user.endsWith(')'))
+ continue;
+ fprintf(out, " case %d: *_b = %s; break;\n",
+ propindex, p.user.constData());
+ }
+ fprintf(out, " }\n");
+ }
+ fprintf(out,
+ " _id -= %d;\n"
+ " }", cdef->propertyList.count());
+
+
+ fprintf(out, "\n#endif // QT_NO_PROPERTIES");
+ }
+ if (methodList.size() || cdef->signalList.size() || cdef->propertyList.size())
+ fprintf(out, "\n ");
+ fprintf(out,"return _id;\n}\n");
+}
+
+void Generator::generateStaticMetacall()
+{
+ fprintf(out, "void %s::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)\n{\n",
+ cdef->qualified.constData());
+
+ bool needElse = false;
+ bool isUsed_a = false;
+
+ if (!cdef->constructorList.isEmpty()) {
+ fprintf(out, " if (_c == QMetaObject::CreateInstance) {\n");
+ fprintf(out, " switch (_id) {\n");
+ for (int ctorindex = 0; ctorindex < cdef->constructorList.count(); ++ctorindex) {
+ fprintf(out, " case %d: { %s *_r = new %s(", ctorindex,
+ cdef->classname.constData(), cdef->classname.constData());
+ const FunctionDef &f = cdef->constructorList.at(ctorindex);
+ int offset = 1;
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))", a.typeNameForCast.constData(), offset++);
+ }
+ fprintf(out, ");\n");
+ fprintf(out, " if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;\n");
+ }
+ fprintf(out, " }\n");
+ fprintf(out, " }");
+ needElse = true;
+ isUsed_a = true;
+ }
+
+ QList<FunctionDef> methodList;
+ methodList += cdef->signalList;
+ methodList += cdef->slotList;
+ methodList += cdef->methodList;
+
+ if (!methodList.isEmpty()) {
+ if (needElse)
+ fprintf(out, " else ");
+ else
+ fprintf(out, " ");
+ fprintf(out, "if (_c == QMetaObject::InvokeMetaMethod) {\n");
+#ifndef QT_NO_DEBUG
+ fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n");
+#endif
+ fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData());
+ fprintf(out, " switch (_id) {\n");
+ for (int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
+ const FunctionDef &f = methodList.at(methodindex);
+ fprintf(out, " case %d: ", methodindex);
+ if (f.normalizedType.size())
+ fprintf(out, "{ %s _r = ", noRef(f.normalizedType).constData());
+ fprintf(out, "_t->");
+ if (f.inPrivateClass.size())
+ fprintf(out, "%s->", f.inPrivateClass.constData());
+ fprintf(out, "%s(", f.name.constData());
+ int offset = 1;
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j)
+ fprintf(out, ",");
+ fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
+ isUsed_a = true;
+ }
+ fprintf(out, ");");
+ if (f.normalizedType.size()) {
+ fprintf(out, "\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = _r; } ",
+ noRef(f.normalizedType).constData());
+ isUsed_a = true;
+ }
+ fprintf(out, " break;\n");
+ }
+ fprintf(out, " default: ;\n");
+ fprintf(out, " }\n");
+ fprintf(out, " }");
+ needElse = true;
+ }
+
+ if (needElse)
+ fprintf(out, "\n");
+
+ if (methodList.isEmpty()) {
+ fprintf(out, " Q_UNUSED(_o);\n");
+ if (cdef->constructorList.isEmpty()) {
+ fprintf(out, " Q_UNUSED(_id);\n");
+ fprintf(out, " Q_UNUSED(_c);\n");
+ }
+ }
+ if (!isUsed_a)
+ fprintf(out, " Q_UNUSED(_a);\n");
+
+ fprintf(out, "}\n\n");
+}
+
+void Generator::generateSignal(FunctionDef *def,int index)
+{
+ if (def->wasCloned || def->isAbstract)
+ return;
+ fprintf(out, "\n// SIGNAL %d\n%s %s::%s(",
+ index, def->type.name.constData(), cdef->qualified.constData(), def->name.constData());
+
+ QByteArray thisPtr = "this";
+ const char *constQualifier = "";
+
+ if (def->isConst) {
+ thisPtr = "const_cast< ";
+ thisPtr += cdef->qualified;
+ thisPtr += " *>(this)";
+ constQualifier = "const";
+ }
+
+ if (def->arguments.isEmpty() && def->normalizedType.isEmpty()) {
+ fprintf(out, ")%s\n{\n"
+ " QMetaObject::activate(%s, &staticMetaObject, %d, 0);\n"
+ "}\n", constQualifier, thisPtr.constData(), index);
+ return;
+ }
+
+ int offset = 1;
+ for (int j = 0; j < def->arguments.count(); ++j) {
+ const ArgumentDef &a = def->arguments.at(j);
+ if (j)
+ fprintf(out, ", ");
+ fprintf(out, "%s _t%d%s", a.type.name.constData(), offset++, a.rightType.constData());
+ }
+ fprintf(out, ")%s\n{\n", constQualifier);
+ if (def->type.name.size() && def->normalizedType.size())
+ fprintf(out, " %s _t0;\n", noRef(def->normalizedType).constData());
+
+ fprintf(out, " void *_a[] = { ");
+ if (def->normalizedType.isEmpty()) {
+ fprintf(out, "0");
+ } else {
+ if (def->returnTypeIsVolatile)
+ fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))");
+ else
+ fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(&_t0))");
+ }
+ int i;
+ for (i = 1; i < offset; ++i)
+ if (def->arguments.at(i - 1).type.isVolatile)
+ fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(&_t%d))", i);
+ else
+ fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i);
+ fprintf(out, " };\n");
+ fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
+ if (def->normalizedType.size())
+ fprintf(out, " return _t0;\n");
+ fprintf(out, "}\n");
+}
+
+//
+// Functions used when generating QMetaObject directly
+//
+// Much of this code is copied from the corresponding
+// C++ code-generating functions; we can change the
+// two generators so that more of the code is shared.
+// The key difference from the C++ code generator is
+// that instead of calling fprintf(), we append bytes
+// to a buffer.
+//
+
+QMetaObject *Generator::generateMetaObject(bool ignoreProperties)
+{
+//
+// build the data array
+//
+
+ // filter out undeclared enumerators and sets
+ {
+ QList<EnumDef> enumList;
+ for (int i = 0; i < cdef->enumList.count(); ++i) {
+ EnumDef def = cdef->enumList.at(i);
+ if (cdef->enumDeclarations.contains(def.name)) {
+ enumList += def;
+ }
+ QByteArray alias = cdef->flagAliases.value(def.name);
+ if (cdef->enumDeclarations.contains(alias)) {
+ def.name = alias;
+ enumList += def;
+ }
+ }
+ cdef->enumList = enumList;
+ }
+
+ int index = 10;
+ meta_data
+ << 1 // revision
+ << strreg(cdef->qualified) // classname
+ << cdef->classInfoList.count() << (cdef->classInfoList.count() ? index : 0) // classinfo
+ ;
+ index += cdef->classInfoList.count() * 2;
+
+ int methodCount = cdef->signalList.count() + cdef->slotList.count() + cdef->methodList.count();
+ meta_data << methodCount << (methodCount ? index : 0); // methods
+ index += methodCount * 5;
+ if (!ignoreProperties) {
+ meta_data << cdef->propertyList.count() << (cdef->propertyList.count() ? index : 0); // properties
+ index += cdef->propertyList.count() * 3;
+ } else {
+ meta_data << 0 << 0; // properties
+ }
+ meta_data << cdef->enumList.count() << (cdef->enumList.count() ? index : 0); // enums/sets
+
+//
+// Build classinfo array
+//
+ _generateClassInfos();
+
+//
+// Build signals array first, otherwise the signal indices would be wrong
+//
+ _generateFunctions(cdef->signalList, MethodSignal);
+
+//
+// Build slots array
+//
+ _generateFunctions(cdef->slotList, MethodSlot);
+
+//
+// Build method array
+//
+ _generateFunctions(cdef->methodList, MethodMethod);
+
+
+//
+// Build property array
+//
+ if (!ignoreProperties)
+ _generateProperties();
+
+//
+// Build enums array
+//
+ _generateEnums(index);
+
+//
+// Terminate data array
+//
+ meta_data << 0;
+
+//
+// Build stringdata array
+//
+ QVector<char> string_data;
+ for (int i = 0; i < strings.size(); ++i) {
+ const char *s = strings.at(i).constData();
+ char c;
+ do {
+ c = *(s++);
+ string_data << c;
+ } while (c != '\0');
+ }
+
+//
+// Finally create and initialize the static meta object
+//
+ const int meta_object_offset = 0;
+ const int meta_object_size = sizeof(QMetaObject);
+ const int meta_data_offset = meta_object_offset + meta_object_size;
+ const int meta_data_size = meta_data.count() * sizeof(uint);
+ const int string_data_offset = meta_data_offset + meta_data_size;
+ const int string_data_size = string_data.count();
+ const int total_size = string_data_offset + string_data_size;
+
+ char *blob = new char[total_size];
+
+ char *string_data_output = blob + string_data_offset;
+ const char *string_data_src = string_data.constData();
+ for (int i = 0; i < string_data.count(); ++i)
+ string_data_output[i] = string_data_src[i];
+
+ uint *meta_data_output = reinterpret_cast<uint *>(blob + meta_data_offset);
+ const uint *meta_data_src = meta_data.constData();
+ for (int i = 0; i < meta_data.count(); ++i)
+ meta_data_output[i] = meta_data_src[i];
+
+ QMetaObject *meta_object = new (blob + meta_object_offset)QMetaObject;
+ meta_object->d.superdata = 0;
+ meta_object->d.stringdata = string_data_output;
+ meta_object->d.data = meta_data_output;
+ meta_object->d.extradata = 0;
+ return meta_object;
+}
+
+void Generator::_generateClassInfos()
+{
+ for (int i = 0; i < cdef->classInfoList.size(); ++i) {
+ const ClassInfoDef &c = cdef->classInfoList.at(i);
+ meta_data << strreg(c.name) << strreg(c.value);
+ }
+}
+
+void Generator::_generateFunctions(QList<FunctionDef> &list, int type)
+{
+ for (int i = 0; i < list.count(); ++i) {
+ const FunctionDef &f = list.at(i);
+
+ QByteArray sig = f.name + '(';
+ QByteArray arguments;
+
+ for (int j = 0; j < f.arguments.count(); ++j) {
+ const ArgumentDef &a = f.arguments.at(j);
+ if (j) {
+ sig += ',';
+ arguments += ',';
+ }
+ sig += a.normalizedType;
+ arguments += a.name;
+ }
+ sig += ')';
+
+ char flags = type;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.access == FunctionDef::Private)
+ flags |= AccessPrivate;
+ else if (f.access == FunctionDef::Public)
+ flags |= AccessPublic;
+ else if (f.access == FunctionDef::Protected)
+ flags |= AccessProtected;
+ if (f.isCompat)
+ flags |= MethodCompatibility;
+ if (f.wasCloned)
+ flags |= MethodCloned;
+ if (f.isScriptable)
+ flags |= MethodScriptable;
+
+ meta_data << strreg(sig)
+ << strreg(arguments)
+ << strreg(f.normalizedType)
+ << strreg(f.tag)
+ << flags;
+ }
+}
+
+void Generator::_generateEnums(int index)
+{
+ index += 4 * cdef->enumList.count();
+ int i;
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ meta_data << strreg(e.name) << (cdef->enumDeclarations.value(e.name) ? 1 : 0)
+ << e.values.count() << index;
+ index += e.values.count() * 2;
+ }
+
+ for (i = 0; i < cdef->enumList.count(); ++i) {
+ const EnumDef &e = cdef->enumList.at(i);
+ for (int j = 0; j < e.values.count(); ++j) {
+ const QByteArray &val = e.values.at(j);
+ meta_data << strreg(val) << 0; // we don't know the value itself
+ }
+ }
+}
+
+void Generator::_generateProperties()
+{
+ //
+ // specify get function, for compatibiliy we accept functions
+ // returning pointers, or const char * for QByteArray.
+ //
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ PropertyDef &p = cdef->propertyList[i];
+ if (p.read.isEmpty())
+ continue;
+ for (int j = 0; j < cdef->publicList.count(); ++j) {
+ const FunctionDef &f = cdef->publicList.at(j);
+ if (f.name != p.read)
+ continue;
+ if (!f.isConst) // get functions must be const
+ continue;
+ if (f.arguments.size()) // and must not take any arguments
+ continue;
+ PropertyDef::Specification spec = PropertyDef::ValueSpec;
+ QByteArray tmp = f.normalizedType;
+ if (p.type == "QByteArray" && tmp == "const char *")
+ tmp = "QByteArray";
+ if (tmp.left(6) == "const ")
+ tmp = tmp.mid(6);
+ if (p.type != tmp && tmp.endsWith('*')) {
+ tmp.chop(1);
+ spec = PropertyDef::PointerSpec;
+ } else if (f.type.name.endsWith('&')) { // raw type, not normalized type
+ spec = PropertyDef::ReferenceSpec;
+ }
+ if (p.type != tmp)
+ continue;
+ p.gspec = spec;
+ break;
+ }
+ }
+
+
+ //
+ // Create meta data
+ //
+
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ const PropertyDef &p = cdef->propertyList.at(i);
+ uint flags = Invalid;
+ if (!isVariantType(p.type)) {
+ flags |= EnumOrFlag;
+ } else {
+ flags |= qvariant_nameToType(p.type) << 24;
+ }
+ if (!p.read.isEmpty())
+ flags |= Readable;
+ if (!p.write.isEmpty()) {
+ flags |= Writable;
+ if (p.stdCppSet())
+ flags |= StdCppSet;
+ }
+ if (!p.reset.isEmpty())
+ flags |= Resettable;
+
+// if (p.override)
+// flags |= Override;
+
+ if (p.designable.isEmpty())
+ flags |= ResolveDesignable;
+ else if (p.designable != "false")
+ flags |= Designable;
+
+ if (p.scriptable.isEmpty())
+ flags |= ResolveScriptable;
+ else if (p.scriptable != "false")
+ flags |= Scriptable;
+
+ if (p.stored.isEmpty())
+ flags |= ResolveStored;
+ else if (p.stored != "false")
+ flags |= Stored;
+
+ if (p.editable.isEmpty())
+ flags |= ResolveEditable;
+ else if (p.editable != "false")
+ flags |= Editable;
+
+ if (p.user.isEmpty())
+ flags |= ResolveUser;
+ else if (p.user != "false")
+ flags |= User;
+
+ meta_data << strreg(p.name) << strreg(p.type) << flags;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
new file mode 100644
index 0000000000..fa5885f0e1
--- /dev/null
+++ b/src/tools/moc/generator.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include "moc.h"
+
+QT_BEGIN_NAMESPACE
+
+class Generator
+{
+ FILE *out;
+ ClassDef *cdef;
+ QVector<uint> meta_data;
+public:
+ Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0);
+ void generateCode();
+ QMetaObject *generateMetaObject(bool ignoreProperties);
+private:
+ void generateClassInfos();
+ void generateFunctions(QList<FunctionDef> &list, const char *functype, int type);
+ void generateFunctionRevisions(QList<FunctionDef>& list, const char *functype);
+ void generateEnums(int index);
+ void generateProperties();
+ void generateMetacall();
+ void generateStaticMetacall();
+ void generateSignal(FunctionDef *def, int index);
+
+ // used by binary QMetaObject generator
+ void _generateClassInfos();
+ void _generateFunctions(QList<FunctionDef> &list, int type);
+ void _generateEnums(int index);
+ void _generateProperties();
+
+ int strreg(const char *); // registers a string and returns its id
+ QList<QByteArray> strings;
+ QByteArray purestSuperClass;
+ QList<QByteArray> metaTypes;
+};
+
+QT_END_NAMESPACE
+
+#endif // GENERATOR_H
diff --git a/src/tools/moc/keywords.cpp b/src/tools/moc/keywords.cpp
new file mode 100644
index 0000000000..9a8aa416e8
--- /dev/null
+++ b/src/tools/moc/keywords.cpp
@@ -0,0 +1,1003 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// auto generated
+// DO NOT EDIT.
+
+static const short keyword_trans[][128] = {
+ {0,0,0,0,0,0,0,0,0,541,538,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 541,252,539,542,0,38,239,540,25,26,236,234,30,235,27,237,
+ 22,22,22,22,22,22,22,22,22,22,34,41,23,39,24,43,
+ 0,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,21,8,8,8,8,8,8,8,8,8,31,543,32,238,8,
+ 0,1,2,3,4,5,6,7,8,9,8,8,10,11,12,13,
+ 14,8,15,16,17,18,19,20,8,8,8,36,245,37,248,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,192,0,173,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,240,0,0,0,0,0,287,
+ 0,0,341,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,109,0,0,0,0,0,0,280,0,0,0,121,0,0,80,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,229,0,0,0,0,0,0,0,0,0,312,
+ 0,0,0,0,0,0,0,0,0,44,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,327,0,133,0,
+ 0,0,0,0,0,0,0,0,168,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,339,
+ 0,0,116,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,326,0,0,0,0,0,0,0,198,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,125,0,0,0,227,0,0,0,0,0,0,0,0,0,253,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,150,0,0,163,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,290,222,0,0,461,0,0,0,
+ 0,0,0,0,55,0,0,330,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,97,0,0,94,0,0,0,0,0,0,0,
+ 0,0,107,0,0,0,0,0,0,89,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,0,
+ 0,0,0,194,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,144,0,0,0,0,0,208,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,283,0,0,0,0,335,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,485,0,0,0,0,0,0,0,0,0,0,357,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,33,0,263,272,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,273,264,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,42,0,0,0,28,0,
+ 546,546,546,546,546,546,546,546,546,546,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,40,0,0,0,32,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,259,37,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,136,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,176,0,66,0,0,0,0,0,0,
+ 0,0,0,0,353,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,249,81,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,82,345,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,113,0,0,0,0,92,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,95,0,0,0,0,0,0,
+ 0,0,104,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,319,110,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,141,0,0,0,0,0,0,
+ 0,0,0,302,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,151,0,0,0,0,0,156,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 169,0,0,0,182,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,203,0,0,170,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,199,0,0,0,
+ 0,0,0,0,294,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,317,0,0,209,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,298,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,223,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,321,0,0,0,0,0,230,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,276,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,277,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,256,278,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,545,0,0,0,0,544,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,274,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,261,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,242,0,0,0,0,0,0,0,0,0,0,0,0,0,246,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,262,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,275,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,458,0,0,0,300,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,439,388,378,383,364,0,448,0,0,0,0,0,358,
+ 370,0,530,436,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,475,0,0,0,0,0,372,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,418,396,0,0,401,0,0,0,410,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,513,0,437,0,0,0,465,0,0,471,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,450,0,506,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 522,0,0,481,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,497,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,486,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
+
+static const struct
+{
+ Token token;
+ short next;
+ char defchar;
+ short defnext;
+ Token ident;
+} keywords[] = {
+ {NOTOKEN, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 1, 0, 0, NOTOKEN},
+ {CHARACTER, 2, 0, 0, NOTOKEN},
+ {CHARACTER, 3, 0, 0, NOTOKEN},
+ {CHARACTER, 4, 0, 0, NOTOKEN},
+ {CHARACTER, 5, 0, 0, NOTOKEN},
+ {CHARACTER, 6, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 111, 350, NOTOKEN},
+ {CHARACTER, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 7, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 111, 295, NOTOKEN},
+ {CHARACTER, 0, 117, 186, NOTOKEN},
+ {CHARACTER, 8, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 112, 215, NOTOKEN},
+ {CHARACTER, 9, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 101, 65, NOTOKEN},
+ {CHARACTER, 10, 0, 0, NOTOKEN},
+ {CHARACTER, 11, 0, 0, NOTOKEN},
+ {CHARACTER, 12, 0, 0, NOTOKEN},
+ {CHARACTER, 13, 0, 0, NOTOKEN},
+ {CHARACTER, 14, 0, 0, NOTOKEN},
+ {CHARACTER, 15, 0, 0, NOTOKEN},
+ {DIGIT, 0, 0, 0, NOTOKEN},
+ {LANGLE, 16, 0, 0, NOTOKEN},
+ {RANGLE, 17, 0, 0, NOTOKEN},
+ {LPAREN, 0, 0, 0, NOTOKEN},
+ {RPAREN, 0, 0, 0, NOTOKEN},
+ {DOT, 18, 0, 0, NOTOKEN},
+ {INCOMPLETE, 0, 46, 29, NOTOKEN},
+ {ELIPSIS, 0, 0, 0, NOTOKEN},
+ {COMMA, 0, 0, 0, NOTOKEN},
+ {LBRACK, 0, 0, 0, NOTOKEN},
+ {RBRACK, 0, 0, 0, NOTOKEN},
+ {LBRACK, 0, 58, 35, NOTOKEN},
+ {COLON, 19, 0, 0, NOTOKEN},
+ {LANGLE_SCOPE, 0, 0, 0, NOTOKEN},
+ {LBRACE, 0, 0, 0, NOTOKEN},
+ {RBRACE, 0, 0, 0, NOTOKEN},
+ {PERCENT, 20, 0, 0, NOTOKEN},
+ {EQ, 0, 61, 267, NOTOKEN},
+ {SCOPE, 0, 0, 0, NOTOKEN},
+ {SEMIC, 0, 0, 0, NOTOKEN},
+ {DOTSTAR, 0, 0, 0, NOTOKEN},
+ {QUESTION, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 110, 45, CHARACTER},
+ {CHARACTER, 0, 97, 46, CHARACTER},
+ {CHARACTER, 0, 109, 47, CHARACTER},
+ {CHARACTER, 0, 105, 48, CHARACTER},
+ {CHARACTER, 0, 99, 49, CHARACTER},
+ {CHARACTER, 0, 95, 50, CHARACTER},
+ {CHARACTER, 0, 99, 51, CHARACTER},
+ {CHARACTER, 0, 97, 52, CHARACTER},
+ {CHARACTER, 0, 115, 53, CHARACTER},
+ {CHARACTER, 0, 116, 54, CHARACTER},
+ {DYNAMIC_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 21, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 57, CHARACTER},
+ {CHARACTER, 0, 105, 58, CHARACTER},
+ {CHARACTER, 0, 99, 59, CHARACTER},
+ {STATIC, 0, 95, 60, CHARACTER},
+ {CHARACTER, 0, 99, 61, CHARACTER},
+ {CHARACTER, 0, 97, 62, CHARACTER},
+ {CHARACTER, 0, 115, 63, CHARACTER},
+ {CHARACTER, 0, 116, 64, CHARACTER},
+ {STATIC_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 22, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 67, CHARACTER},
+ {CHARACTER, 0, 116, 68, CHARACTER},
+ {CHARACTER, 0, 101, 69, CHARACTER},
+ {CHARACTER, 0, 114, 70, CHARACTER},
+ {CHARACTER, 0, 112, 71, CHARACTER},
+ {CHARACTER, 0, 114, 72, CHARACTER},
+ {CHARACTER, 0, 101, 73, CHARACTER},
+ {CHARACTER, 0, 116, 74, CHARACTER},
+ {CHARACTER, 0, 95, 75, CHARACTER},
+ {CHARACTER, 0, 99, 76, CHARACTER},
+ {CHARACTER, 0, 97, 77, CHARACTER},
+ {CHARACTER, 0, 115, 78, CHARACTER},
+ {CHARACTER, 0, 116, 79, CHARACTER},
+ {REINTERPRET_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 23, 0, 0, CHARACTER},
+ {CHARACTER, 24, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 83, CHARACTER},
+ {CONST, 0, 95, 84, CHARACTER},
+ {CHARACTER, 0, 99, 85, CHARACTER},
+ {CHARACTER, 0, 97, 86, CHARACTER},
+ {CHARACTER, 0, 115, 87, CHARACTER},
+ {CHARACTER, 0, 116, 88, CHARACTER},
+ {CONST_CAST, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 112, 90, CHARACTER},
+ {CHARACTER, 0, 101, 91, CHARACTER},
+ {CHARACTER, 25, 0, 0, CHARACTER},
+ {CHARACTER, 0, 100, 93, CHARACTER},
+ {TYPEID, 0, 0, 0, CHARACTER},
+ {CHARACTER, 26, 0, 0, CHARACTER},
+ {CHARACTER, 0, 115, 96, CHARACTER},
+ {THIS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 109, 98, CHARACTER},
+ {CHARACTER, 0, 112, 99, CHARACTER},
+ {CHARACTER, 0, 108, 100, CHARACTER},
+ {CHARACTER, 0, 97, 101, CHARACTER},
+ {CHARACTER, 0, 116, 102, CHARACTER},
+ {CHARACTER, 0, 101, 103, CHARACTER},
+ {TEMPLATE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 105, CHARACTER},
+ {CHARACTER, 0, 119, 106, CHARACTER},
+ {THROW, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 121, 108, CHARACTER},
+ {TRY, 0, 0, 0, CHARACTER},
+ {CHARACTER, 27, 0, 0, CHARACTER},
+ {CHARACTER, 0, 99, 111, CHARACTER},
+ {CHARACTER, 0, 104, 112, CHARACTER},
+ {CATCH, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 114, CHARACTER},
+ {CHARACTER, 0, 102, 115, CHARACTER},
+ {TYPEDEF, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 117, CHARACTER},
+ {CHARACTER, 0, 101, 118, CHARACTER},
+ {CHARACTER, 0, 110, 119, CHARACTER},
+ {CHARACTER, 0, 100, 120, CHARACTER},
+ {FRIEND, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 97, 122, CHARACTER},
+ {CHARACTER, 0, 115, 123, CHARACTER},
+ {CHARACTER, 0, 115, 124, CHARACTER},
+ {CLASS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 109, 126, CHARACTER},
+ {CHARACTER, 0, 101, 127, CHARACTER},
+ {CHARACTER, 0, 115, 128, CHARACTER},
+ {CHARACTER, 0, 112, 129, CHARACTER},
+ {CHARACTER, 0, 97, 130, CHARACTER},
+ {CHARACTER, 0, 99, 131, CHARACTER},
+ {CHARACTER, 0, 101, 132, CHARACTER},
+ {NAMESPACE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 117, 134, CHARACTER},
+ {CHARACTER, 0, 109, 135, CHARACTER},
+ {ENUM, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 117, 137, CHARACTER},
+ {CHARACTER, 0, 99, 138, CHARACTER},
+ {CHARACTER, 0, 116, 139, CHARACTER},
+ {STRUCT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 28, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 142, CHARACTER},
+ {CHARACTER, 0, 110, 143, CHARACTER},
+ {UNION, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 114, 145, CHARACTER},
+ {CHARACTER, 0, 116, 146, CHARACTER},
+ {CHARACTER, 0, 117, 147, CHARACTER},
+ {CHARACTER, 0, 97, 148, CHARACTER},
+ {CHARACTER, 0, 108, 149, CHARACTER},
+ {VIRTUAL, 0, 0, 0, CHARACTER},
+ {CHARACTER, 29, 0, 0, CHARACTER},
+ {CHARACTER, 0, 118, 152, CHARACTER},
+ {CHARACTER, 0, 97, 153, CHARACTER},
+ {CHARACTER, 0, 116, 154, CHARACTER},
+ {CHARACTER, 0, 101, 155, CHARACTER},
+ {PRIVATE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 157, CHARACTER},
+ {CHARACTER, 0, 101, 158, CHARACTER},
+ {CHARACTER, 0, 99, 159, CHARACTER},
+ {CHARACTER, 0, 116, 160, CHARACTER},
+ {CHARACTER, 0, 101, 161, CHARACTER},
+ {CHARACTER, 0, 100, 162, CHARACTER},
+ {PROTECTED, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 98, 164, CHARACTER},
+ {CHARACTER, 0, 108, 165, CHARACTER},
+ {CHARACTER, 0, 105, 166, CHARACTER},
+ {CHARACTER, 0, 99, 167, CHARACTER},
+ {PUBLIC, 0, 0, 0, CHARACTER},
+ {CHARACTER, 30, 0, 0, CHARACTER},
+ {CHARACTER, 31, 0, 0, CHARACTER},
+ {CHARACTER, 0, 114, 171, CHARACTER},
+ {CHARACTER, 0, 116, 172, CHARACTER},
+ {EXPORT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 174, CHARACTER},
+ {CHARACTER, 0, 111, 175, CHARACTER},
+ {AUTO, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 177, CHARACTER},
+ {CHARACTER, 0, 115, 178, CHARACTER},
+ {CHARACTER, 0, 116, 179, CHARACTER},
+ {CHARACTER, 0, 101, 180, CHARACTER},
+ {CHARACTER, 0, 114, 181, CHARACTER},
+ {REGISTER, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 183, CHARACTER},
+ {CHARACTER, 0, 114, 184, CHARACTER},
+ {CHARACTER, 0, 110, 185, CHARACTER},
+ {EXTERN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 187, CHARACTER},
+ {CHARACTER, 0, 97, 188, CHARACTER},
+ {CHARACTER, 0, 98, 189, CHARACTER},
+ {CHARACTER, 0, 108, 190, CHARACTER},
+ {CHARACTER, 0, 101, 191, CHARACTER},
+ {MUTABLE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 109, 193, CHARACTER},
+ {ASM, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 195, CHARACTER},
+ {CHARACTER, 0, 110, 196, CHARACTER},
+ {CHARACTER, 0, 103, 197, CHARACTER},
+ {USING, 0, 0, 0, CHARACTER},
+ {CHARACTER, 32, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 200, CHARACTER},
+ {CHARACTER, 0, 110, 201, CHARACTER},
+ {CHARACTER, 0, 101, 202, CHARACTER},
+ {INLINE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 204, CHARACTER},
+ {CHARACTER, 0, 99, 205, CHARACTER},
+ {CHARACTER, 0, 105, 206, CHARACTER},
+ {CHARACTER, 0, 116, 207, CHARACTER},
+ {EXPLICIT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 33, 0, 0, CHARACTER},
+ {CHARACTER, 0, 97, 210, CHARACTER},
+ {CHARACTER, 0, 116, 211, CHARACTER},
+ {CHARACTER, 0, 105, 212, CHARACTER},
+ {CHARACTER, 0, 108, 213, CHARACTER},
+ {CHARACTER, 0, 101, 214, CHARACTER},
+ {VOLATILE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 216, CHARACTER},
+ {CHARACTER, 0, 114, 217, CHARACTER},
+ {CHARACTER, 0, 97, 218, CHARACTER},
+ {CHARACTER, 0, 116, 219, CHARACTER},
+ {CHARACTER, 0, 111, 220, CHARACTER},
+ {CHARACTER, 0, 114, 221, CHARACTER},
+ {OPERATOR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 34, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 224, CHARACTER},
+ {CHARACTER, 0, 111, 225, CHARACTER},
+ {CHARACTER, 0, 102, 226, CHARACTER},
+ {SIZEOF, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 119, 228, CHARACTER},
+ {NEW, 0, 0, 0, CHARACTER},
+ {CHARACTER, 35, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 231, CHARACTER},
+ {CHARACTER, 0, 116, 232, CHARACTER},
+ {CHARACTER, 0, 101, 233, CHARACTER},
+ {DELETE, 0, 0, 0, CHARACTER},
+ {PLUS, 36, 0, 0, NOTOKEN},
+ {MINUS, 37, 0, 0, NOTOKEN},
+ {STAR, 0, 61, 257, NOTOKEN},
+ {SLASH, 38, 0, 0, NOTOKEN},
+ {HAT, 0, 61, 260, NOTOKEN},
+ {AND, 39, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 116, 241, CHARACTER},
+ {CHARACTER, 40, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 243, CHARACTER},
+ {CHARACTER, 0, 100, 244, CHARACTER},
+ {AND, 0, 0, 0, CHARACTER},
+ {OR, 41, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 114, 247, CHARACTER},
+ {OR, 0, 0, 0, CHARACTER},
+ {TILDE, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 112, 250, CHARACTER},
+ {CHARACTER, 0, 108, 251, CHARACTER},
+ {TILDE, 0, 0, 0, CHARACTER},
+ {NOT, 0, 61, 268, NOTOKEN},
+ {CHARACTER, 0, 116, 254, CHARACTER},
+ {NOT, 0, 95, 269, CHARACTER},
+ {PLUS_EQ, 0, 0, 0, NOTOKEN},
+ {MINUS_EQ, 0, 0, 0, NOTOKEN},
+ {STAR_EQ, 0, 0, 0, NOTOKEN},
+ {SLASH_EQ, 0, 0, 0, NOTOKEN},
+ {PERCENT_EQ, 0, 0, 0, NOTOKEN},
+ {HAT_EQ, 0, 0, 0, NOTOKEN},
+ {AND_EQ, 0, 0, 0, NOTOKEN},
+ {OR_EQ, 0, 0, 0, NOTOKEN},
+ {LTLT, 0, 61, 266, NOTOKEN},
+ {GTGT, 0, 61, 265, NOTOKEN},
+ {GTGT_EQ, 0, 0, 0, NOTOKEN},
+ {LTLT_EQ, 0, 0, 0, NOTOKEN},
+ {EQEQ, 0, 0, 0, NOTOKEN},
+ {NE, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 101, 270, CHARACTER},
+ {CHARACTER, 0, 113, 271, CHARACTER},
+ {NE, 0, 0, 0, CHARACTER},
+ {LE, 0, 0, 0, NOTOKEN},
+ {GE, 0, 0, 0, NOTOKEN},
+ {ANDAND, 0, 0, 0, NOTOKEN},
+ {OROR, 0, 0, 0, NOTOKEN},
+ {INCR, 0, 0, 0, NOTOKEN},
+ {DECR, 0, 0, 0, NOTOKEN},
+ {ARROW, 0, 42, 279, NOTOKEN},
+ {ARROW_STAR, 0, 0, 0, NOTOKEN},
+ {CHARACTER, 0, 97, 281, CHARACTER},
+ {CHARACTER, 0, 114, 282, CHARACTER},
+ {CHAR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 104, 284, CHARACTER},
+ {CHARACTER, 0, 97, 285, CHARACTER},
+ {CHARACTER, 0, 114, 286, CHARACTER},
+ {WCHAR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 288, CHARACTER},
+ {CHARACTER, 0, 108, 289, CHARACTER},
+ {BOOL, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 291, CHARACTER},
+ {CHARACTER, 0, 114, 292, CHARACTER},
+ {CHARACTER, 0, 116, 293, CHARACTER},
+ {SHORT, 0, 0, 0, CHARACTER},
+ {INT, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 296, CHARACTER},
+ {CHARACTER, 0, 103, 297, CHARACTER},
+ {LONG, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 110, 299, CHARACTER},
+ {CHARACTER, 42, 0, 0, CHARACTER},
+ {CHARACTER, 0, 100, 301, CHARACTER},
+ {SIGNED, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 303, CHARACTER},
+ {CHARACTER, 0, 103, 304, CHARACTER},
+ {CHARACTER, 0, 110, 305, CHARACTER},
+ {CHARACTER, 0, 101, 306, CHARACTER},
+ {CHARACTER, 0, 100, 307, CHARACTER},
+ {UNSIGNED, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 309, CHARACTER},
+ {CHARACTER, 0, 97, 310, CHARACTER},
+ {CHARACTER, 0, 116, 311, CHARACTER},
+ {FLOAT, 0, 0, 0, CHARACTER},
+ {DO, 0, 117, 313, CHARACTER},
+ {CHARACTER, 0, 98, 314, CHARACTER},
+ {CHARACTER, 0, 108, 315, CHARACTER},
+ {CHARACTER, 0, 101, 316, CHARACTER},
+ {DOUBLE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 100, 318, CHARACTER},
+ {VOID, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 320, CHARACTER},
+ {CASE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 97, 322, CHARACTER},
+ {CHARACTER, 0, 117, 323, CHARACTER},
+ {CHARACTER, 0, 108, 324, CHARACTER},
+ {CHARACTER, 0, 116, 325, CHARACTER},
+ {DEFAULT, 0, 0, 0, CHARACTER},
+ {IF, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 115, 328, CHARACTER},
+ {CHARACTER, 0, 101, 329, CHARACTER},
+ {ELSE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 331, CHARACTER},
+ {CHARACTER, 0, 116, 332, CHARACTER},
+ {CHARACTER, 0, 99, 333, CHARACTER},
+ {CHARACTER, 0, 104, 334, CHARACTER},
+ {SWITCH, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 336, CHARACTER},
+ {CHARACTER, 0, 108, 337, CHARACTER},
+ {CHARACTER, 0, 101, 338, CHARACTER},
+ {WHILE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 114, 340, CHARACTER},
+ {FOR, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 101, 342, CHARACTER},
+ {CHARACTER, 0, 97, 343, CHARACTER},
+ {CHARACTER, 0, 107, 344, CHARACTER},
+ {BREAK, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 105, 346, CHARACTER},
+ {CHARACTER, 0, 110, 347, CHARACTER},
+ {CHARACTER, 0, 117, 348, CHARACTER},
+ {CHARACTER, 0, 101, 349, CHARACTER},
+ {CONTINUE, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 116, 351, CHARACTER},
+ {CHARACTER, 0, 111, 352, CHARACTER},
+ {GOTO, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 117, 354, CHARACTER},
+ {CHARACTER, 0, 114, 355, CHARACTER},
+ {CHARACTER, 0, 110, 356, CHARACTER},
+ {RETURN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 43, 0, 0, CHARACTER},
+ {CHARACTER, 0, 66, 359, CHARACTER},
+ {CHARACTER, 0, 74, 360, CHARACTER},
+ {CHARACTER, 0, 69, 361, CHARACTER},
+ {CHARACTER, 0, 67, 362, CHARACTER},
+ {CHARACTER, 0, 84, 363, CHARACTER},
+ {Q_OBJECT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 65, 365, CHARACTER},
+ {CHARACTER, 0, 68, 366, CHARACTER},
+ {CHARACTER, 0, 71, 367, CHARACTER},
+ {CHARACTER, 0, 69, 368, CHARACTER},
+ {CHARACTER, 0, 84, 369, CHARACTER},
+ {Q_GADGET_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 82, 371, CHARACTER},
+ {CHARACTER, 44, 0, 0, CHARACTER},
+ {CHARACTER, 0, 80, 373, CHARACTER},
+ {CHARACTER, 0, 69, 374, CHARACTER},
+ {CHARACTER, 0, 82, 375, CHARACTER},
+ {CHARACTER, 0, 84, 376, CHARACTER},
+ {CHARACTER, 0, 89, 377, CHARACTER},
+ {Q_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 379, CHARACTER},
+ {CHARACTER, 0, 85, 380, CHARACTER},
+ {CHARACTER, 0, 77, 381, CHARACTER},
+ {CHARACTER, 0, 83, 382, CHARACTER},
+ {Q_ENUMS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 76, 384, CHARACTER},
+ {CHARACTER, 0, 65, 385, CHARACTER},
+ {CHARACTER, 0, 71, 386, CHARACTER},
+ {CHARACTER, 0, 83, 387, CHARACTER},
+ {Q_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 389, CHARACTER},
+ {CHARACTER, 0, 67, 390, CHARACTER},
+ {CHARACTER, 0, 76, 391, CHARACTER},
+ {CHARACTER, 0, 65, 392, CHARACTER},
+ {CHARACTER, 0, 82, 393, CHARACTER},
+ {CHARACTER, 0, 69, 394, CHARACTER},
+ {CHARACTER, 0, 95, 395, CHARACTER},
+ {CHARACTER, 45, 0, 0, CHARACTER},
+ {CHARACTER, 0, 76, 397, CHARACTER},
+ {CHARACTER, 0, 65, 398, CHARACTER},
+ {CHARACTER, 0, 71, 399, CHARACTER},
+ {CHARACTER, 0, 83, 400, CHARACTER},
+ {Q_DECLARE_FLAGS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 402, CHARACTER},
+ {CHARACTER, 0, 84, 403, CHARACTER},
+ {CHARACTER, 0, 69, 404, CHARACTER},
+ {CHARACTER, 0, 82, 405, CHARACTER},
+ {CHARACTER, 0, 70, 406, CHARACTER},
+ {CHARACTER, 0, 65, 407, CHARACTER},
+ {CHARACTER, 0, 67, 408, CHARACTER},
+ {CHARACTER, 0, 69, 409, CHARACTER},
+ {Q_DECLARE_INTERFACE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 411, CHARACTER},
+ {CHARACTER, 0, 84, 412, CHARACTER},
+ {CHARACTER, 0, 65, 413, CHARACTER},
+ {CHARACTER, 0, 84, 414, CHARACTER},
+ {CHARACTER, 0, 89, 415, CHARACTER},
+ {CHARACTER, 0, 80, 416, CHARACTER},
+ {CHARACTER, 0, 69, 417, CHARACTER},
+ {Q_DECLARE_METATYPE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 88, 419, CHARACTER},
+ {CHARACTER, 0, 84, 420, CHARACTER},
+ {CHARACTER, 0, 69, 421, CHARACTER},
+ {CHARACTER, 0, 78, 422, CHARACTER},
+ {CHARACTER, 0, 83, 423, CHARACTER},
+ {CHARACTER, 0, 73, 424, CHARACTER},
+ {CHARACTER, 0, 79, 425, CHARACTER},
+ {CHARACTER, 0, 78, 426, CHARACTER},
+ {CHARACTER, 0, 95, 427, CHARACTER},
+ {CHARACTER, 0, 73, 428, CHARACTER},
+ {CHARACTER, 0, 78, 429, CHARACTER},
+ {CHARACTER, 0, 84, 430, CHARACTER},
+ {CHARACTER, 0, 69, 431, CHARACTER},
+ {CHARACTER, 0, 82, 432, CHARACTER},
+ {CHARACTER, 0, 70, 433, CHARACTER},
+ {CHARACTER, 0, 65, 434, CHARACTER},
+ {CHARACTER, 0, 67, 435, CHARACTER},
+ {CHARACTER, 0, 69, 409, CHARACTER},
+ {CHARACTER, 46, 0, 0, CHARACTER},
+ {CHARACTER, 0, 84, 438, CHARACTER},
+ {CHARACTER, 0, 83, 387, CHARACTER},
+ {CHARACTER, 0, 76, 440, CHARACTER},
+ {CHARACTER, 0, 65, 441, CHARACTER},
+ {CHARACTER, 0, 83, 442, CHARACTER},
+ {CHARACTER, 0, 83, 443, CHARACTER},
+ {CHARACTER, 0, 73, 444, CHARACTER},
+ {CHARACTER, 0, 78, 445, CHARACTER},
+ {CHARACTER, 0, 70, 446, CHARACTER},
+ {CHARACTER, 0, 79, 447, CHARACTER},
+ {Q_CLASSINFO_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 78, 449, CHARACTER},
+ {CHARACTER, 47, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 451, CHARACTER},
+ {CHARACTER, 0, 82, 452, CHARACTER},
+ {CHARACTER, 0, 70, 453, CHARACTER},
+ {CHARACTER, 0, 65, 454, CHARACTER},
+ {CHARACTER, 0, 67, 455, CHARACTER},
+ {CHARACTER, 0, 69, 456, CHARACTER},
+ {CHARACTER, 0, 83, 457, CHARACTER},
+ {Q_INTERFACES_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 108, 459, CHARACTER},
+ {CHARACTER, 0, 115, 460, CHARACTER},
+ {SIGNALS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 111, 462, CHARACTER},
+ {CHARACTER, 0, 116, 463, CHARACTER},
+ {CHARACTER, 0, 115, 464, CHARACTER},
+ {SLOTS, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 71, 466, CHARACTER},
+ {CHARACTER, 0, 78, 467, CHARACTER},
+ {CHARACTER, 0, 65, 468, CHARACTER},
+ {CHARACTER, 0, 76, 469, CHARACTER},
+ {Q_SIGNAL_TOKEN, 0, 83, 470, CHARACTER},
+ {Q_SIGNALS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 79, 472, CHARACTER},
+ {CHARACTER, 0, 84, 473, CHARACTER},
+ {Q_SLOT_TOKEN, 0, 83, 474, CHARACTER},
+ {Q_SLOTS_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 86, 476, CHARACTER},
+ {CHARACTER, 0, 65, 477, CHARACTER},
+ {CHARACTER, 0, 84, 478, CHARACTER},
+ {CHARACTER, 0, 69, 479, CHARACTER},
+ {CHARACTER, 0, 95, 480, CHARACTER},
+ {CHARACTER, 48, 0, 0, CHARACTER},
+ {CHARACTER, 0, 76, 482, CHARACTER},
+ {CHARACTER, 0, 79, 483, CHARACTER},
+ {CHARACTER, 0, 84, 484, CHARACTER},
+ {Q_PRIVATE_SLOT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 49, 0, 0, CHARACTER},
+ {CHARACTER, 0, 77, 487, CHARACTER},
+ {CHARACTER, 0, 79, 488, CHARACTER},
+ {CHARACTER, 0, 67, 489, CHARACTER},
+ {CHARACTER, 0, 95, 490, CHARACTER},
+ {CHARACTER, 0, 67, 491, CHARACTER},
+ {CHARACTER, 0, 79, 492, CHARACTER},
+ {CHARACTER, 0, 77, 493, CHARACTER},
+ {CHARACTER, 0, 80, 494, CHARACTER},
+ {CHARACTER, 0, 65, 495, CHARACTER},
+ {CHARACTER, 0, 84, 496, CHARACTER},
+ {Q_MOC_COMPAT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 95, 498, CHARACTER},
+ {CHARACTER, 0, 83, 499, CHARACTER},
+ {CHARACTER, 0, 85, 500, CHARACTER},
+ {CHARACTER, 0, 80, 501, CHARACTER},
+ {CHARACTER, 0, 80, 502, CHARACTER},
+ {CHARACTER, 0, 79, 503, CHARACTER},
+ {CHARACTER, 0, 82, 504, CHARACTER},
+ {CHARACTER, 0, 84, 505, CHARACTER},
+ {Q_QT3_SUPPORT_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 79, 507, CHARACTER},
+ {CHARACTER, 0, 75, 508, CHARACTER},
+ {CHARACTER, 0, 65, 509, CHARACTER},
+ {CHARACTER, 0, 66, 510, CHARACTER},
+ {CHARACTER, 0, 76, 511, CHARACTER},
+ {CHARACTER, 0, 69, 512, CHARACTER},
+ {Q_INVOKABLE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 82, 514, CHARACTER},
+ {CHARACTER, 0, 73, 515, CHARACTER},
+ {CHARACTER, 0, 80, 516, CHARACTER},
+ {CHARACTER, 0, 84, 517, CHARACTER},
+ {CHARACTER, 0, 65, 518, CHARACTER},
+ {CHARACTER, 0, 66, 519, CHARACTER},
+ {CHARACTER, 0, 76, 520, CHARACTER},
+ {CHARACTER, 0, 69, 521, CHARACTER},
+ {Q_SCRIPTABLE_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 82, 523, CHARACTER},
+ {CHARACTER, 0, 79, 524, CHARACTER},
+ {CHARACTER, 0, 80, 525, CHARACTER},
+ {CHARACTER, 0, 69, 526, CHARACTER},
+ {CHARACTER, 0, 82, 527, CHARACTER},
+ {CHARACTER, 0, 84, 528, CHARACTER},
+ {CHARACTER, 0, 89, 529, CHARACTER},
+ {Q_PRIVATE_PROPERTY_TOKEN, 0, 0, 0, CHARACTER},
+ {CHARACTER, 0, 69, 531, CHARACTER},
+ {CHARACTER, 0, 86, 532, CHARACTER},
+ {CHARACTER, 0, 73, 533, CHARACTER},
+ {CHARACTER, 0, 83, 534, CHARACTER},
+ {CHARACTER, 0, 73, 535, CHARACTER},
+ {CHARACTER, 0, 79, 536, CHARACTER},
+ {CHARACTER, 0, 78, 537, CHARACTER},
+ {Q_REVISION_TOKEN, 0, 0, 0, CHARACTER},
+ {NEWLINE, 0, 0, 0, NOTOKEN},
+ {QUOTE, 0, 0, 0, NOTOKEN},
+ {SINGLEQUOTE, 0, 0, 0, NOTOKEN},
+ {WHITESPACE, 0, 0, 0, NOTOKEN},
+ {HASH, 0, 0, 0, HASH},
+ {BACKSLASH, 0, 0, 0, NOTOKEN},
+ {CPP_COMMENT, 0, 0, 0, NOTOKEN},
+ {C_COMMENT, 0, 0, 0, NOTOKEN},
+ {FLOATING_LITERAL, 0, 0, 0, NOTOKEN}
+};
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
new file mode 100644
index 0000000000..ecff10555a
--- /dev/null
+++ b/src/tools/moc/main.cpp
@@ -0,0 +1,448 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "preprocessor.h"
+#include "moc.h"
+#include "outputrevision.h"
+#include "../../corelib/global/qconfig.cpp"
+#include <QFile>
+#include <QFileInfo>
+#include <QDir>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ This function looks at two file names and returns the name of the
+ infile with a path relative to outfile.
+
+ Examples:
+
+ /tmp/abc, /tmp/bcd -> abc
+ xyz/a/bc, xyz/b/ac -> ../a/bc
+ /tmp/abc, xyz/klm -> /tmp/abc
+ */
+
+static QByteArray combinePath(const char *infile, const char *outfile)
+{
+ QFileInfo inFileInfo(QDir::current(), QFile::decodeName(infile));
+ QFileInfo outFileInfo(QDir::current(), QFile::decodeName(outfile));
+ int numCommonComponents = 0;
+
+ QStringList inSplitted = inFileInfo.dir().canonicalPath().split(QLatin1Char('/'));
+ QStringList outSplitted = outFileInfo.dir().canonicalPath().split(QLatin1Char('/'));
+
+ while (!inSplitted.isEmpty() && !outSplitted.isEmpty() &&
+ inSplitted.first() == outSplitted.first()) {
+ inSplitted.removeFirst();
+ outSplitted.removeFirst();
+ numCommonComponents++;
+ }
+
+ if (numCommonComponents < 2)
+ /*
+ The paths don't have the same drive, or they don't have the
+ same root directory. Use an absolute path.
+ */
+ return QFile::encodeName(inFileInfo.absoluteFilePath());
+ /*
+ The paths have something in common. Use a path relative to
+ the output file.
+ */
+ while (!outSplitted.isEmpty()) {
+ outSplitted.removeFirst();
+ inSplitted.prepend(QLatin1String(".."));
+ }
+ inSplitted.append(inFileInfo.fileName());
+ return QFile::encodeName(inSplitted.join(QLatin1String("/")));
+}
+
+
+void error(const char *msg = "Invalid argument")
+{
+ if (msg)
+ fprintf(stderr, "moc: %s\n", msg);
+ fprintf(stderr, "Usage: moc [options] <header-file>\n"
+ " -o<file> write output to file rather than stdout\n"
+ " -I<dir> add dir to the include path for header files\n"
+ " -E preprocess only; do not generate meta object code\n"
+ " -D<macro>[=<def>] define macro, with optional definition\n"
+ " -U<macro> undefine macro\n"
+ " -i do not generate an #include statement\n"
+ " -p<path> path prefix for included file\n"
+ " -f[<file>] force #include, optional file name\n"
+ " -nn do not display notes\n"
+ " -nw do not display warnings\n"
+ " @<file> read additional options from file\n"
+ " -v display version of moc\n");
+ exit(1);
+}
+
+
+static inline bool hasNext(const Symbols &symbols, int i)
+{ return (i < symbols.size()); }
+
+static inline const Symbol &next(const Symbols &symbols, int &i)
+{ return symbols.at(i++); }
+
+
+QByteArray composePreprocessorOutput(const Symbols &symbols) {
+ QByteArray output;
+ int lineNum = 1;
+ Token last = PP_NOTOKEN;
+ Token secondlast = last;
+ int i = 0;
+ while (hasNext(symbols, i)) {
+ Symbol sym = next(symbols, i);
+ switch (sym.token) {
+ case PP_NEWLINE:
+ case PP_WHITESPACE:
+ if (last != PP_WHITESPACE) {
+ secondlast = last;
+ last = PP_WHITESPACE;
+ output += ' ';
+ }
+ continue;
+ case PP_STRING_LITERAL:
+ if (last == PP_STRING_LITERAL)
+ output.chop(1);
+ else if (secondlast == PP_STRING_LITERAL && last == PP_WHITESPACE)
+ output.chop(2);
+ else
+ break;
+ output += sym.lexem().mid(1);
+ secondlast = last;
+ last = PP_STRING_LITERAL;
+ continue;
+ case MOC_INCLUDE_BEGIN:
+ lineNum = 0;
+ continue;
+ case MOC_INCLUDE_END:
+ lineNum = sym.lineNum;
+ continue;
+ default:
+ break;
+ }
+ secondlast = last;
+ last = sym.token;
+
+ const int padding = sym.lineNum - lineNum;
+ if (padding > 0) {
+ output.resize(output.size() + padding);
+ qMemSet(output.data() + output.size() - padding, '\n', padding);
+ lineNum = sym.lineNum;
+ }
+
+ output += sym.lexem();
+ }
+
+ return output;
+}
+
+
+int runMoc(int _argc, char **_argv)
+{
+ bool autoInclude = true;
+ Preprocessor pp;
+ Moc moc;
+ pp.macros["Q_MOC_RUN"];
+ pp.macros["__cplusplus"];
+ QByteArray filename;
+ QByteArray output;
+ FILE *in = 0;
+ FILE *out = 0;
+ bool ignoreConflictingOptions = false;
+
+ QVector<QByteArray> argv;
+ argv.resize(_argc - 1);
+ for (int n = 1; n < _argc; ++n)
+ argv[n - 1] = _argv[n];
+ int argc = argv.count();
+
+ for (int n = 0; n < argv.count(); ++n) {
+ if (argv.at(n).startsWith('@')) {
+ QByteArray optionsFile = argv.at(n);
+ optionsFile.remove(0, 1);
+ if (optionsFile.isEmpty())
+ error("The @ option requires an input file");
+ QFile f(QString::fromLatin1(optionsFile.constData()));
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ error("Cannot open options file specified with @");
+ argv.remove(n);
+ while (!f.atEnd()) {
+ QByteArray line = f.readLine().trimmed();
+ if (!line.isEmpty())
+ argv.insert(n++, line);
+ }
+ }
+ }
+
+ argc = argv.count();
+
+ for (int n = 0; n < argc; ++n) {
+ QByteArray arg(argv[n]);
+ if (arg[0] != '-') {
+ if (filename.isEmpty()) {
+ filename = arg;
+ continue;
+ }
+ error("Too many input files specified");
+ }
+ QByteArray opt = arg.mid(1);
+ bool more = (opt.size() > 1);
+ switch (opt[0]) {
+ case 'o': // output redirection
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing output file name");
+ output = argv[++n];
+ } else
+ output = opt.mid(1);
+ break;
+ case 'E': // only preprocessor
+ pp.preprocessOnly = true;
+ break;
+ case 'i': // no #include statement
+ if (more)
+ error();
+ moc.noInclude = true;
+ autoInclude = false;
+ break;
+ case 'f': // produce #include statement
+ if (ignoreConflictingOptions)
+ break;
+ moc.noInclude = false;
+ autoInclude = false;
+ if (opt[1]) // -fsomething.h
+ moc.includeFiles.append(opt.mid(1));
+ break;
+ case 'p': // include file path
+ if (ignoreConflictingOptions)
+ break;
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing path name for the -p option.");
+ moc.includePath = argv[++n];
+ } else {
+ moc.includePath = opt.mid(1);
+ }
+ break;
+ case 'I': // produce #include statement
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing path name for the -I option.");
+ pp.includes += Preprocessor::IncludePath(argv[++n]);
+ } else {
+ pp.includes += Preprocessor::IncludePath(opt.mid(1));
+ }
+ break;
+ case 'F': // minimalistic framework support for the mac
+ if (!more) {
+ if (!(n < argc-1))
+ error("Missing path name for the -F option.");
+ Preprocessor::IncludePath p(argv[++n]);
+ p.isFrameworkPath = true;
+ pp.includes += p;
+ } else {
+ Preprocessor::IncludePath p(opt.mid(1));
+ p.isFrameworkPath = true;
+ pp.includes += p;
+ }
+ break;
+ case 'D': // define macro
+ {
+ QByteArray name;
+ QByteArray value("1");
+ if (!more) {
+ if (n < argc-1)
+ name = argv[++n];
+ } else
+ name = opt.mid(1);
+ int eq = name.indexOf('=');
+ if (eq >= 0) {
+ value = name.mid(eq + 1);
+ name = name.left(eq);
+ }
+ if (name.isEmpty())
+ error("Missing macro name");
+ Macro macro;
+ macro.symbols += Symbol(0, PP_IDENTIFIER, value);
+ pp.macros.insert(name, macro);
+
+ }
+ break;
+ case 'U':
+ {
+ QByteArray macro;
+ if (!more) {
+ if (n < argc-1)
+ macro = argv[++n];
+ } else
+ macro = opt.mid(1);
+ if (macro.isEmpty())
+ error("Missing macro name");
+ pp.macros.remove(macro);
+
+ }
+ break;
+ case 'v': // version number
+ if (more && opt != "version")
+ error();
+ fprintf(stderr, "Qt Meta Object Compiler version %d (Qt %s)\n",
+ mocOutputRevision, QT_VERSION_STR);
+ return 1;
+ case 'n': // don't display warnings
+ if (ignoreConflictingOptions)
+ break;
+ if (opt == "nw")
+ moc.displayWarnings = moc.displayNotes = false;
+ else if (opt == "nn")
+ moc.displayNotes = false;
+ else
+ error();
+ break;
+ case 'h': // help
+ if (more && opt != "help")
+ error();
+ else
+ error(0); // 0 means usage only
+ break;
+ case '-':
+ if (more && arg == "--ignore-option-clashes") {
+ // -- ignore all following moc specific options that conflict
+ // with for example gcc, like -pthread conflicting with moc's
+ // -p option.
+ ignoreConflictingOptions = true;
+ break;
+ }
+ // fall through
+ default:
+ error();
+ }
+ }
+
+
+ if (autoInclude) {
+ int spos = filename.lastIndexOf(QDir::separator().toLatin1());
+ int ppos = filename.lastIndexOf('.');
+ // spos >= -1 && ppos > spos => ppos >= 0
+ moc.noInclude = (ppos > spos && tolower(filename[ppos + 1]) != 'h');
+ }
+ if (moc.includeFiles.isEmpty()) {
+ if (moc.includePath.isEmpty()) {
+ if (filename.size()) {
+ if (output.size())
+ moc.includeFiles.append(combinePath(filename, output));
+ else
+ moc.includeFiles.append(filename);
+ }
+ } else {
+ moc.includeFiles.append(combinePath(filename, filename));
+ }
+ }
+
+ if (filename.isEmpty()) {
+ filename = "standard input";
+ in = stdin;
+ } else {
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&in, filename.data(), "rb")) {
+#else
+ in = fopen(filename.data(), "rb");
+ if (!in) {
+#endif
+ fprintf(stderr, "moc: %s: No such file\n", (const char*)filename);
+ return 1;
+ }
+ moc.filename = filename;
+ }
+
+ moc.currentFilenames.push(filename);
+
+ // 1. preprocess
+ moc.symbols = pp.preprocessed(moc.filename, in);
+ fclose(in);
+
+ if (!pp.preprocessOnly) {
+ // 2. parse
+ moc.parse();
+ }
+
+ // 3. and output meta object code
+
+ if (output.size()) { // output file specified
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ if (fopen_s(&out, output.data(), "w"))
+#else
+ out = fopen(output.data(), "w"); // create output file
+ if (!out)
+#endif
+ {
+ fprintf(stderr, "moc: Cannot create %s\n", (const char*)output);
+ return 1;
+ }
+ } else { // use stdout
+ out = stdout;
+ }
+
+ if (pp.preprocessOnly) {
+ fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData());
+ } else {
+ if (moc.classList.isEmpty())
+ moc.note("No relevant classes found. No output generated.");
+ else
+ moc.generate(out);
+ }
+
+ if (output.size())
+ fclose(out);
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+int main(int _argc, char **_argv)
+{
+ return QT_PREPEND_NAMESPACE(runMoc)(_argc, _argv);
+}
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
new file mode 100644
index 0000000000..4a2ba68b80
--- /dev/null
+++ b/src/tools/moc/moc.cpp
@@ -0,0 +1,1453 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "moc.h"
+#include "generator.h"
+#include "qdatetime.h"
+#include "utils.h"
+#include "outputrevision.h"
+
+// for normalizeTypeInternal
+#include <private/qmetaobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// only moc needs this function
+static QByteArray normalizeType(const char *s, bool fixScope = false)
+{
+ int len = qstrlen(s);
+ char stackbuf[64];
+ char *buf = (len >= 64 ? new char[len + 1] : stackbuf);
+ char *d = buf;
+ char last = 0;
+ while(*s && is_space(*s))
+ s++;
+ while (*s) {
+ while (*s && !is_space(*s))
+ last = *d++ = *s++;
+ while (*s && is_space(*s))
+ s++;
+ if (*s && ((is_ident_char(*s) && is_ident_char(last))
+ || ((*s == ':') && (last == '<')))) {
+ last = *d++ = ' ';
+ }
+ }
+ *d = '\0';
+ QByteArray result;
+ if (strncmp("void", buf, d - buf) != 0)
+ result = normalizeTypeInternal(buf, d, fixScope);
+ if (buf != stackbuf)
+ delete [] buf;
+ return result;
+}
+
+bool Moc::parseClassHead(ClassDef *def)
+{
+ // figure out whether this is a class declaration, or only a
+ // forward or variable declaration.
+ int i = 0;
+ Token token;
+ do {
+ token = lookup(i++);
+ if (token == COLON || token == LBRACE)
+ break;
+ if (token == SEMIC || token == RANGLE)
+ return false;
+ } while (token);
+
+ if (!test(IDENTIFIER)) // typedef struct { ... }
+ return false;
+ QByteArray name = lexem();
+
+ // support "class IDENT name" and "class IDENT(IDENT) name"
+ if (test(LPAREN)) {
+ until(RPAREN);
+ if (!test(IDENTIFIER))
+ return false;
+ name = lexem();
+ } else if (test(IDENTIFIER)) {
+ name = lexem();
+ }
+
+ def->qualified += name;
+ while (test(SCOPE)) {
+ def->qualified += lexem();
+ if (test(IDENTIFIER)) {
+ name = lexem();
+ def->qualified += name;
+ }
+ }
+ def->classname = name;
+ if (test(COLON)) {
+ do {
+ test(VIRTUAL);
+ FunctionDef::Access access = FunctionDef::Public;
+ if (test(PRIVATE))
+ access = FunctionDef::Private;
+ else if (test(PROTECTED))
+ access = FunctionDef::Protected;
+ else
+ test(PUBLIC);
+ test(VIRTUAL);
+ const QByteArray type = parseType().name;
+ // ignore the 'class Foo : BAR(Baz)' case
+ if (test(LPAREN)) {
+ until(RPAREN);
+ } else {
+ def->superclassList += qMakePair(type, access);
+ }
+ } while (test(COMMA));
+ }
+ if (!test(LBRACE))
+ return false;
+ def->begin = index - 1;
+ bool foundRBrace = until(RBRACE);
+ def->end = index;
+ index = def->begin + 1;
+ return foundRBrace;
+}
+
+Type Moc::parseType()
+{
+ Type type;
+ bool hasSignedOrUnsigned = false;
+ bool isVoid = false;
+ type.firstToken = lookup();
+ for (;;) {
+ switch (next()) {
+ case SIGNED:
+ case UNSIGNED:
+ hasSignedOrUnsigned = true;
+ // fall through
+ case CONST:
+ case VOLATILE:
+ type.name += lexem();
+ type.name += ' ';
+ if (lookup(0) == VOLATILE)
+ type.isVolatile = true;
+ continue;
+ case Q_MOC_COMPAT_TOKEN:
+ case Q_QT3_SUPPORT_TOKEN:
+ case Q_INVOKABLE_TOKEN:
+ case Q_SCRIPTABLE_TOKEN:
+ case Q_SIGNALS_TOKEN:
+ case Q_SLOTS_TOKEN:
+ case Q_SIGNAL_TOKEN:
+ case Q_SLOT_TOKEN:
+ type.name += lexem();
+ return type;
+ default:
+ prev();
+ break;
+ }
+ break;
+ }
+ test(ENUM) || test(CLASS) || test(STRUCT);
+ for(;;) {
+ switch (next()) {
+ case IDENTIFIER:
+ // void mySlot(unsigned myArg)
+ if (hasSignedOrUnsigned) {
+ prev();
+ break;
+ }
+ case CHAR:
+ case SHORT:
+ case INT:
+ case LONG:
+ type.name += lexem();
+ // preserve '[unsigned] long long', 'short int', 'long int', 'long double'
+ if (test(LONG) || test(INT) || test(DOUBLE)) {
+ type.name += ' ';
+ prev();
+ continue;
+ }
+ break;
+ case FLOAT:
+ case DOUBLE:
+ case VOID:
+ case BOOL:
+ type.name += lexem();
+ isVoid |= (lookup(0) == VOID);
+ break;
+ default:
+ prev();
+ ;
+ }
+ if (test(LANGLE)) {
+ QByteArray templ = lexemUntil(RANGLE);
+ for (int i = 0; i < templ.size(); ++i) {
+ type.name += templ.at(i);
+ if ((templ.at(i) == '<' && i < templ.size()-1 && templ.at(i+1) == ':')
+ || (templ.at(i) == '>' && i < templ.size()-1 && templ.at(i+1) == '>')) {
+ type.name += ' ';
+ }
+ }
+ }
+ if (test(SCOPE)) {
+ type.name += lexem();
+ type.isScoped = true;
+ } else {
+ break;
+ }
+ }
+ while (test(CONST) || test(VOLATILE) || test(SIGNED) || test(UNSIGNED)
+ || test(STAR) || test(AND) || test(ANDAND)) {
+ type.name += ' ';
+ type.name += lexem();
+ if (lookup(0) == AND)
+ type.referenceType = Type::Reference;
+ else if (lookup(0) == ANDAND)
+ type.referenceType = Type::RValueReference;
+ else if (lookup(0) == STAR)
+ type.referenceType = Type::Pointer;
+ }
+ // transform stupid things like 'const void' or 'void const' into 'void'
+ if (isVoid && type.referenceType == Type::NoReference) {
+ type.name = "void";
+ }
+ return type;
+}
+
+bool Moc::parseEnum(EnumDef *def)
+{
+ bool isTypdefEnum = false; // typedef enum { ... } Foo;
+
+ if (test(IDENTIFIER)) {
+ def->name = lexem();
+ } else {
+ if (lookup(-1) != TYPEDEF)
+ return false; // anonymous enum
+ isTypdefEnum = true;
+ }
+ if (!test(LBRACE))
+ return false;
+ do {
+ if (lookup() == RBRACE) // accept trailing comma
+ break;
+ next(IDENTIFIER);
+ def->values += lexem();
+ } while (test(EQ) ? until(COMMA) : test(COMMA));
+ next(RBRACE);
+ if (isTypdefEnum) {
+ if (!test(IDENTIFIER))
+ return false;
+ def->name = lexem();
+ }
+ return true;
+}
+
+void Moc::parseFunctionArguments(FunctionDef *def)
+{
+ Q_UNUSED(def);
+ while (hasNext()) {
+ ArgumentDef arg;
+ arg.type = parseType();
+ if (arg.type.name == "void")
+ break;
+ if (test(IDENTIFIER))
+ arg.name = lexem();
+ while (test(LBRACK)) {
+ arg.rightType += lexemUntil(RBRACK);
+ }
+ if (test(CONST) || test(VOLATILE)) {
+ arg.rightType += ' ';
+ arg.rightType += lexem();
+ }
+ arg.normalizedType = normalizeType(QByteArray(arg.type.name + ' ' + arg.rightType));
+ arg.typeNameForCast = normalizeType(QByteArray(noRef(arg.type.name) + "(*)" + arg.rightType));
+ if (test(EQ))
+ arg.isDefault = true;
+ def->arguments += arg;
+ if (!until(COMMA))
+ break;
+ }
+}
+
+bool Moc::testFunctionAttribute(FunctionDef *def)
+{
+ if (index < symbols.size() && testFunctionAttribute(symbols.at(index).token, def)) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+bool Moc::testFunctionAttribute(Token tok, FunctionDef *def)
+{
+ switch (tok) {
+ case Q_MOC_COMPAT_TOKEN:
+ case Q_QT3_SUPPORT_TOKEN:
+ def->isCompat = true;
+ return true;
+ case Q_INVOKABLE_TOKEN:
+ def->isInvokable = true;
+ return true;
+ case Q_SIGNAL_TOKEN:
+ def->isSignal = true;
+ return true;
+ case Q_SLOT_TOKEN:
+ def->isSlot = true;
+ return true;
+ case Q_SCRIPTABLE_TOKEN:
+ def->isInvokable = def->isScriptable = true;
+ return true;
+ default: break;
+ }
+ return false;
+}
+
+bool Moc::testFunctionRevision(FunctionDef *def)
+{
+ if (test(Q_REVISION_TOKEN)) {
+ next(LPAREN);
+ QByteArray revision = lexemUntil(RPAREN);
+ revision.remove(0, 1);
+ revision.chop(1);
+ bool ok = false;
+ def->revision = revision.toInt(&ok);
+ if (!ok || def->revision < 0)
+ error("Invalid revision");
+ return true;
+ }
+
+ return false;
+}
+
+// returns false if the function should be ignored
+bool Moc::parseFunction(FunctionDef *def, bool inMacro)
+{
+ def->isVirtual = false;
+ def->isStatic = false;
+ //skip modifiers and attributes
+ while (test(INLINE) || (test(STATIC) && (def->isStatic = true)) ||
+ (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual
+ || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ bool templateFunction = (lookup() == TEMPLATE);
+ def->type = parseType();
+ if (def->type.name.isEmpty()) {
+ if (templateFunction)
+ error("Template function as signal or slot");
+ else
+ error();
+ }
+ bool scopedFunctionName = false;
+ if (test(LPAREN)) {
+ def->name = def->type.name;
+ scopedFunctionName = def->type.isScoped;
+ def->type = Type("int");
+ } else {
+ Type tempType = parseType();;
+ while (!tempType.name.isEmpty() && lookup() != LPAREN) {
+ if (testFunctionAttribute(def->type.firstToken, def))
+ ; // fine
+ else if (def->type.firstToken == Q_SIGNALS_TOKEN)
+ error();
+ else if (def->type.firstToken == Q_SLOTS_TOKEN)
+ error();
+ else {
+ if (!def->tag.isEmpty())
+ def->tag += ' ';
+ def->tag += def->type.name;
+ }
+ def->type = tempType;
+ tempType = parseType();
+ }
+ next(LPAREN, "Not a signal or slot declaration");
+ def->name = tempType.name;
+ scopedFunctionName = tempType.isScoped;
+ }
+
+ // we don't support references as return types, it's too dangerous
+ if (def->type.referenceType == Type::Reference)
+ def->type = Type("void");
+
+ def->normalizedType = normalizeType(def->type.name);
+
+ if (!test(RPAREN)) {
+ parseFunctionArguments(def);
+ next(RPAREN);
+ }
+
+ // support optional macros with compiler specific options
+ while (test(IDENTIFIER))
+ ;
+
+ def->isConst = test(CONST);
+
+ while (test(IDENTIFIER))
+ ;
+
+ if (inMacro) {
+ next(RPAREN);
+ prev();
+ } else {
+ if (test(THROW)) {
+ next(LPAREN);
+ until(RPAREN);
+ }
+ if (test(SEMIC))
+ ;
+ else if ((def->inlineCode = test(LBRACE)))
+ until(RBRACE);
+ else if ((def->isAbstract = test(EQ)))
+ until(SEMIC);
+ else
+ error();
+ }
+
+ if (scopedFunctionName) {
+ QByteArray msg("Function declaration ");
+ msg += def->name;
+ msg += " contains extra qualification. Ignoring as signal or slot.";
+ warning(msg.constData());
+ return false;
+ }
+ return true;
+}
+
+// like parseFunction, but never aborts with an error
+bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
+{
+ def->isVirtual = false;
+ def->isStatic = false;
+ //skip modifiers and attributes
+ while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true)) ||
+ (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual
+ || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ bool tilde = test(TILDE);
+ def->type = parseType();
+ if (def->type.name.isEmpty())
+ return false;
+ bool scopedFunctionName = false;
+ if (test(LPAREN)) {
+ def->name = def->type.name;
+ scopedFunctionName = def->type.isScoped;
+ if (def->name == cdef->classname) {
+ def->isDestructor = tilde;
+ def->isConstructor = !tilde;
+ def->type = Type();
+ } else {
+ def->type = Type("int");
+ }
+ } else {
+ Type tempType = parseType();;
+ while (!tempType.name.isEmpty() && lookup() != LPAREN) {
+ if (testFunctionAttribute(def->type.firstToken, def))
+ ; // fine
+ else if (def->type.name == "Q_SIGNAL")
+ def->isSignal = true;
+ else if (def->type.name == "Q_SLOT")
+ def->isSlot = true;
+ else {
+ if (!def->tag.isEmpty())
+ def->tag += ' ';
+ def->tag += def->type.name;
+ }
+ def->type = tempType;
+ tempType = parseType();
+ }
+ if (!test(LPAREN))
+ return false;
+ def->name = tempType.name;
+ scopedFunctionName = tempType.isScoped;
+ }
+
+ // we don't support references as return types, it's too dangerous
+ if (def->type.referenceType == Type::Reference)
+ def->type = Type("void");
+
+ def->normalizedType = normalizeType(def->type.name);
+
+ if (!test(RPAREN)) {
+ parseFunctionArguments(def);
+ if (!test(RPAREN))
+ return false;
+ }
+ def->isConst = test(CONST);
+ if (scopedFunctionName
+ && (def->isSignal || def->isSlot || def->isInvokable)) {
+ QByteArray msg("parsemaybe: Function declaration ");
+ msg += def->name;
+ msg += " contains extra qualification. Ignoring as signal or slot.";
+ warning(msg.constData());
+ return false;
+ }
+ return true;
+}
+
+
+void Moc::parse()
+{
+ QList<NamespaceDef> namespaceList;
+ bool templateClass = false;
+ while (hasNext()) {
+ Token t = next();
+ switch (t) {
+ case NAMESPACE: {
+ int rewind = index;
+ if (test(IDENTIFIER)) {
+ if (test(EQ)) {
+ // namespace Foo = Bar::Baz;
+ until(SEMIC);
+ } else if (!test(SEMIC)) {
+ NamespaceDef def;
+ def.name = lexem();
+ next(LBRACE);
+ def.begin = index - 1;
+ until(RBRACE);
+ def.end = index;
+ index = def.begin + 1;
+ namespaceList += def;
+ index = rewind;
+ }
+ }
+ break;
+ }
+ case SEMIC:
+ case RBRACE:
+ templateClass = false;
+ break;
+ case TEMPLATE:
+ templateClass = true;
+ break;
+ case MOC_INCLUDE_BEGIN:
+ currentFilenames.push(symbol().unquotedLexem());
+ break;
+ case MOC_INCLUDE_END:
+ currentFilenames.pop();
+ break;
+ case Q_DECLARE_INTERFACE_TOKEN:
+ parseDeclareInterface();
+ break;
+ case Q_DECLARE_METATYPE_TOKEN:
+ parseDeclareMetatype();
+ break;
+ case USING:
+ if (test(NAMESPACE)) {
+ while (test(SCOPE) || test(IDENTIFIER))
+ ;
+ next(SEMIC);
+ }
+ break;
+ case CLASS:
+ case STRUCT: {
+ if (currentFilenames.size() <= 1)
+ break;
+
+ ClassDef def;
+ if (!parseClassHead(&def))
+ continue;
+
+ while (inClass(&def) && hasNext()) {
+ if (next() == Q_OBJECT_TOKEN) {
+ def.hasQObject = true;
+ break;
+ }
+ }
+
+ if (!def.hasQObject)
+ continue;
+
+ for (int i = namespaceList.size() - 1; i >= 0; --i)
+ if (inNamespace(&namespaceList.at(i)))
+ def.qualified.prepend(namespaceList.at(i).name + "::");
+
+ knownQObjectClasses.insert(def.classname);
+ knownQObjectClasses.insert(def.qualified);
+
+ continue; }
+ default: break;
+ }
+ if ((t != CLASS && t != STRUCT)|| currentFilenames.size() > 1)
+ continue;
+ ClassDef def;
+ if (parseClassHead(&def)) {
+ FunctionDef::Access access = FunctionDef::Private;
+ for (int i = namespaceList.size() - 1; i >= 0; --i)
+ if (inNamespace(&namespaceList.at(i)))
+ def.qualified.prepend(namespaceList.at(i).name + "::");
+ while (inClass(&def) && hasNext()) {
+ switch ((t = next())) {
+ case PRIVATE:
+ access = FunctionDef::Private;
+ if (test(Q_SIGNALS_TOKEN))
+ error("Signals cannot have access specifier");
+ break;
+ case PROTECTED:
+ access = FunctionDef::Protected;
+ if (test(Q_SIGNALS_TOKEN))
+ error("Signals cannot have access specifier");
+ break;
+ case PUBLIC:
+ access = FunctionDef::Public;
+ if (test(Q_SIGNALS_TOKEN))
+ error("Signals cannot have access specifier");
+ break;
+ case CLASS: {
+ ClassDef nestedDef;
+ if (parseClassHead(&nestedDef)) {
+ while (inClass(&nestedDef) && inClass(&def)) {
+ t = next();
+ if (t >= Q_META_TOKEN_BEGIN && t < Q_META_TOKEN_END)
+ error("Meta object features not supported for nested classes");
+ }
+ }
+ } break;
+ case Q_SIGNALS_TOKEN:
+ parseSignals(&def);
+ break;
+ case Q_SLOTS_TOKEN:
+ switch (lookup(-1)) {
+ case PUBLIC:
+ case PROTECTED:
+ case PRIVATE:
+ parseSlots(&def, access);
+ break;
+ default:
+ error("Missing access specifier for slots");
+ }
+ break;
+ case Q_OBJECT_TOKEN:
+ def.hasQObject = true;
+ if (templateClass)
+ error("Template classes not supported by Q_OBJECT");
+ if (def.classname != "Qt" && def.classname != "QObject" && def.superclassList.isEmpty())
+ error("Class contains Q_OBJECT macro but does not inherit from QObject");
+ break;
+ case Q_GADGET_TOKEN:
+ def.hasQGadget = true;
+ if (templateClass)
+ error("Template classes not supported by Q_GADGET");
+ break;
+ case Q_PROPERTY_TOKEN:
+ parseProperty(&def);
+ break;
+ case Q_ENUMS_TOKEN:
+ parseEnumOrFlag(&def, false);
+ break;
+ case Q_FLAGS_TOKEN:
+ parseEnumOrFlag(&def, true);
+ break;
+ case Q_DECLARE_FLAGS_TOKEN:
+ parseFlag(&def);
+ break;
+ case Q_CLASSINFO_TOKEN:
+ parseClassInfo(&def);
+ break;
+ case Q_INTERFACES_TOKEN:
+ parseInterfaces(&def);
+ break;
+ case Q_PRIVATE_SLOT_TOKEN:
+ parseSlotInPrivate(&def, access);
+ break;
+ case Q_PRIVATE_PROPERTY_TOKEN:
+ parsePrivateProperty(&def);
+ break;
+ case ENUM: {
+ EnumDef enumDef;
+ if (parseEnum(&enumDef))
+ def.enumList += enumDef;
+ } break;
+ case SEMIC:
+ case COLON:
+ break;
+ default:
+ FunctionDef funcDef;
+ funcDef.access = access;
+ int rewind = index--;
+ if (parseMaybeFunction(&def, &funcDef)) {
+ if (funcDef.isConstructor) {
+ if ((access == FunctionDef::Public) && funcDef.isInvokable) {
+ def.constructorList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.constructorList += funcDef;
+ }
+ }
+ } else if (funcDef.isDestructor) {
+ // don't care about destructors
+ } else {
+ if (access == FunctionDef::Public)
+ def.publicList += funcDef;
+ if (funcDef.isSlot) {
+ def.slotList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.slotList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def.revisionedMethods;
+ } else if (funcDef.isSignal) {
+ def.signalList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.signalList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def.revisionedMethods;
+ } else if (funcDef.isInvokable) {
+ def.methodList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def.methodList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def.revisionedMethods;
+ }
+ }
+ } else {
+ index = rewind;
+ }
+ }
+ }
+
+ next(RBRACE);
+
+ if (!def.hasQObject && !def.hasQGadget && def.signalList.isEmpty() && def.slotList.isEmpty()
+ && def.propertyList.isEmpty() && def.enumDeclarations.isEmpty())
+ continue; // no meta object code required
+
+
+ if (!def.hasQObject && !def.hasQGadget)
+ error("Class declarations lacks Q_OBJECT macro.");
+
+ checkSuperClasses(&def);
+ checkProperties(&def);
+
+ classList += def;
+ knownQObjectClasses.insert(def.classname);
+ knownQObjectClasses.insert(def.qualified);
+ }
+ }
+}
+
+void Moc::generate(FILE *out)
+{
+
+ QDateTime dt = QDateTime::currentDateTime();
+ QByteArray dstr = dt.toString().toLatin1();
+ QByteArray fn = filename;
+ int i = filename.length()-1;
+ while (i>0 && filename[i-1] != '/' && filename[i-1] != '\\')
+ --i; // skip path
+ if (i >= 0)
+ fn = filename.mid(i);
+ fprintf(out, "/****************************************************************************\n"
+ "** Meta object code from reading C++ file '%s'\n**\n" , (const char*)fn);
+ fprintf(out, "** Created: %s\n"
+ "** by: The Qt Meta Object Compiler version %d (Qt %s)\n**\n" , dstr.data(), mocOutputRevision, QT_VERSION_STR);
+ fprintf(out, "** WARNING! All changes made in this file will be lost!\n"
+ "*****************************************************************************/\n\n");
+
+
+ if (!noInclude) {
+ if (includePath.size() && !includePath.endsWith('/'))
+ includePath += '/';
+ for (int i = 0; i < includeFiles.size(); ++i) {
+ QByteArray inc = includeFiles.at(i);
+ if (inc[0] != '<' && inc[0] != '"') {
+ if (includePath.size() && includePath != "./")
+ inc.prepend(includePath);
+ inc = '\"' + inc + '\"';
+ }
+ fprintf(out, "#include %s\n", inc.constData());
+ }
+ }
+ if (classList.size() && classList.first().classname == "Qt")
+ fprintf(out, "#include <QtCore/qobject.h>\n");
+
+ if (mustIncludeQMetaTypeH)
+ fprintf(out, "#include <QtCore/qmetatype.h>\n");
+
+ fprintf(out, "#if !defined(Q_MOC_OUTPUT_REVISION)\n"
+ "#error \"The header file '%s' doesn't include <QObject>.\"\n", (const char *)fn);
+ fprintf(out, "#elif Q_MOC_OUTPUT_REVISION != %d\n", mocOutputRevision);
+ fprintf(out, "#error \"This file was generated using the moc from %s."
+ " It\"\n#error \"cannot be used with the include files from"
+ " this version of Qt.\"\n#error \"(The moc has changed too"
+ " much.)\"\n", QT_VERSION_STR);
+ fprintf(out, "#endif\n\n");
+
+ fprintf(out, "QT_BEGIN_MOC_NAMESPACE\n");
+
+ for (i = 0; i < classList.size(); ++i) {
+ Generator generator(&classList[i], metaTypes, out);
+ generator.generateCode();
+ }
+
+ fprintf(out, "QT_END_MOC_NAMESPACE\n");
+}
+
+
+QList<QMetaObject*> Moc::generate(bool ignoreProperties)
+{
+ QList<QMetaObject*> result;
+ for (int i = 0; i < classList.size(); ++i) {
+ Generator generator(&classList[i], metaTypes);
+ result << generator.generateMetaObject(ignoreProperties);
+ }
+ return result;
+}
+
+void Moc::parseSlots(ClassDef *def, FunctionDef::Access access)
+{
+ int defaultRevision = -1;
+ if (test(Q_REVISION_TOKEN)) {
+ next(LPAREN);
+ QByteArray revision = lexemUntil(RPAREN);
+ revision.remove(0, 1);
+ revision.chop(1);
+ bool ok = false;
+ defaultRevision = revision.toInt(&ok);
+ if (!ok || defaultRevision < 0)
+ error("Invalid revision");
+ }
+
+ next(COLON);
+ while (inClass(def) && hasNext()) {
+ switch (next()) {
+ case PUBLIC:
+ case PROTECTED:
+ case PRIVATE:
+ case Q_SIGNALS_TOKEN:
+ case Q_SLOTS_TOKEN:
+ prev();
+ return;
+ case SEMIC:
+ continue;
+ case FRIEND:
+ until(SEMIC);
+ continue;
+ case USING:
+ error("'using' directive not supported in 'slots' section");
+ default:
+ prev();
+ }
+
+ FunctionDef funcDef;
+ funcDef.access = access;
+ if (!parseFunction(&funcDef))
+ continue;
+ if (funcDef.revision > 0) {
+ ++def->revisionedMethods;
+ } else if (defaultRevision != -1) {
+ funcDef.revision = defaultRevision;
+ ++def->revisionedMethods;
+ }
+ def->slotList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def->slotList += funcDef;
+ }
+ }
+}
+
+void Moc::parseSignals(ClassDef *def)
+{
+ int defaultRevision = -1;
+ if (test(Q_REVISION_TOKEN)) {
+ next(LPAREN);
+ QByteArray revision = lexemUntil(RPAREN);
+ revision.remove(0, 1);
+ revision.chop(1);
+ bool ok = false;
+ defaultRevision = revision.toInt(&ok);
+ if (!ok || defaultRevision < 0)
+ error("Invalid revision");
+ }
+
+ next(COLON);
+ while (inClass(def) && hasNext()) {
+ switch (next()) {
+ case PUBLIC:
+ case PROTECTED:
+ case PRIVATE:
+ case Q_SIGNALS_TOKEN:
+ case Q_SLOTS_TOKEN:
+ prev();
+ return;
+ case SEMIC:
+ continue;
+ case FRIEND:
+ until(SEMIC);
+ continue;
+ case USING:
+ error("'using' directive not supported in 'signals' section");
+ default:
+ prev();
+ }
+ FunctionDef funcDef;
+ funcDef.access = FunctionDef::Protected;
+ parseFunction(&funcDef);
+ if (funcDef.isVirtual)
+ warning("Signals cannot be declared virtual");
+ if (funcDef.inlineCode)
+ error("Not a signal declaration");
+ if (funcDef.revision > 0) {
+ ++def->revisionedMethods;
+ } else if (defaultRevision != -1) {
+ funcDef.revision = defaultRevision;
+ ++def->revisionedMethods;
+ }
+ def->signalList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def->signalList += funcDef;
+ }
+ }
+}
+
+void Moc::createPropertyDef(PropertyDef &propDef)
+{
+ QByteArray type = parseType().name;
+ if (type.isEmpty())
+ error();
+ propDef.designable = propDef.scriptable = propDef.stored = "true";
+ propDef.user = "false";
+ /*
+ The Q_PROPERTY construct cannot contain any commas, since
+ commas separate macro arguments. We therefore expect users
+ to type "QMap" instead of "QMap<QString, QVariant>". For
+ coherence, we also expect the same for
+ QValueList<QVariant>, the other template class supported by
+ QVariant.
+ */
+ type = normalizeType(type);
+ if (type == "QMap")
+ type = "QMap<QString,QVariant>";
+ else if (type == "QValueList")
+ type = "QValueList<QVariant>";
+ else if (type == "LongLong")
+ type = "qlonglong";
+ else if (type == "ULongLong")
+ type = "qulonglong";
+ else if (type == "qreal")
+ mustIncludeQMetaTypeH = true;
+
+ propDef.type = type;
+
+ next();
+ propDef.name = lexem();
+ while (test(IDENTIFIER)) {
+ QByteArray l = lexem();
+ if (l[0] == 'C' && l == "CONSTANT") {
+ propDef.constant = true;
+ continue;
+ } else if(l[0] == 'F' && l == "FINAL") {
+ propDef.final = true;
+ continue;
+ }
+
+ QByteArray v, v2;
+ if (test(LPAREN)) {
+ v = lexemUntil(RPAREN);
+ } else if (test(INTEGER_LITERAL)) {
+ v = lexem();
+ if (l != "REVISION")
+ error(1);
+ } else {
+ next(IDENTIFIER);
+ v = lexem();
+ if (test(LPAREN))
+ v2 = lexemUntil(RPAREN);
+ else if (v != "true" && v != "false")
+ v2 = "()";
+ }
+ switch (l[0]) {
+ case 'R':
+ if (l == "READ")
+ propDef.read = v;
+ else if (l == "RESET")
+ propDef.reset = v + v2;
+ else if (l == "REVISION") {
+ bool ok = false;
+ propDef.revision = v.toInt(&ok);
+ if (!ok || propDef.revision < 0)
+ error(1);
+ } else
+ error(2);
+ break;
+ case 'S':
+ if (l == "SCRIPTABLE")
+ propDef.scriptable = v + v2;
+ else if (l == "STORED")
+ propDef.stored = v + v2;
+ else
+ error(2);
+ break;
+ case 'W': if (l != "WRITE") error(2);
+ propDef.write = v;
+ break;
+ case 'D': if (l != "DESIGNABLE") error(2);
+ propDef.designable = v + v2;
+ break;
+ case 'E': if (l != "EDITABLE") error(2);
+ propDef.editable = v + v2;
+ break;
+ case 'N': if (l != "NOTIFY") error(2);
+ propDef.notify = v;
+ break;
+ case 'U': if (l != "USER") error(2);
+ propDef.user = v + v2;
+ break;
+ default:
+ error(2);
+ }
+ }
+ if (propDef.read.isNull()) {
+ QByteArray msg;
+ msg += "Property declaration ";
+ msg += propDef.name;
+ msg += " has no READ accessor function. The property will be invalid.";
+ warning(msg.constData());
+ }
+ if (propDef.constant && !propDef.write.isNull()) {
+ QByteArray msg;
+ msg += "Property declaration ";
+ msg += propDef.name;
+ msg += " is both WRITEable and CONSTANT. CONSTANT will be ignored.";
+ propDef.constant = false;
+ warning(msg.constData());
+ }
+ if (propDef.constant && !propDef.notify.isNull()) {
+ QByteArray msg;
+ msg += "Property declaration ";
+ msg += propDef.name;
+ msg += " is both NOTIFYable and CONSTANT. CONSTANT will be ignored.";
+ propDef.constant = false;
+ warning(msg.constData());
+ }
+}
+
+void Moc::parseProperty(ClassDef *def)
+{
+ next(LPAREN);
+ PropertyDef propDef;
+ createPropertyDef(propDef);
+ next(RPAREN);
+
+
+ if(!propDef.notify.isEmpty())
+ def->notifyableProperties++;
+ if (propDef.revision > 0)
+ ++def->revisionedProperties;
+ def->propertyList += propDef;
+}
+
+void Moc::parsePrivateProperty(ClassDef *def)
+{
+ next(LPAREN);
+ PropertyDef propDef;
+ next(IDENTIFIER);
+ propDef.inPrivateClass = lexem();
+ while (test(SCOPE)) {
+ propDef.inPrivateClass += lexem();
+ next(IDENTIFIER);
+ propDef.inPrivateClass += lexem();
+ }
+ // also allow void functions
+ if (test(LPAREN)) {
+ next(RPAREN);
+ propDef.inPrivateClass += "()";
+ }
+
+ next(COMMA);
+
+ createPropertyDef(propDef);
+
+ if(!propDef.notify.isEmpty())
+ def->notifyableProperties++;
+ if (propDef.revision > 0)
+ ++def->revisionedProperties;
+
+ def->propertyList += propDef;
+}
+
+void Moc::parseEnumOrFlag(ClassDef *def, bool isFlag)
+{
+ next(LPAREN);
+ QByteArray identifier;
+ while (test(IDENTIFIER)) {
+ identifier = lexem();
+ while (test(SCOPE) && test(IDENTIFIER)) {
+ identifier += "::";
+ identifier += lexem();
+ }
+ def->enumDeclarations[identifier] = isFlag;
+ }
+ next(RPAREN);
+}
+
+void Moc::parseFlag(ClassDef *def)
+{
+ next(LPAREN);
+ QByteArray flagName, enumName;
+ while (test(IDENTIFIER)) {
+ flagName = lexem();
+ while (test(SCOPE) && test(IDENTIFIER)) {
+ flagName += "::";
+ flagName += lexem();
+ }
+ }
+ next(COMMA);
+ while (test(IDENTIFIER)) {
+ enumName = lexem();
+ while (test(SCOPE) && test(IDENTIFIER)) {
+ enumName += "::";
+ enumName += lexem();
+ }
+ }
+
+ def->flagAliases.insert(enumName, flagName);
+ next(RPAREN);
+}
+
+void Moc::parseClassInfo(ClassDef *def)
+{
+ next(LPAREN);
+ ClassInfoDef infoDef;
+ next(STRING_LITERAL);
+ infoDef.name = symbol().unquotedLexem();
+ next(COMMA);
+ if (test(STRING_LITERAL)) {
+ infoDef.value = symbol().unquotedLexem();
+ } else {
+ // support Q_CLASSINFO("help", QT_TR_NOOP("blah"))
+ next(IDENTIFIER);
+ next(LPAREN);
+ next(STRING_LITERAL);
+ infoDef.value = symbol().unquotedLexem();
+ next(RPAREN);
+ }
+ next(RPAREN);
+ def->classInfoList += infoDef;
+}
+
+void Moc::parseInterfaces(ClassDef *def)
+{
+ next(LPAREN);
+ while (test(IDENTIFIER)) {
+ QList<ClassDef::Interface> iface;
+ iface += ClassDef::Interface(lexem());
+ while (test(SCOPE)) {
+ iface.last().className += lexem();
+ next(IDENTIFIER);
+ iface.last().className += lexem();
+ }
+ while (test(COLON)) {
+ next(IDENTIFIER);
+ iface += ClassDef::Interface(lexem());
+ while (test(SCOPE)) {
+ iface.last().className += lexem();
+ next(IDENTIFIER);
+ iface.last().className += lexem();
+ }
+ }
+ // resolve from classnames to interface ids
+ for (int i = 0; i < iface.count(); ++i) {
+ const QByteArray iid = interface2IdMap.value(iface.at(i).className);
+ if (iid.isEmpty())
+ error("Undefined interface");
+
+ iface[i].interfaceId = iid;
+ }
+ def->interfaceList += iface;
+ }
+ next(RPAREN);
+}
+
+void Moc::parseDeclareInterface()
+{
+ next(LPAREN);
+ QByteArray interface;
+ next(IDENTIFIER);
+ interface += lexem();
+ while (test(SCOPE)) {
+ interface += lexem();
+ next(IDENTIFIER);
+ interface += lexem();
+ }
+ next(COMMA);
+ QByteArray iid;
+ if (test(STRING_LITERAL)) {
+ iid = lexem();
+ } else {
+ next(IDENTIFIER);
+ iid = lexem();
+ }
+ interface2IdMap.insert(interface, iid);
+ next(RPAREN);
+}
+
+void Moc::parseDeclareMetatype()
+{
+ next(LPAREN);
+ QByteArray typeName = lexemUntil(RPAREN);
+ typeName.remove(0, 1);
+ typeName.chop(1);
+ metaTypes.append(typeName);
+}
+
+void Moc::parseSlotInPrivate(ClassDef *def, FunctionDef::Access access)
+{
+ next(LPAREN);
+ FunctionDef funcDef;
+ next(IDENTIFIER);
+ funcDef.inPrivateClass = lexem();
+ // also allow void functions
+ if (test(LPAREN)) {
+ next(RPAREN);
+ funcDef.inPrivateClass += "()";
+ }
+ next(COMMA);
+ funcDef.access = access;
+ parseFunction(&funcDef, true);
+ def->slotList += funcDef;
+ while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
+ funcDef.wasCloned = true;
+ funcDef.arguments.removeLast();
+ def->slotList += funcDef;
+ }
+ if (funcDef.revision > 0)
+ ++def->revisionedMethods;
+
+}
+
+QByteArray Moc::lexemUntil(Token target)
+{
+ int from = index;
+ until(target);
+ QByteArray s;
+ while (from <= index) {
+ QByteArray n = symbols.at(from++-1).lexem();
+ if (s.size() && n.size()
+ && is_ident_char(s.at(s.size()-1))
+ && is_ident_char(n.at(0)))
+ s += ' ';
+ s += n;
+ }
+ return s;
+}
+
+bool Moc::until(Token target) {
+ int braceCount = 0;
+ int brackCount = 0;
+ int parenCount = 0;
+ int angleCount = 0;
+ if (index) {
+ switch(symbols.at(index-1).token) {
+ case LBRACE: ++braceCount; break;
+ case LBRACK: ++brackCount; break;
+ case LPAREN: ++parenCount; break;
+ case LANGLE: ++angleCount; break;
+ default: break;
+ }
+ }
+
+ //when searching commas within the default argument, we should take care of template depth (anglecount)
+ // unfortunatelly, we do not have enough semantic information to know if '<' is the operator< or
+ // the beginning of a template type. so we just use heuristics.
+ int possible = -1;
+
+ while (index < symbols.size()) {
+ Token t = symbols.at(index++).token;
+ switch (t) {
+ case LBRACE: ++braceCount; break;
+ case RBRACE: --braceCount; break;
+ case LBRACK: ++brackCount; break;
+ case RBRACK: --brackCount; break;
+ case LPAREN: ++parenCount; break;
+ case RPAREN: --parenCount; break;
+ case LANGLE: ++angleCount; break;
+ case RANGLE: --angleCount; break;
+ case GTGT: angleCount -= 2; t = RANGLE; break;
+ default: break;
+ }
+ if (t == target
+ && braceCount <= 0
+ && brackCount <= 0
+ && parenCount <= 0
+ && (target != RANGLE || angleCount <= 0)) {
+ if (target != COMMA || angleCount <= 0)
+ return true;
+ possible = index;
+ }
+
+ if (target == COMMA && t == EQ && possible != -1) {
+ index = possible;
+ return true;
+ }
+
+ if (braceCount < 0 || brackCount < 0 || parenCount < 0
+ || (target == RANGLE && angleCount < 0)) {
+ --index;
+ break;
+ }
+ }
+
+ if(target == COMMA && angleCount != 0 && possible != -1) {
+ index = possible;
+ return true;
+ }
+
+ return false;
+}
+
+void Moc::checkSuperClasses(ClassDef *def)
+{
+ const QByteArray firstSuperclass = def->superclassList.value(0).first;
+
+ if (!knownQObjectClasses.contains(firstSuperclass)) {
+ // enable once we /require/ include paths
+#if 0
+ QByteArray msg;
+ msg += "Class ";
+ msg += def->className;
+ msg += " contains the Q_OBJECT macro and inherits from ";
+ msg += def->superclassList.value(0);
+ msg += " but that is not a known QObject subclass. You may get compilation errors.";
+ warning(msg.constData());
+#endif
+ return;
+ }
+ for (int i = 1; i < def->superclassList.count(); ++i) {
+ const QByteArray superClass = def->superclassList.at(i).first;
+ if (knownQObjectClasses.contains(superClass)) {
+ QByteArray msg;
+ msg += "Class ";
+ msg += def->classname;
+ msg += " inherits from two QObject subclasses ";
+ msg += firstSuperclass;
+ msg += " and ";
+ msg += superClass;
+ msg += ". This is not supported!";
+ warning(msg.constData());
+ }
+
+ if (interface2IdMap.contains(superClass)) {
+ bool registeredInterface = false;
+ for (int i = 0; i < def->interfaceList.count(); ++i)
+ if (def->interfaceList.at(i).first().className == superClass) {
+ registeredInterface = true;
+ break;
+ }
+
+ if (!registeredInterface) {
+ QByteArray msg;
+ msg += "Class ";
+ msg += def->classname;
+ msg += " implements the interface ";
+ msg += superClass;
+ msg += " but does not list it in Q_INTERFACES. qobject_cast to ";
+ msg += superClass;
+ msg += " will not work!";
+ warning(msg.constData());
+ }
+ }
+ }
+}
+
+void Moc::checkProperties(ClassDef *cdef)
+{
+ //
+ // specify get function, for compatibiliy we accept functions
+ // returning pointers, or const char * for QByteArray.
+ //
+ for (int i = 0; i < cdef->propertyList.count(); ++i) {
+ PropertyDef &p = cdef->propertyList[i];
+ if (p.read.isEmpty())
+ continue;
+ for (int j = 0; j < cdef->publicList.count(); ++j) {
+ const FunctionDef &f = cdef->publicList.at(j);
+ if (f.name != p.read)
+ continue;
+ if (!f.isConst) // get functions must be const
+ continue;
+ if (f.arguments.size()) // and must not take any arguments
+ continue;
+ PropertyDef::Specification spec = PropertyDef::ValueSpec;
+ QByteArray tmp = f.normalizedType;
+ if (p.type == "QByteArray" && tmp == "const char *")
+ tmp = "QByteArray";
+ if (tmp.left(6) == "const ")
+ tmp = tmp.mid(6);
+ if (p.type != tmp && tmp.endsWith('*')) {
+ tmp.chop(1);
+ spec = PropertyDef::PointerSpec;
+ } else if (f.type.name.endsWith('&')) { // raw type, not normalized type
+ spec = PropertyDef::ReferenceSpec;
+ }
+ if (p.type != tmp)
+ continue;
+ p.gspec = spec;
+ break;
+ }
+ if(!p.notify.isEmpty()) {
+ int notifyId = -1;
+ for (int j = 0; j < cdef->signalList.count(); ++j) {
+ const FunctionDef &f = cdef->signalList.at(j);
+ if(f.name != p.notify) {
+ continue;
+ } else {
+ notifyId = j /* Signal indexes start from 0 */;
+ break;
+ }
+ }
+ p.notifyId = notifyId;
+ if (notifyId == -1) {
+ QByteArray msg = "NOTIFY signal '" + p.notify + "' of property '" + p.name
+ + "' does not exist in class " + cdef->classname + ".";
+ error(msg.constData());
+ }
+ }
+ }
+}
+
+
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
new file mode 100644
index 0000000000..4049534e74
--- /dev/null
+++ b/src/tools/moc/moc.h
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOC_H
+#define MOC_H
+
+#include "parser.h"
+#include <QStringList>
+#include <QMap>
+#include <QPair>
+#include <stdio.h>
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QMetaObject;
+
+struct Type
+{
+ enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
+
+ inline Type() : isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
+ inline explicit Type(const QByteArray &_name) : name(_name), isVolatile(false), isScoped(false), firstToken(NOTOKEN), referenceType(NoReference) {}
+ QByteArray name;
+ uint isVolatile : 1;
+ uint isScoped : 1;
+ Token firstToken;
+ ReferenceType referenceType;
+};
+
+struct EnumDef
+{
+ QByteArray name;
+ QList<QByteArray> values;
+};
+
+struct ArgumentDef
+{
+ ArgumentDef() : isDefault(false) {}
+ Type type;
+ QByteArray rightType, normalizedType, name;
+ QByteArray typeNameForCast; // type name to be used in cast from void * in metacall
+ bool isDefault;
+};
+
+struct FunctionDef
+{
+ FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false), isStatic(false),
+ inlineCode(false), wasCloned(false), isCompat(false), isInvokable(false),
+ isScriptable(false), isSlot(false), isSignal(false),
+ isConstructor(false), isDestructor(false), isAbstract(false), revision(0) {}
+ Type type;
+ QByteArray normalizedType;
+ QByteArray tag;
+ QByteArray name;
+ bool returnTypeIsVolatile;
+
+ QList<ArgumentDef> arguments;
+
+ enum Access { Private, Protected, Public };
+ Access access;
+ bool isConst;
+ bool isVirtual;
+ bool isStatic;
+ bool inlineCode;
+ bool wasCloned;
+
+ QByteArray inPrivateClass;
+ bool isCompat;
+ bool isInvokable;
+ bool isScriptable;
+ bool isSlot;
+ bool isSignal;
+ bool isConstructor;
+ bool isDestructor;
+ bool isAbstract;
+
+ int revision;
+};
+
+struct PropertyDef
+{
+ PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){}
+ QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass;
+ int notifyId;
+ bool constant;
+ bool final;
+ enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
+ Specification gspec;
+ bool stdCppSet() const {
+ QByteArray s("set");
+ s += toupper(name[0]);
+ s += name.mid(1);
+ return (s == write);
+ }
+ int revision;
+};
+
+
+struct ClassInfoDef
+{
+ QByteArray name;
+ QByteArray value;
+};
+
+struct ClassDef {
+ ClassDef():
+ hasQObject(false), hasQGadget(false), notifyableProperties(0)
+ , revisionedMethods(0), revisionedProperties(0), begin(0), end(0){}
+ QByteArray classname;
+ QByteArray qualified;
+ QList<QPair<QByteArray, FunctionDef::Access> > superclassList;
+
+ struct Interface
+ {
+ inline explicit Interface(const QByteArray &_className)
+ : className(_className) {}
+ QByteArray className;
+ QByteArray interfaceId;
+ };
+ QList<QList<Interface> >interfaceList;
+
+ bool hasQObject;
+ bool hasQGadget;
+
+ QList<FunctionDef> constructorList;
+ QList<FunctionDef> signalList, slotList, methodList, publicList;
+ int notifyableProperties;
+ QList<PropertyDef> propertyList;
+ QList<ClassInfoDef> classInfoList;
+ QMap<QByteArray, bool> enumDeclarations;
+ QList<EnumDef> enumList;
+ QMap<QByteArray, QByteArray> flagAliases;
+ int revisionedMethods;
+ int revisionedProperties;
+
+ int begin;
+ int end;
+};
+
+struct NamespaceDef {
+ QByteArray name;
+ int begin;
+ int end;
+};
+
+class Moc : public Parser
+{
+public:
+ Moc()
+ : noInclude(false), generatedCode(false), mustIncludeQMetaTypeH(false)
+ {}
+
+ QByteArray filename;
+
+ bool noInclude;
+ bool generatedCode;
+ bool mustIncludeQMetaTypeH;
+ QByteArray includePath;
+ QList<QByteArray> includeFiles;
+ QList<ClassDef> classList;
+ QMap<QByteArray, QByteArray> interface2IdMap;
+ QList<QByteArray> metaTypes;
+ QSet<QByteArray> knownQObjectClasses;
+
+ void parse();
+ void generate(FILE *out);
+ QList<QMetaObject*> generate(bool ignoreProperties);
+
+ bool parseClassHead(ClassDef *def);
+ inline bool inClass(const ClassDef *def) const {
+ return index > def->begin && index < def->end - 1;
+ }
+
+ inline bool inNamespace(const NamespaceDef *def) const {
+ return index > def->begin && index < def->end - 1;
+ }
+
+ Type parseType();
+
+ bool parseEnum(EnumDef *def);
+
+ bool parseFunction(FunctionDef *def, bool inMacro = false);
+ bool parseMaybeFunction(const ClassDef *cdef, FunctionDef *def);
+
+ void parseSlots(ClassDef *def, FunctionDef::Access access);
+ void parseSignals(ClassDef *def);
+ void parseProperty(ClassDef *def);
+ void createPropertyDef(PropertyDef &def);
+ void parseEnumOrFlag(ClassDef *def, bool isFlag);
+ void parseFlag(ClassDef *def);
+ void parseClassInfo(ClassDef *def);
+ void parseInterfaces(ClassDef *def);
+ void parseDeclareInterface();
+ void parseDeclareMetatype();
+ void parseSlotInPrivate(ClassDef *def, FunctionDef::Access access);
+ void parsePrivateProperty(ClassDef *def);
+
+ void parseFunctionArguments(FunctionDef *def);
+
+ QByteArray lexemUntil(Token);
+ bool until(Token);
+
+ // test for Q_INVOCABLE, Q_SCRIPTABLE, etc. and set the flags
+ // in FunctionDef accordingly
+ bool testFunctionAttribute(FunctionDef *def);
+ bool testFunctionAttribute(Token tok, FunctionDef *def);
+ bool testFunctionRevision(FunctionDef *def);
+
+ void checkSuperClasses(ClassDef *def);
+ void checkProperties(ClassDef* cdef);
+};
+
+inline QByteArray noRef(const QByteArray &type)
+{
+ if (type.endsWith('&')) {
+ if (type.endsWith("&&"))
+ return type.left(type.length()-2);
+ return type.left(type.length()-1);
+ }
+ return type;
+}
+
+QT_END_NAMESPACE
+
+#endif // MOC_H
diff --git a/src/tools/moc/moc.pri b/src/tools/moc/moc.pri
new file mode 100644
index 0000000000..b689a35478
--- /dev/null
+++ b/src/tools/moc/moc.pri
@@ -0,0 +1,16 @@
+
+INCLUDEPATH += $$PWD
+
+HEADERS = $$PWD/moc.h \
+ $$PWD/preprocessor.h \
+ $$PWD/parser.h \
+ $$PWD/symbols.h \
+ $$PWD/token.h \
+ $$PWD/utils.h \
+ $$PWD/generator.h \
+ $$PWD/outputrevision.h
+SOURCES = $$PWD/moc.cpp \
+ $$PWD/preprocessor.cpp \
+ $$PWD/generator.cpp \
+ $$PWD/parser.cpp \
+ $$PWD/token.cpp
diff --git a/src/tools/moc/moc.pro b/src/tools/moc/moc.pro
new file mode 100644
index 0000000000..0b8ddbe31e
--- /dev/null
+++ b/src/tools/moc/moc.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+TARGET = moc
+
+DEFINES += QT_MOC
+DESTDIR = ../../../bin
+INCLUDEPATH += .
+DEPENDPATH += .
+LIBS =
+OBJECTS_DIR = .
+
+include(moc.pri)
+HEADERS += qdatetime_p.h
+SOURCES += main.cpp
+include(../bootstrap/bootstrap.pri)
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+include(../../qt_targets.pri)
diff --git a/src/tools/moc/mwerks_mac.cpp b/src/tools/moc/mwerks_mac.cpp
new file mode 100644
index 0000000000..c2f5d189c7
--- /dev/null
+++ b/src/tools/moc/mwerks_mac.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifdef MOC_MWERKS_PLUGIN
+
+#include "mwerks_mac.h"
+#include "qt_mac.h"
+
+/* compiler headers */
+#include "DropInCompilerLinker.h"
+#include "CompilerMapping.h"
+#include "CWPluginErrors.h"
+
+/* standard headers */
+#include <stdio.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+//qglobal.cpp
+const unsigned char * p_str(const char * c);
+QCString pstring2qstring(const unsigned char *c);
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export on
+#endif
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInFlags)(const DropInFlags** flags, long* flagsSize)
+{
+ static const DropInFlags sFlags = {
+ kCurrentDropInFlagsVersion,
+ CWDROPINCOMPILERTYPE,
+ DROPINCOMPILERLINKERAPIVERSION_7,
+ kCompAlwaysReload|kCompRequiresProjectBuildStartedMsg,
+ Lang_C_CPP,
+ DROPINCOMPILERLINKERAPIVERSION
+ };
+ *flags = &sFlags;
+ *flagsSize = sizeof(sFlags);
+ return cwNoErr;
+}
+
+
+
+CWPLUGIN_ENTRY(CWPlugin_GetDropInName)(const char** dropinName)
+{
+ static const char sDropInName[] = "McMoc";
+ *dropinName = sDropInName;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDisplayName)(const char** displayName)
+{
+ static const char sDisplayName[] = "McMoc";
+ *displayName = sDisplayName;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetTargetList)(const CWTargetList** targetList)
+{
+ static CWDataType sCPU = targetCPUAny;
+ static CWDataType sOS = targetOSMacintosh;
+ static CWTargetList sTargetList = {kCurrentCWTargetListVersion, 1, &sCPU, 1, &sOS};
+ *targetList = &sTargetList;
+ return cwNoErr;
+}
+
+CWPLUGIN_ENTRY(CWPlugin_GetDefaultMappingList)(const CWExtMapList** defaultMappingList)
+{
+ static CWExtensionMapping sExtension[] = { {'TEXT', ".mocs", kPrecompile } };
+ static CWExtMapList sExtensionMapList = {kCurrentCWExtMapListVersion, 3, sExtension};
+ *defaultMappingList = &sExtensionMapList;
+ return cwNoErr;
+}
+
+#if CW_USE_PRAGMA_EXPORT
+#pragma export off
+#endif
+typedef short CWFileRef;
+
+static int line_count = 0;
+moc_status do_moc(CWPluginContext, const QCString &, const QCString &, CWFileSpec *, bool);
+
+static CWResult mocify(CWPluginContext context, const QCString &source)
+{
+ CWDisplayLines(context, line_count++);
+
+ source.stripWhiteSpace();
+
+ CWResult err;
+ bool dotmoc=false;
+ QCString stem = source, ext;
+ int dotpos = stem.findRev('.');
+ if(dotpos != -1) {
+ ext = stem.right(stem.length() - (dotpos+1));
+ stem = stem.left(dotpos);
+ if(ext == "cpp")
+ dotmoc = true;
+ } else {
+ //whoa!
+ }
+ QCString dest;
+ if(dotmoc)
+ dest = stem + ".moc";
+ else
+ dest = "moc_" + stem + ".cpp";
+
+ //moc it
+ CWFileSpec destSpec;
+ moc_status mocd = do_moc(context, source, dest, &destSpec, dotmoc);
+
+#if 0
+ QCString derr = "Weird";
+ switch(mocd) {
+ case moc_success: derr = "Success"; break;
+ case moc_parse_error: derr = "Parser Error"; break;
+ case moc_no_qobject:derr = "No QOBJECT"; break;
+ case moc_not_time: derr = "Not Time"; break;
+ case moc_no_source: derr = "No Source"; break;
+ case moc_general_error: derr = "General Error"; break;
+ }
+ char dmsg[200];
+ sprintf(dmsg, "\"%s\" %s", source.data(), derr.data());
+ CWReportMessage(context, NULL, dmsg, NULL, messagetypeError, 0);
+#endif
+
+ //handle project
+ if(mocd == moc_no_qobject) {
+ char msg[400];
+ sprintf(msg, "\"%s\" No relevant classes found. No output generated.", source.data());
+ CWReportMessage(context, NULL, msg, NULL, messagetypeWarning, 0);
+ } else if ((mocd == moc_success || mocd == moc_not_time) && !dotmoc)
+ {
+ long whichFile;
+ CWNewProjectEntryInfo ei;
+ memset(&ei, '\0', sizeof(ei));
+ ei.groupPath = "QtGenerated";
+ err = CWAddProjectEntry(context, &destSpec, true, &ei, &whichFile);
+ if (!CWSUCCESS(err))
+ {
+ char msg[200];
+ sprintf(msg, "\"%s\" not added", dest.data());
+ CWReportMessage(context, NULL, msg, NULL, messagetypeWarning, 0);
+ }
+ if(mocd == moc_success)
+ CWSetModDate(context, &destSpec, NULL, true);
+ }
+ return cwNoErr;
+}
+
+pascal short main(CWPluginContext context)
+{
+ short result;
+ long request;
+
+ if (CWGetPluginRequest(context, &request) != cwNoErr)
+ return cwErrRequestFailed;
+ result = cwErrInvalidParameter;
+
+ /* dispatch on compiler request */
+ switch (request)
+ {
+ case reqInitCompiler:
+ case reqTermCompiler:
+ result = cwNoErr;
+ break;
+
+ case reqCompile:
+ {
+ line_count = 0;
+ const char *files = NULL;
+ long filelen;
+ CWGetMainFileText(context, &files, &filelen);
+ const char *beg = files;
+ for(int x = 0; x < filelen; x++) {
+ if(*(files++) == '\r') {
+ char file[1024];
+ memcpy(file, beg, files - beg);
+ file[(files-beg)-1] = '\0';
+ mocify(context, file);
+ beg = files;
+ }
+ }
+ if(beg != files) {
+ char file[1024];
+ memcpy(file, beg, files - beg);
+ file[(files-beg)] = '\0';
+ mocify(context, file);
+ }
+
+ result = cwNoErr;
+ break;
+ }
+ }
+
+ /* return result code */
+ return result;
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/mwerks_mac.h b/src/tools/moc/mwerks_mac.h
new file mode 100644
index 0000000000..fe0141e7af
--- /dev/null
+++ b/src/tools/moc/mwerks_mac.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MWERKS_MAC_H
+#define MWERKS_MAC_H
+
+#include <QtGlobal>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_MAC
+
+#define macintosh
+
+/*make moc a plugin*/
+enum moc_status {
+ moc_success = 1,
+ moc_parse_error = 2,
+ moc_no_qobject = 3,
+ moc_not_time = 4,
+ moc_no_source = 5,
+ moc_general_error = 6
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // MWERKS_MAC_H
diff --git a/src/tools/moc/outputrevision.h b/src/tools/moc/outputrevision.h
new file mode 100644
index 0000000000..104a3738dd
--- /dev/null
+++ b/src/tools/moc/outputrevision.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OUTPUTREVISION_H
+#define OUTPUTREVISION_H
+
+// if the output revision changes, you MUST change it in qobjectdefs.h too
+enum { mocOutputRevision = 63 }; // moc format output revision
+
+#endif // OUTPUTREVISION_H
diff --git a/src/tools/moc/parser.cpp b/src/tools/moc/parser.cpp
new file mode 100644
index 0000000000..b6f0837c55
--- /dev/null
+++ b/src/tools/moc/parser.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "parser.h"
+#include "utils.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef USE_LEXEM_STORE
+Symbol::LexemStore Symbol::lexemStore;
+#endif
+
+static const char *error_msg = 0;
+
+#ifdef Q_CC_MSVC
+#define ErrorFormatString "%s(%d): "
+#else
+#define ErrorFormatString "%s:%d: "
+#endif
+
+void Parser::error(int rollback) {
+ index -= rollback;
+ error();
+}
+void Parser::error(const char *msg) {
+ if (msg || error_msg)
+ qWarning(ErrorFormatString "Error: %s",
+ currentFilenames.top().constData(), symbol().lineNum, msg?msg:error_msg);
+ else
+ qWarning(ErrorFormatString "Parse error at \"%s\"",
+ currentFilenames.top().constData(), symbol().lineNum, symbol().lexem().data());
+ exit(EXIT_FAILURE);
+}
+
+void Parser::warning(const char *msg) {
+ if (displayWarnings && msg)
+ fprintf(stderr, ErrorFormatString "Warning: %s\n",
+ currentFilenames.top().constData(), qMax(0, index > 0 ? symbol().lineNum : 0), msg);
+}
+
+void Parser::note(const char *msg) {
+ if (displayNotes && msg)
+ fprintf(stderr, ErrorFormatString "Note: %s\n",
+ currentFilenames.top().constData(), qMax(0, index > 0 ? symbol().lineNum : 0), msg);
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/parser.h b/src/tools/moc/parser.h
new file mode 100644
index 0000000000..a874248f5e
--- /dev/null
+++ b/src/tools/moc/parser.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <QStack>
+#include "symbols.h"
+
+QT_BEGIN_NAMESPACE
+
+class Parser
+{
+public:
+ Parser():index(0), displayWarnings(true), displayNotes(true) {}
+ Symbols symbols;
+ int index;
+ bool displayWarnings;
+ bool displayNotes;
+
+ QStack<QByteArray> currentFilenames;
+
+ inline bool hasNext() const { return (index < symbols.size()); }
+ inline Token next() { if (index >= symbols.size()) return NOTOKEN; return symbols.at(index++).token; }
+ bool test(Token);
+ void next(Token);
+ void next(Token, const char *msg);
+ inline void prev() {--index;}
+ inline Token lookup(int k = 1);
+ inline const Symbol &symbol_lookup(int k = 1) { return symbols.at(index-1+k);}
+ inline Token token() { return symbols.at(index-1).token;}
+ inline QByteArray lexem() { return symbols.at(index-1).lexem();}
+ inline QByteArray unquotedLexem() { return symbols.at(index-1).unquotedLexem();}
+ inline const Symbol &symbol() { return symbols.at(index-1);}
+
+ void error(int rollback);
+ void error(const char *msg = 0);
+ void warning(const char * = 0);
+ void note(const char * = 0);
+
+};
+
+inline bool Parser::test(Token token)
+{
+ if (index < symbols.size() && symbols.at(index).token == token) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+inline Token Parser::lookup(int k)
+{
+ const int l = index - 1 + k;
+ return l < symbols.size() ? symbols.at(l).token : NOTOKEN;
+}
+
+inline void Parser::next(Token token)
+{
+ if (!test(token))
+ error();
+}
+
+inline void Parser::next(Token token, const char *msg)
+{
+ if (!test(token))
+ error(msg);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/tools/moc/ppkeywords.cpp b/src/tools/moc/ppkeywords.cpp
new file mode 100644
index 0000000000..69aa72a05d
--- /dev/null
+++ b/src/tools/moc/ppkeywords.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// auto generated
+// DO NOT EDIT.
+
+static const short pp_keyword_trans[][128] = {
+ {0,0,0,0,0,0,0,0,0,98,12,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 98,76,96,13,0,60,62,97,9,10,58,56,11,57,102,59,
+ 6,6,6,6,6,6,6,6,6,6,92,0,7,81,8,91,
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,0,101,0,61,1,
+ 0,1,2,3,4,1,1,1,1,1,1,1,1,1,5,1,
+ 1,1,1,1,1,1,1,1,1,1,1,0,68,0,71,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,79,87,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,88,80,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,93,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,14,34,0,0,0,20,0,0,0,0,0,0,
+ 0,0,0,0,0,22,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,21,0,0,0,0,0,0,0,44,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,27,0,0,0,0,0,0,0,0,0,30,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,35,0,40,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,
+ 0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,99,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,65,0,0,0,0,0,0,0,0,0,0,0,0,0,69,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 103,103,103,103,103,103,103,103,103,103,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
+
+static const struct
+{
+ PP_Token token;
+ short next;
+ char defchar;
+ short defnext;
+ PP_Token ident;
+} pp_keywords[] = {
+ {PP_NOTOKEN, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 105, 63, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 111, 72, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 101, 50, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 111, 77, PP_NOTOKEN},
+ {PP_DIGIT, 0, 0, 0, PP_NOTOKEN},
+ {PP_LANGLE, 1, 0, 0, PP_NOTOKEN},
+ {PP_RANGLE, 2, 0, 0, PP_NOTOKEN},
+ {PP_LPAREN, 0, 0, 0, PP_NOTOKEN},
+ {PP_RPAREN, 0, 0, 0, PP_NOTOKEN},
+ {PP_COMMA, 0, 0, 0, PP_NOTOKEN},
+ {PP_NEWLINE, 0, 0, 0, PP_NOTOKEN},
+ {PP_HASH, 3, 0, 0, PP_HASH},
+ {PP_HASH, 0, 101, 15, PP_HASH},
+ {PP_HASH, 0, 102, 16, PP_HASH},
+ {PP_HASH, 0, 105, 17, PP_HASH},
+ {PP_HASH, 0, 110, 18, PP_HASH},
+ {PP_HASH, 0, 101, 19, PP_HASH},
+ {PP_DEFINE, 0, 0, 0, PP_HASH},
+ {PP_HASH, 4, 0, 0, PP_HASH},
+ {PP_IF, 5, 0, 0, PP_HASH},
+ {PP_HASH, 0, 110, 23, PP_HASH},
+ {PP_HASH, 0, 100, 24, PP_HASH},
+ {PP_HASH, 0, 101, 25, PP_HASH},
+ {PP_HASH, 0, 102, 26, PP_HASH},
+ {PP_UNDEF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 101, 28, PP_HASH},
+ {PP_HASH, 0, 102, 29, PP_HASH},
+ {PP_IFDEF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 100, 31, PP_HASH},
+ {PP_HASH, 0, 101, 32, PP_HASH},
+ {PP_HASH, 0, 102, 33, PP_HASH},
+ {PP_IFNDEF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 6, 0, 0, PP_HASH},
+ {PP_HASH, 7, 0, 0, PP_HASH},
+ {PP_HASH, 0, 102, 37, PP_HASH},
+ {PP_ELIF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 101, 39, PP_HASH},
+ {PP_ELSE, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 100, 41, PP_HASH},
+ {PP_HASH, 0, 105, 42, PP_HASH},
+ {PP_HASH, 0, 102, 43, PP_HASH},
+ {PP_ENDIF, 0, 0, 0, PP_HASH},
+ {PP_HASH, 0, 99, 45, PP_HASH},
+ {PP_HASH, 0, 108, 46, PP_HASH},
+ {PP_HASH, 0, 117, 47, PP_HASH},
+ {PP_HASH, 0, 100, 48, PP_HASH},
+ {PP_HASH, 0, 101, 49, PP_HASH},
+ {PP_INCLUDE, 0, 0, 0, PP_HASH},
+ {PP_CHARACTER, 0, 102, 51, PP_CHARACTER},
+ {PP_CHARACTER, 0, 105, 52, PP_CHARACTER},
+ {PP_CHARACTER, 0, 110, 53, PP_CHARACTER},
+ {PP_CHARACTER, 0, 101, 54, PP_CHARACTER},
+ {PP_CHARACTER, 0, 100, 55, PP_CHARACTER},
+ {PP_DEFINED, 0, 0, 0, PP_CHARACTER},
+ {PP_PLUS, 0, 0, 0, PP_NOTOKEN},
+ {PP_MINUS, 0, 0, 0, PP_NOTOKEN},
+ {PP_STAR, 0, 0, 0, PP_NOTOKEN},
+ {PP_SLASH, 8, 0, 0, PP_NOTOKEN},
+ {PP_PERCENT, 0, 58, 94, PP_NOTOKEN},
+ {PP_HAT, 0, 0, 0, PP_NOTOKEN},
+ {PP_AND, 0, 38, 89, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 116, 64, PP_CHARACTER},
+ {PP_CHARACTER, 9, 0, 0, PP_CHARACTER},
+ {PP_CHARACTER, 0, 110, 66, PP_CHARACTER},
+ {PP_CHARACTER, 0, 100, 67, PP_CHARACTER},
+ {PP_AND, 0, 0, 0, PP_CHARACTER},
+ {PP_OR, 0, 124, 90, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 114, 70, PP_CHARACTER},
+ {PP_OR, 0, 0, 0, PP_CHARACTER},
+ {PP_TILDE, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 109, 73, PP_CHARACTER},
+ {PP_CHARACTER, 0, 112, 74, PP_CHARACTER},
+ {PP_CHARACTER, 0, 108, 75, PP_CHARACTER},
+ {PP_TILDE, 0, 0, 0, PP_CHARACTER},
+ {PP_NOT, 0, 61, 83, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 116, 78, PP_CHARACTER},
+ {PP_NOT, 0, 95, 84, PP_CHARACTER},
+ {PP_LTLT, 0, 0, 0, PP_NOTOKEN},
+ {PP_GTGT, 0, 0, 0, PP_NOTOKEN},
+ {PP_INCOMPLETE, 0, 61, 82, PP_NOTOKEN},
+ {PP_EQEQ, 0, 0, 0, PP_NOTOKEN},
+ {PP_NE, 0, 0, 0, PP_NOTOKEN},
+ {PP_CHARACTER, 0, 101, 85, PP_CHARACTER},
+ {PP_CHARACTER, 0, 113, 86, PP_CHARACTER},
+ {PP_NE, 0, 0, 0, PP_CHARACTER},
+ {PP_LE, 0, 0, 0, PP_NOTOKEN},
+ {PP_GE, 0, 0, 0, PP_NOTOKEN},
+ {PP_ANDAND, 0, 0, 0, PP_NOTOKEN},
+ {PP_OROR, 0, 0, 0, PP_NOTOKEN},
+ {PP_QUESTION, 0, 0, 0, PP_NOTOKEN},
+ {PP_COLON, 0, 0, 0, PP_NOTOKEN},
+ {PP_HASHHASH, 0, 0, 0, PP_NOTOKEN},
+ {PP_INCOMPLETE, 0, 37, 95, PP_NOTOKEN},
+ {PP_INCOMPLETE, 0, 58, 93, PP_NOTOKEN},
+ {PP_QUOTE, 0, 0, 0, PP_NOTOKEN},
+ {PP_SINGLEQUOTE, 0, 0, 0, PP_NOTOKEN},
+ {PP_WHITESPACE, 0, 0, 0, PP_NOTOKEN},
+ {PP_CPP_COMMENT, 0, 0, 0, PP_NOTOKEN},
+ {PP_C_COMMENT, 0, 0, 0, PP_NOTOKEN},
+ {PP_BACKSLASH, 0, 0, 0, PP_NOTOKEN},
+ {PP_INCOMPLETE, 10, 0, 0, PP_NOTOKEN},
+ {PP_FLOATING_LITERAL, 0, 0, 0, PP_NOTOKEN}
+};
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
new file mode 100644
index 0000000000..fbea82d7fa
--- /dev/null
+++ b/src/tools/moc/preprocessor.cpp
@@ -0,0 +1,978 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "preprocessor.h"
+#include "utils.h"
+#include <QStringList>
+#include <QFile>
+#include <QDir>
+#include <QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+#include "ppkeywords.cpp"
+#include "keywords.cpp"
+
+// transform \r\n into \n
+// \r into \n (os9 style)
+// backslash-newlines into newlines
+static QByteArray cleaned(const QByteArray &input)
+{
+ QByteArray result;
+ result.reserve(input.size());
+ const char *data = input;
+ char *output = result.data();
+
+ int newlines = 0;
+ while (*data) {
+ while (*data && is_space(*data))
+ ++data;
+ bool takeLine = (*data == '#');
+ if (*data == '%' && *(data+1) == ':') {
+ takeLine = true;
+ ++data;
+ }
+ if (takeLine) {
+ *output = '#';
+ ++output;
+ do ++data; while (*data && is_space(*data));
+ }
+ while (*data) {
+ // handle \\\n, \\\r\n and \\\r
+ if (*data == '\\') {
+ if (*(data + 1) == '\r') {
+ ++data;
+ }
+ if (*data && (*(data + 1) == '\n' || (*data) == '\r')) {
+ ++newlines;
+ data += 1;
+ if (*data != '\r')
+ data += 1;
+ continue;
+ }
+ } else if (*data == '\r' && *(data + 1) == '\n') { // reduce \r\n to \n
+ ++data;
+ }
+
+ char ch = *data;
+ if (ch == '\r') // os9: replace \r with \n
+ ch = '\n';
+ *output = ch;
+ ++output;
+
+ if (*data == '\n') {
+ // output additional newlines to keep the correct line-numbering
+ // for the lines following the backslash-newline sequence(s)
+ while (newlines) {
+ *output = '\n';
+ ++output;
+ --newlines;
+ }
+ ++data;
+ break;
+ }
+ ++data;
+ }
+ }
+ result.resize(output - result.constData());
+ return result;
+}
+
+bool Preprocessor::preprocessOnly = false;
+void Preprocessor::skipUntilEndif()
+{
+ while(index < symbols.size() - 1 && symbols.at(index).token != PP_ENDIF){
+ switch (symbols.at(index).token) {
+ case PP_IF:
+ case PP_IFDEF:
+ case PP_IFNDEF:
+ ++index;
+ skipUntilEndif();
+ break;
+ default:
+ ;
+ }
+ ++index;
+ }
+}
+
+bool Preprocessor::skipBranch()
+{
+ while (index < symbols.size() - 1
+ && (symbols.at(index).token != PP_ENDIF
+ && symbols.at(index).token != PP_ELIF
+ && symbols.at(index).token != PP_ELSE)
+ ){
+ switch (symbols.at(index).token) {
+ case PP_IF:
+ case PP_IFDEF:
+ case PP_IFNDEF:
+ ++index;
+ skipUntilEndif();
+ break;
+ default:
+ ;
+ }
+ ++index;
+ }
+ return (index < symbols.size() - 1);
+}
+
+
+enum TokenizeMode { TokenizeCpp, TokenizePreprocessor, PreparePreprocessorStatement, TokenizePreprocessorStatement, TokenizeInclude };
+static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp)
+{
+ Symbols symbols;
+ const char *begin = input;
+ const char *data = begin;
+ while (*data) {
+ if (mode == TokenizeCpp) {
+ int column = 0;
+
+ const char *lexem = data;
+ int state = 0;
+ Token token = NOTOKEN;
+ for (;;) {
+ if (static_cast<signed char>(*data) < 0) {
+ ++data;
+ continue;
+ }
+ int nextindex = keywords[state].next;
+ int next = 0;
+ if (*data == keywords[state].defchar)
+ next = keywords[state].defnext;
+ else if (!state || nextindex)
+ next = keyword_trans[nextindex][(int)*data];
+ if (!next)
+ break;
+ state = next;
+ token = keywords[state].token;
+ ++data;
+ }
+
+ // suboptimal, is_ident_char should use a table
+ if (keywords[state].ident && is_ident_char(*data))
+ token = keywords[state].ident;
+
+ if (token == NOTOKEN) {
+ // an error really
+ ++data;
+ continue;
+ }
+
+ ++column;
+
+ if (token > SPECIAL_TREATMENT_MARK) {
+ switch (token) {
+ case QUOTE:
+ data = skipQuote(data);
+ token = STRING_LITERAL;
+ // concatenate multi-line strings for easier
+ // STRING_LITERAAL handling in moc
+ if (!Preprocessor::preprocessOnly
+ && !symbols.isEmpty()
+ && symbols.last().token == STRING_LITERAL) {
+
+ QByteArray newString = symbols.last().unquotedLexem();
+ newString += input.mid(lexem - begin + 1, data - lexem - 2);
+ newString.prepend('\"');
+ newString.append('\"');
+ symbols.last() = Symbol(symbols.last().lineNum,
+ STRING_LITERAL,
+ newString);
+ continue;
+ }
+ break;
+ case SINGLEQUOTE:
+ while (*data && (*data != '\''
+ || (*(data-1)=='\\'
+ && *(data-2)!='\\')))
+ ++data;
+ if (*data)
+ ++data;
+ token = CHARACTER_LITERAL;
+ break;
+ case LANGLE_SCOPE:
+ // split <:: into two tokens, < and ::
+ token = LANGLE;
+ data -= 2;
+ break;
+ case DIGIT:
+ while (is_digit_char(*data))
+ ++data;
+ if (!*data || *data != '.') {
+ token = INTEGER_LITERAL;
+ if (data - lexem == 1 &&
+ (*data == 'x' || *data == 'X')
+ && *lexem == '0') {
+ ++data;
+ while (is_hex_char(*data))
+ ++data;
+ }
+ break;
+ }
+ token = FLOATING_LITERAL;
+ ++data;
+ // fall through
+ case FLOATING_LITERAL:
+ while (is_digit_char(*data))
+ ++data;
+ if (*data == '+' || *data == '-')
+ ++data;
+ if (*data == 'e' || *data == 'E') {
+ ++data;
+ while (is_digit_char(*data))
+ ++data;
+ }
+ if (*data == 'f' || *data == 'F'
+ || *data == 'l' || *data == 'L')
+ ++data;
+ break;
+ case HASH:
+ if (column == 1) {
+ mode = PreparePreprocessorStatement;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (is_ident_char(*data))
+ mode = TokenizePreprocessorStatement;
+ continue;
+ }
+ break;
+ case NEWLINE:
+ ++lineNum;
+ continue;
+ case BACKSLASH:
+ {
+ const char *rewind = data;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (*data && *data == '\n') {
+ ++data;
+ continue;
+ }
+ data = rewind;
+ } break;
+ case CHARACTER:
+ while (is_ident_char(*data))
+ ++data;
+ token = IDENTIFIER;
+ break;
+ case C_COMMENT:
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ }
+ while (*data && (*(data-1) != '/' || *(data-2) != '*')) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ token = WHITESPACE; // one comment, one whitespace
+ // fall through;
+ case WHITESPACE:
+ if (column == 1)
+ column = 0;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (Preprocessor::preprocessOnly) // tokenize whitespace
+ break;
+ continue;
+ case CPP_COMMENT:
+ while (*data && *data != '\n')
+ ++data;
+ continue; // ignore safely, the newline is a separator
+ default:
+ continue; //ignore
+ }
+ }
+#ifdef USE_LEXEM_STORE
+ if (!Preprocessor::preprocessOnly
+ && token != IDENTIFIER
+ && token != STRING_LITERAL
+ && token != FLOATING_LITERAL
+ && token != INTEGER_LITERAL)
+ symbols += Symbol(lineNum, token);
+ else
+#endif
+ symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem);
+
+ } else { // Preprocessor
+
+ const char *lexem = data;
+ int state = 0;
+ Token token = NOTOKEN;
+ if (mode == TokenizePreprocessorStatement) {
+ state = pp_keyword_trans[0][(int)'#'];
+ mode = TokenizePreprocessor;
+ }
+ for (;;) {
+ if (static_cast<signed char>(*data) < 0) {
+ ++data;
+ continue;
+ }
+
+ int nextindex = pp_keywords[state].next;
+ int next = 0;
+ if (*data == pp_keywords[state].defchar)
+ next = pp_keywords[state].defnext;
+ else if (!state || nextindex)
+ next = pp_keyword_trans[nextindex][(int)*data];
+ if (!next)
+ break;
+ state = next;
+ token = pp_keywords[state].token;
+ ++data;
+ }
+ // suboptimal, is_ident_char should use a table
+ if (pp_keywords[state].ident && is_ident_char(*data))
+ token = pp_keywords[state].ident;
+
+ switch (token) {
+ case NOTOKEN:
+ ++data;
+ break;
+ case PP_IFDEF:
+ symbols += Symbol(lineNum, PP_IF);
+ symbols += Symbol(lineNum, PP_DEFINED);
+ continue;
+ case PP_IFNDEF:
+ symbols += Symbol(lineNum, PP_IF);
+ symbols += Symbol(lineNum, PP_NOT);
+ symbols += Symbol(lineNum, PP_DEFINED);
+ continue;
+ case PP_INCLUDE:
+ mode = TokenizeInclude;
+ break;
+ case PP_QUOTE:
+ data = skipQuote(data);
+ token = PP_STRING_LITERAL;
+ break;
+ case PP_SINGLEQUOTE:
+ while (*data && (*data != '\''
+ || (*(data-1)=='\\'
+ && *(data-2)!='\\')))
+ ++data;
+ if (*data)
+ ++data;
+ token = PP_CHARACTER_LITERAL;
+ break;
+ case PP_DIGIT:
+ while (is_digit_char(*data))
+ ++data;
+ if (!*data || *data != '.') {
+ token = PP_INTEGER_LITERAL;
+ if (data - lexem == 1 &&
+ (*data == 'x' || *data == 'X')
+ && *lexem == '0') {
+ ++data;
+ while (is_hex_char(*data))
+ ++data;
+ }
+ break;
+ }
+ token = PP_FLOATING_LITERAL;
+ ++data;
+ // fall through
+ case PP_FLOATING_LITERAL:
+ while (is_digit_char(*data))
+ ++data;
+ if (*data == '+' || *data == '-')
+ ++data;
+ if (*data == 'e' || *data == 'E') {
+ ++data;
+ while (is_digit_char(*data))
+ ++data;
+ }
+ if (*data == 'f' || *data == 'F'
+ || *data == 'l' || *data == 'L')
+ ++data;
+ break;
+ case PP_CHARACTER:
+ if (mode == PreparePreprocessorStatement) {
+ // rewind entire token to begin
+ data = lexem;
+ mode = TokenizePreprocessorStatement;
+ continue;
+ }
+ while (is_ident_char(*data))
+ ++data;
+ token = PP_IDENTIFIER;
+ break;
+ case PP_C_COMMENT:
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ if (*data) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ }
+ while (*data && (*(data-1) != '/' || *(data-2) != '*')) {
+ if (*data == '\n')
+ ++lineNum;
+ ++data;
+ }
+ token = PP_WHITESPACE; // one comment, one whitespace
+ // fall through;
+ case PP_WHITESPACE:
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ continue; // the preprocessor needs no whitespace
+ case PP_CPP_COMMENT:
+ while (*data && *data != '\n')
+ ++data;
+ continue; // ignore safely, the newline is a separator
+ case PP_NEWLINE:
+ ++lineNum;
+ mode = TokenizeCpp;
+ break;
+ case PP_BACKSLASH:
+ {
+ const char *rewind = data;
+ while (*data && (*data == ' ' || *data == '\t'))
+ ++data;
+ if (*data && *data == '\n') {
+ ++data;
+ continue;
+ }
+ data = rewind;
+ } break;
+ case PP_LANGLE:
+ if (mode != TokenizeInclude)
+ break;
+ token = PP_STRING_LITERAL;
+ while (*data && *data != '\n' && *(data-1) != '>')
+ ++data;
+ break;
+ default:
+ break;
+ }
+ if (mode == PreparePreprocessorStatement)
+ continue;
+#ifdef USE_LEXEM_STORE
+ if (token != PP_IDENTIFIER
+ && token != PP_STRING_LITERAL
+ && token != PP_FLOATING_LITERAL
+ && token != PP_INTEGER_LITERAL)
+ symbols += Symbol(lineNum, token);
+ else
+#endif
+ symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem);
+ }
+ }
+ symbols += Symbol(); // eof symbol
+ return symbols;
+}
+
+void Preprocessor::substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset)
+{
+ Symbols saveSymbols = symbols;
+ int saveIndex = index;
+
+ symbols = macros.value(macro).symbols;
+ index = 0;
+
+ safeset += macro;
+ substituteUntilNewline(substituted, safeset);
+
+ symbols = saveSymbols;
+ index = saveIndex;
+}
+
+
+
+void Preprocessor::substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset)
+{
+ while (hasNext()) {
+ Token token = next();
+ if (token == PP_IDENTIFIER) {
+ MacroName macro = symbol();
+ if (macros.contains(macro) && !safeset.contains(macro)) {
+ substituteMacro(macro, substituted, safeset);
+ continue;
+ }
+ } else if (token == PP_DEFINED) {
+ test(PP_LPAREN);
+ next(PP_IDENTIFIER);
+ Symbol definedOrNotDefined = symbol();
+ definedOrNotDefined.token = macros.contains(definedOrNotDefined)? PP_MOC_TRUE : PP_MOC_FALSE;
+ substituted += definedOrNotDefined;
+ test(PP_RPAREN);
+ continue;
+ } else if (token == PP_NEWLINE) {
+ substituted += symbol();
+ break;
+ }
+ substituted += symbol();
+ }
+}
+
+
+class PP_Expression : public Parser
+{
+public:
+ int value() { index = 0; return unary_expression_lookup() ? conditional_expression() : 0; }
+
+ int conditional_expression();
+ int logical_OR_expression();
+ int logical_AND_expression();
+ int inclusive_OR_expression();
+ int exclusive_OR_expression();
+ int AND_expression();
+ int equality_expression();
+ int relational_expression();
+ int shift_expression();
+ int additive_expression();
+ int multiplicative_expression();
+ int unary_expression();
+ bool unary_expression_lookup();
+ int primary_expression();
+ bool primary_expression_lookup();
+};
+
+int PP_Expression::conditional_expression()
+{
+ int value = logical_OR_expression();
+ if (test(PP_QUESTION)) {
+ int alt1 = conditional_expression();
+ int alt2 = test(PP_COLON) ? conditional_expression() : 0;
+ return value ? alt1 : alt2;
+ }
+ return value;
+}
+
+int PP_Expression::logical_OR_expression()
+{
+ int value = logical_AND_expression();
+ if (test(PP_OROR))
+ return logical_OR_expression() || value;
+ return value;
+}
+
+int PP_Expression::logical_AND_expression()
+{
+ int value = inclusive_OR_expression();
+ if (test(PP_ANDAND))
+ return logical_AND_expression() && value;
+ return value;
+}
+
+int PP_Expression::inclusive_OR_expression()
+{
+ int value = exclusive_OR_expression();
+ if (test(PP_OR))
+ return value | inclusive_OR_expression();
+ return value;
+}
+
+int PP_Expression::exclusive_OR_expression()
+{
+ int value = AND_expression();
+ if (test(PP_HAT))
+ return value ^ exclusive_OR_expression();
+ return value;
+}
+
+int PP_Expression::AND_expression()
+{
+ int value = equality_expression();
+ if (test(PP_AND))
+ return value & AND_expression();
+ return value;
+}
+
+int PP_Expression::equality_expression()
+{
+ int value = relational_expression();
+ switch (next()) {
+ case PP_EQEQ:
+ return value == equality_expression();
+ case PP_NE:
+ return value != equality_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::relational_expression()
+{
+ int value = shift_expression();
+ switch (next()) {
+ case PP_LANGLE:
+ return value < relational_expression();
+ case PP_RANGLE:
+ return value > relational_expression();
+ case PP_LE:
+ return value <= relational_expression();
+ case PP_GE:
+ return value >= relational_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::shift_expression()
+{
+ int value = additive_expression();
+ switch (next()) {
+ case PP_LTLT:
+ return value << shift_expression();
+ case PP_GTGT:
+ return value >> shift_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::additive_expression()
+{
+ int value = multiplicative_expression();
+ switch (next()) {
+ case PP_PLUS:
+ return value + additive_expression();
+ case PP_MINUS:
+ return value - additive_expression();
+ default:
+ prev();
+ return value;
+ }
+}
+
+int PP_Expression::multiplicative_expression()
+{
+ int value = unary_expression();
+ switch (next()) {
+ case PP_STAR:
+ return value * multiplicative_expression();
+ case PP_PERCENT:
+ {
+ int remainder = multiplicative_expression();
+ return remainder ? value % remainder : 0;
+ }
+ case PP_SLASH:
+ {
+ int div = multiplicative_expression();
+ return div ? value / div : 0;
+ }
+ default:
+ prev();
+ return value;
+ };
+}
+
+int PP_Expression::unary_expression()
+{
+ switch (next()) {
+ case PP_PLUS:
+ return unary_expression();
+ case PP_MINUS:
+ return -unary_expression();
+ case PP_NOT:
+ return !unary_expression();
+ case PP_TILDE:
+ return ~unary_expression();
+ case PP_MOC_TRUE:
+ return 1;
+ case PP_MOC_FALSE:
+ return 0;
+ default:
+ prev();
+ return primary_expression();
+ }
+}
+
+bool PP_Expression::unary_expression_lookup()
+{
+ Token t = lookup();
+ return (primary_expression_lookup()
+ || t == PP_PLUS
+ || t == PP_MINUS
+ || t == PP_NOT
+ || t == PP_TILDE
+ || t == PP_DEFINED);
+}
+
+int PP_Expression::primary_expression()
+{
+ int value;
+ if (test(PP_LPAREN)) {
+ value = conditional_expression();
+ test(PP_RPAREN);
+ } else {
+ next();
+ value = lexem().toInt(0, 0);
+ }
+ return value;
+}
+
+bool PP_Expression::primary_expression_lookup()
+{
+ Token t = lookup();
+ return (t == PP_IDENTIFIER
+ || t == PP_INTEGER_LITERAL
+ || t == PP_FLOATING_LITERAL
+ || t == PP_MOC_TRUE
+ || t == PP_MOC_FALSE
+ || t == PP_LPAREN);
+}
+
+int Preprocessor::evaluateCondition()
+{
+ PP_Expression expression;
+ expression.currentFilenames = currentFilenames;
+
+ substituteUntilNewline(expression.symbols);
+
+ return expression.value();
+}
+
+void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed)
+{
+ currentFilenames.push(filename);
+ preprocessed.reserve(preprocessed.size() + symbols.size());
+ while (hasNext()) {
+ Token token = next();
+
+ switch (token) {
+ case PP_INCLUDE:
+ {
+ int lineNum = symbol().lineNum;
+ QByteArray include;
+ bool local = false;
+ if (test(PP_STRING_LITERAL)) {
+ local = lexem().startsWith('\"');
+ include = unquotedLexem();
+ } else
+ continue;
+ until(PP_NEWLINE);
+
+ // #### stringery
+ QFileInfo fi;
+ if (local)
+ fi.setFile(QFileInfo(QString::fromLocal8Bit(filename)).dir(), QString::fromLocal8Bit(include));
+ for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) {
+ const IncludePath &p = Preprocessor::includes.at(j);
+ if (p.isFrameworkPath) {
+ const int slashPos = include.indexOf('/');
+ if (slashPos == -1)
+ continue;
+ QByteArray frameworkCandidate = include.left(slashPos);
+ frameworkCandidate.append(".framework/Headers/");
+ fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate)), QString::fromLocal8Bit(include.mid(slashPos + 1)));
+ } else {
+ fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include));
+ }
+ // try again, maybe there's a file later in the include paths with the same name
+ // (186067)
+ if (fi.isDir()) {
+ fi = QFileInfo();
+ continue;
+ }
+ }
+
+ if (!fi.exists() || fi.isDir())
+ continue;
+ include = fi.canonicalFilePath().toLocal8Bit();
+
+ if (Preprocessor::preprocessedIncludes.contains(include))
+ continue;
+ Preprocessor::preprocessedIncludes.insert(include);
+
+ QFile file(QString::fromLocal8Bit(include));
+ if (!file.open(QFile::ReadOnly))
+ continue;
+
+ QByteArray input = file.readAll();
+ file.close();
+ if (input.isEmpty())
+ continue;
+
+ Symbols saveSymbols = symbols;
+ int saveIndex = index;
+
+ // phase 1: get rid of backslash-newlines
+ input = cleaned(input);
+
+ // phase 2: tokenize for the preprocessor
+ symbols = tokenize(input);
+ input.clear();
+
+ index = 0;
+
+ // phase 3: preprocess conditions and substitute macros
+ preprocessed += Symbol(0, MOC_INCLUDE_BEGIN, include);
+ preprocess(include, preprocessed);
+ preprocessed += Symbol(lineNum, MOC_INCLUDE_END, include);
+
+ symbols = saveSymbols;
+ index = saveIndex;
+ continue;
+ }
+ case PP_DEFINE:
+ {
+ next(IDENTIFIER);
+ QByteArray name = lexem();
+ int start = index;
+ until(PP_NEWLINE);
+ Macro macro;
+ macro.symbols.reserve(index - start - 1);
+ for (int i = start; i < index - 1; ++i)
+ macro.symbols += symbols.at(i);
+ macros.insert(name, macro);
+ continue;
+ }
+ case PP_UNDEF: {
+ next(IDENTIFIER);
+ QByteArray name = lexem();
+ until(PP_NEWLINE);
+ macros.remove(name);
+ continue;
+ }
+ case PP_IDENTIFIER:
+ {
+// if (macros.contains(symbol()))
+// ;
+ }
+ // we _could_ easily substitute macros by the following
+ // four lines, but we choose not to.
+ /*
+ if (macros.contains(sym.lexem())) {
+ preprocessed += substitute(macros, symbols, i);
+ continue;
+ }
+ */
+ break;
+ case PP_HASH:
+ until(PP_NEWLINE);
+ continue; // skip unknown preprocessor statement
+ case PP_IFDEF:
+ case PP_IFNDEF:
+ case PP_IF:
+ while (!evaluateCondition()) {
+ if (!skipBranch())
+ break;
+ if (test(PP_ELIF)) {
+ } else {
+ until(PP_NEWLINE);
+ break;
+ }
+ }
+ continue;
+ case PP_ELIF:
+ case PP_ELSE:
+ skipUntilEndif();
+ // fall through
+ case PP_ENDIF:
+ until(PP_NEWLINE);
+ continue;
+ case SIGNALS:
+ case SLOTS: {
+ Symbol sym = symbol();
+ if (macros.contains("QT_NO_KEYWORDS"))
+ sym.token = IDENTIFIER;
+ else
+ sym.token = (token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN);
+ preprocessed += sym;
+ } continue;
+ default:
+ break;
+ }
+ preprocessed += symbol();
+ }
+
+ currentFilenames.pop();
+}
+
+Symbols Preprocessor::preprocessed(const QByteArray &filename, FILE *file)
+{
+ QFile qfile;
+ qfile.open(file, QFile::ReadOnly);
+ QByteArray input = qfile.readAll();
+ if (input.isEmpty())
+ return symbols;
+
+ // phase 1: get rid of backslash-newlines
+ input = cleaned(input);
+
+ // phase 2: tokenize for the preprocessor
+ symbols = tokenize(input);
+
+#if 0
+ for (int j = 0; j < symbols.size(); ++j)
+ fprintf(stderr, "line %d: %s(%s)\n",
+ symbols[j].lineNum,
+ symbols[j].lexem().constData(),
+ tokenTypeName(symbols[j].token));
+#endif
+
+ // phase 3: preprocess conditions and substitute macros
+ Symbols result;
+ preprocess(filename, result);
+
+#if 0
+ for (int j = 0; j < result.size(); ++j)
+ fprintf(stderr, "line %d: %s(%s)\n",
+ result[j].lineNum,
+ result[j].lexem().constData(),
+ tokenTypeName(result[j].token));
+#endif
+
+ return result;
+}
+
+void Preprocessor::until(Token t)
+{
+ while(hasNext() && next() != t)
+ ;
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h
new file mode 100644
index 0000000000..c1b3569dcf
--- /dev/null
+++ b/src/tools/moc/preprocessor.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREPROCESSOR_H
+#define PREPROCESSOR_H
+
+#include "parser.h"
+#include <QList>
+#include <QSet>
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+struct Macro
+{
+ Symbols symbols;
+};
+
+#ifdef USE_LEXEM_STORE
+typedef QByteArray MacroName;
+#else
+typedef SubArray MacroName;
+#endif
+typedef QHash<MacroName, Macro> Macros;
+typedef QVector<MacroName> MacroSafeSet;
+
+
+class Preprocessor : public Parser
+{
+public:
+ Preprocessor(){}
+ static bool preprocessOnly;
+ struct IncludePath
+ {
+ inline explicit IncludePath(const QByteArray &_path)
+ : path(_path), isFrameworkPath(false) {}
+ QByteArray path;
+ bool isFrameworkPath;
+ };
+ QList<IncludePath> includes;
+ QList<QByteArray> frameworks;
+ QSet<QByteArray> preprocessedIncludes;
+ Macros macros;
+ Symbols preprocessed(const QByteArray &filename, FILE *file);
+
+
+ void skipUntilEndif();
+ bool skipBranch();
+
+ void substituteMacro(const MacroName &macro, Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
+ void substituteUntilNewline(Symbols &substituted, MacroSafeSet safeset = MacroSafeSet());
+
+ int evaluateCondition();
+
+
+private:
+ void until(Token);
+
+ void preprocess(const QByteArray &filename, Symbols &preprocessed);
+};
+
+QT_END_NAMESPACE
+
+#endif // PREPROCESSOR_H
diff --git a/src/tools/moc/symbols.h b/src/tools/moc/symbols.h
new file mode 100644
index 0000000000..3eed7061ac
--- /dev/null
+++ b/src/tools/moc/symbols.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SYMBOLS_H
+#define SYMBOLS_H
+
+#include "token.h"
+#include <QString>
+#include <QHash>
+#include <QVector>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+//#define USE_LEXEM_STORE
+
+struct SubArray
+{
+ inline SubArray():from(0),len(-1){}
+ inline SubArray(const QByteArray &a):array(a),from(0), len(a.size()){}
+ inline SubArray(const char *s):array(s),from(0) { len = array.size(); }
+ inline SubArray(const QByteArray &a, int from, int len):array(a), from(from), len(len){}
+ QByteArray array;
+ int from, len;
+ inline bool operator==(const SubArray &other) const {
+ if (len != other.len)
+ return false;
+ for (int i = 0; i < len; ++i)
+ if (array.at(from + i) != other.array.at(other.from + i))
+ return false;
+ return true;
+ }
+};
+
+inline uint qHash(const SubArray &key)
+{
+ const uchar *p = reinterpret_cast<const uchar *>(key.array.data() + key.from);
+ int n = key.len;
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + *p++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+
+struct Symbol
+{
+
+#ifdef USE_LEXEM_STORE
+ typedef QHash<SubArray, QHashDummyValue> LexemStore;
+ static LexemStore lexemStore;
+
+ inline Symbol() : lineNum(-1),token(NOTOKEN){}
+ inline Symbol(int lineNum, Token token):
+ lineNum(lineNum), token(token){}
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem):
+ lineNum(lineNum), token(token),lex(lexem){}
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem, int from, int len):
+ lineNum(lineNum), token(token){
+ LexemStore::const_iterator it = lexemStore.constFind(SubArray(lexem, from, len));
+
+ if (it != lexemStore.constEnd()) {
+ lex = it.key().array;
+ } else {
+ lex = lexem.mid(from, len);
+ lexemStore.insert(lex, QHashDummyValue());
+ }
+ }
+ int lineNum;
+ Token token;
+ inline QByteArray unquotedLexem() const { return lex.mid(1, lex.length()-2); }
+ inline QByteArray lexem() const { return lex; }
+ inline operator QByteArray() const { return lex; }
+ QByteArray lex;
+
+#else
+
+ inline Symbol() : lineNum(-1),token(NOTOKEN), from(0),len(-1) {}
+ inline Symbol(int lineNum, Token token):
+ lineNum(lineNum), token(token), from(0), len(-1) {}
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem):
+ lineNum(lineNum), token(token), lex(lexem), from(0) { len = lex.size(); }
+ inline Symbol(int lineNum, Token token, const QByteArray &lexem, int from, int len):
+ lineNum(lineNum), token(token),lex(lexem),from(from), len(len){}
+ int lineNum;
+ Token token;
+ inline QByteArray lexem() const { return lex.mid(from, len); }
+ inline QByteArray unquotedLexem() const { return lex.mid(from+1, len-2); }
+ inline operator QByteArray() const { return lex.mid(from, len); }
+ inline operator SubArray() const { return SubArray(lex, from, len); }
+ QByteArray lex;
+ int from, len;
+
+#endif
+};
+Q_DECLARE_TYPEINFO(Symbol, Q_MOVABLE_TYPE);
+
+
+typedef QVector<Symbol> Symbols;
+
+QT_END_NAMESPACE
+
+#endif // SYMBOLS_H
diff --git a/src/tools/moc/token.cpp b/src/tools/moc/token.cpp
new file mode 100644
index 0000000000..9d07c4867a
--- /dev/null
+++ b/src/tools/moc/token.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "token.h"
+
+QT_BEGIN_NAMESPACE
+
+#if defined(DEBUG_MOC)
+const char *tokenTypeName(Token t)
+{
+ switch (t) {
+ case NOTOKEN: return "NOTOKEN";
+ case IDENTIFIER: return "IDENTIFIER";
+ case INTEGER_LITERAL: return "INTEGER_LITERAL";
+ case CHARACTER_LITERAL: return "CHARACTER_LITERAL";
+ case STRING_LITERAL: return "STRING_LITERAL";
+ case BOOLEAN_LITERAL: return "BOOLEAN_LITERAL";
+ case HEADER_NAME: return "HEADER_NAME";
+ case LANGLE: return "LANGLE";
+ case RANGLE: return "RANGLE";
+ case LPAREN: return "LPAREN";
+ case RPAREN: return "RPAREN";
+ case ELIPSIS: return "ELIPSIS";
+ case LBRACK: return "LBRACK";
+ case RBRACK: return "RBRACK";
+ case LBRACE: return "LBRACE";
+ case RBRACE: return "RBRACE";
+ case EQ: return "EQ";
+ case SCOPE: return "SCOPE";
+ case SEMIC: return "SEMIC";
+ case COLON: return "COLON";
+ case DOTSTAR: return "DOTSTAR";
+ case QUESTION: return "QUESTION";
+ case DOT: return "DOT";
+ case DYNAMIC_CAST: return "DYNAMIC_CAST";
+ case STATIC_CAST: return "STATIC_CAST";
+ case REINTERPRET_CAST: return "REINTERPRET_CAST";
+ case CONST_CAST: return "CONST_CAST";
+ case TYPEID: return "TYPEID";
+ case THIS: return "THIS";
+ case TEMPLATE: return "TEMPLATE";
+ case THROW: return "THROW";
+ case TRY: return "TRY";
+ case CATCH: return "CATCH";
+ case TYPEDEF: return "TYPEDEF";
+ case FRIEND: return "FRIEND";
+ case CLASS: return "CLASS";
+ case NAMESPACE: return "NAMESPACE";
+ case ENUM: return "ENUM";
+ case STRUCT: return "STRUCT";
+ case UNION: return "UNION";
+ case VIRTUAL: return "VIRTUAL";
+ case PRIVATE: return "PRIVATE";
+ case PROTECTED: return "PROTECTED";
+ case PUBLIC: return "PUBLIC";
+ case EXPORT: return "EXPORT";
+ case AUTO: return "AUTO";
+ case REGISTER: return "REGISTER";
+ case EXTERN: return "EXTERN";
+ case MUTABLE: return "MUTABLE";
+ case ASM: return "ASM";
+ case USING: return "USING";
+ case INLINE: return "INLINE";
+ case EXPLICIT: return "EXPLICIT";
+ case STATIC: return "STATIC";
+ case CONST: return "CONST";
+ case VOLATILE: return "VOLATILE";
+ case OPERATOR: return "OPERATOR";
+ case SIZEOF: return "SIZEOF";
+ case NEW: return "NEW";
+ case DELETE: return "DELETE";
+ case PLUS: return "PLUS";
+ case MINUS: return "MINUS";
+ case STAR: return "STAR";
+ case SLASH: return "SLASH";
+ case PERCENT: return "PERCENT";
+ case HAT: return "HAT";
+ case AND: return "AND";
+ case OR: return "OR";
+ case TILDE: return "TILDE";
+ case NOT: return "NOT";
+ case PLUS_EQ: return "PLUS_EQ";
+ case MINUS_EQ: return "MINUS_EQ";
+ case STAR_EQ: return "STAR_EQ";
+ case SLASH_EQ: return "SLASH_EQ";
+ case PERCENT_EQ: return "PERCENT_EQ";
+ case HAT_EQ: return "HAT_EQ";
+ case AND_EQ: return "AND_EQ";
+ case OR_EQ: return "OR_EQ";
+ case LTLT: return "LTLT";
+ case GTGT: return "GTGT";
+ case GTGT_EQ: return "GTGT_EQ";
+ case LTLT_EQ: return "LTLT_EQ";
+ case EQEQ: return "EQEQ";
+ case NE: return "NE";
+ case LE: return "LE";
+ case GE: return "GE";
+ case ANDAND: return "ANDAND";
+ case OROR: return "OROR";
+ case INCR: return "INCR";
+ case DECR: return "DECR";
+ case COMMA: return "COMMA";
+ case ARROW_STAR: return "ARROW_STAR";
+ case ARROW: return "ARROW";
+ case CHAR: return "CHAR";
+ case WCHAR: return "WCHAR";
+ case BOOL: return "BOOL";
+ case SHORT: return "SHORT";
+ case INT: return "INT";
+ case LONG: return "LONG";
+ case SIGNED: return "SIGNED";
+ case UNSIGNED: return "UNSIGNED";
+ case FLOAT: return "FLOAT";
+ case DOUBLE: return "DOUBLE";
+ case VOID: return "VOID";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case GOTO: return "GOTO";
+ case SIGNALS: return "SIGNALS";
+ case SLOTS: return "SLOTS";
+ case RETURN: return "RETURN";
+ case Q_OBJECT_TOKEN: return "Q_OBJECT_TOKEN";
+ case Q_GADGET_TOKEN: return "Q_GADGET_TOKEN";
+ case Q_PROPERTY_TOKEN: return "Q_PROPERTY_TOKEN";
+ case Q_ENUMS_TOKEN: return "Q_ENUMS_TOKEN";
+ case Q_FLAGS_TOKEN: return "Q_FLAGS_TOKEN";
+ case Q_DECLARE_FLAGS_TOKEN: return "Q_DECLARE_FLAGS_TOKEN";
+ case Q_DECLARE_INTERFACE_TOKEN: return "Q_DECLARE_INTERFACE_TOKEN";
+ case Q_CLASSINFO_TOKEN: return "Q_CLASSINFO_TOKEN";
+ case Q_INTERFACES_TOKEN: return "Q_INTERFACES_TOKEN";
+ case Q_SIGNALS_TOKEN: return "Q_SIGNALS_TOKEN";
+ case Q_SLOTS_TOKEN: return "Q_SLOTS_TOKEN";
+ case Q_SIGNAL_TOKEN: return "Q_SIGNAL_TOKEN";
+ case Q_SLOT_TOKEN: return "Q_SLOT_TOKEN";
+ case Q_PRIVATE_SLOT_TOKEN: return "Q_PRIVATE_SLOT_TOKEN";
+ case Q_PRIVATE_PROPERTY_TOKEN: return "Q_PRIVATE_PROPERTY_TOKEN";
+ case Q_REVISION_TOKEN: return "Q_REVISION_TOKEN";
+ case SPECIAL_TREATMENT_MARK: return "SPECIAL_TREATMENT_MARK";
+ case MOC_INCLUDE_BEGIN: return "MOC_INCLUDE_BEGIN";
+ case MOC_INCLUDE_END: return "MOC_INCLUDE_END";
+ case CPP_COMMENT: return "CPP_COMMENT";
+ case C_COMMENT: return "C_COMMENT";
+ case FLOATING_LITERAL: return "FLOATING_LITERAL";
+ case HASH: return "HASH";
+ case QUOTE: return "QUOTE";
+ case SINGLEQUOTE: return "SINGLEQUOTE";
+ case DIGIT: return "DIGIT";
+ case CHARACTER: return "CHARACTER";
+ case NEWLINE: return "NEWLINE";
+ case WHITESPACE: return "WHITESPACE";
+ case BACKSLASH: return "BACKSLASH";
+ case INCOMPLETE: return "INCOMPLETE";
+ case PP_DEFINE: return "PP_DEFINE";
+ case PP_UNDEF: return "PP_UNDEF";
+ case PP_IF: return "PP_IF";
+ case PP_IFDEF: return "PP_IFDEF";
+ case PP_IFNDEF: return "PP_IFNDEF";
+ case PP_ELIF: return "PP_ELIF";
+ case PP_ELSE: return "PP_ELSE";
+ case PP_ENDIF: return "PP_ENDIF";
+ case PP_INCLUDE: return "PP_INCLUDE";
+ case PP_HASHHASH: return "PP_HASHHASH";
+ case PP_HASH: return "PP_HASH";
+ case PP_DEFINED: return "PP_DEFINED";
+ case PP_INCOMPLETE: return "PP_INCOMPLETE";
+ case PP_MOC_TRUE: return "PP_MOC_TRUE";
+ case PP_MOC_FALSE: return "PP_MOC_FALSE";
+ case Q_DECLARE_METATYPE_TOKEN: return "Q_DECLARE_METATYPE_TOKEN";
+ case Q_MOC_COMPAT_TOKEN: return "Q_MOC_COMPAT_TOKEN";
+ case Q_QT3_SUPPORT_TOKEN: return "Q_QT3_SUPPORT_TOKEN";
+ case Q_INVOKABLE_TOKEN: return "Q_INVOKABLE_TOKEN";
+ case Q_SCRIPTABLE_TOKEN: return "Q_SCRIPTABLE_TOKEN";
+ }
+ return "";
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/tools/moc/token.h b/src/tools/moc/token.h
new file mode 100644
index 0000000000..95f17c2598
--- /dev/null
+++ b/src/tools/moc/token.h
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOKEN_H
+#define TOKEN_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+enum Token {
+ NOTOKEN,
+ IDENTIFIER,
+ INTEGER_LITERAL,
+ CHARACTER_LITERAL,
+ STRING_LITERAL,
+ BOOLEAN_LITERAL,
+ HEADER_NAME,
+ LANGLE,
+ RANGLE,
+ LPAREN,
+ RPAREN,
+ ELIPSIS,
+ LBRACK,
+ RBRACK,
+ LBRACE,
+ RBRACE,
+ EQ,
+ SCOPE,
+ SEMIC,
+ COLON,
+ DOTSTAR,
+ QUESTION,
+ DOT,
+ DYNAMIC_CAST,
+ STATIC_CAST,
+ REINTERPRET_CAST,
+ CONST_CAST,
+ TYPEID,
+ THIS,
+ TEMPLATE,
+ THROW,
+ TRY,
+ CATCH,
+ TYPEDEF,
+ FRIEND,
+ CLASS,
+ NAMESPACE,
+ ENUM,
+ STRUCT,
+ UNION,
+ VIRTUAL,
+ PRIVATE,
+ PROTECTED,
+ PUBLIC,
+ EXPORT,
+ AUTO,
+ REGISTER,
+ EXTERN,
+ MUTABLE,
+ ASM,
+ USING,
+ INLINE,
+ EXPLICIT,
+ STATIC,
+ CONST,
+ VOLATILE,
+ OPERATOR,
+ SIZEOF,
+ NEW,
+ DELETE,
+ PLUS,
+ MINUS,
+ STAR,
+ SLASH,
+ PERCENT,
+ HAT,
+ AND,
+ OR,
+ TILDE,
+ NOT,
+ PLUS_EQ,
+ MINUS_EQ,
+ STAR_EQ,
+ SLASH_EQ,
+ PERCENT_EQ,
+ HAT_EQ,
+ AND_EQ,
+ OR_EQ,
+ LTLT,
+ GTGT,
+ GTGT_EQ,
+ LTLT_EQ,
+ EQEQ,
+ NE,
+ LE,
+ GE,
+ ANDAND,
+ OROR,
+ INCR,
+ DECR,
+ COMMA,
+ ARROW_STAR,
+ ARROW,
+ CHAR,
+ WCHAR,
+ BOOL,
+ SHORT,
+ INT,
+ LONG,
+ SIGNED,
+ UNSIGNED,
+ FLOAT,
+ DOUBLE,
+ VOID,
+ CASE,
+ DEFAULT,
+ IF,
+ ELSE,
+ SWITCH,
+ WHILE,
+ DO,
+ FOR,
+ BREAK,
+ CONTINUE,
+ GOTO,
+ SIGNALS,
+ SLOTS,
+ RETURN,
+ Q_META_TOKEN_BEGIN,
+ Q_OBJECT_TOKEN = Q_META_TOKEN_BEGIN,
+ Q_GADGET_TOKEN,
+ Q_PROPERTY_TOKEN,
+ Q_ENUMS_TOKEN,
+ Q_FLAGS_TOKEN,
+ Q_DECLARE_FLAGS_TOKEN,
+ Q_DECLARE_INTERFACE_TOKEN,
+ Q_DECLARE_METATYPE_TOKEN,
+ Q_CLASSINFO_TOKEN,
+ Q_INTERFACES_TOKEN,
+ Q_SIGNALS_TOKEN,
+ Q_SLOTS_TOKEN,
+ Q_SIGNAL_TOKEN,
+ Q_SLOT_TOKEN,
+ Q_PRIVATE_SLOT_TOKEN,
+ Q_MOC_COMPAT_TOKEN,
+ Q_QT3_SUPPORT_TOKEN,
+ Q_INVOKABLE_TOKEN,
+ Q_SCRIPTABLE_TOKEN,
+ Q_PRIVATE_PROPERTY_TOKEN,
+ Q_REVISION_TOKEN,
+ Q_META_TOKEN_END,
+ SPECIAL_TREATMENT_MARK = Q_META_TOKEN_END,
+ MOC_INCLUDE_BEGIN,
+ MOC_INCLUDE_END,
+ CPP_COMMENT,
+ C_COMMENT,
+ FLOATING_LITERAL,
+ HASH,
+ QUOTE,
+ SINGLEQUOTE,
+ LANGLE_SCOPE,
+ DIGIT,
+ CHARACTER,
+ NEWLINE,
+ WHITESPACE,
+ BACKSLASH,
+ INCOMPLETE,
+
+ PP_DEFINE,
+ PP_UNDEF,
+ PP_IF,
+ PP_IFDEF,
+ PP_IFNDEF,
+ PP_ELIF,
+ PP_ELSE,
+ PP_ENDIF,
+ PP_INCLUDE,
+ PP_HASHHASH,
+ PP_HASH,
+ PP_DEFINED,
+ PP_INCOMPLETE,
+
+ PP_MOC_TRUE,
+ PP_MOC_FALSE,
+
+ PP_NOTOKEN = NOTOKEN,
+ PP_IDENTIFIER = IDENTIFIER,
+ PP_INTEGER_LITERAL = INTEGER_LITERAL,
+ PP_CHARACTER_LITERAL = CHARACTER_LITERAL,
+ PP_STRING_LITERAL = STRING_LITERAL,
+ PP_LANGLE = LANGLE,
+ PP_RANGLE = RANGLE,
+ PP_LPAREN = LPAREN,
+ PP_RPAREN = RPAREN,
+ PP_COMMA = COMMA,
+ PP_PLUS = PLUS,
+ PP_MINUS = MINUS,
+ PP_STAR = STAR,
+ PP_SLASH = SLASH,
+ PP_PERCENT = PERCENT,
+ PP_HAT = HAT,
+ PP_AND = AND,
+ PP_OR = OR,
+ PP_TILDE = TILDE,
+ PP_NOT = NOT,
+ PP_LTLT = LTLT,
+ PP_GTGT = GTGT,
+ PP_EQEQ = EQEQ,
+ PP_NE = NE,
+ PP_LE = LE,
+ PP_GE = GE,
+ PP_ANDAND = ANDAND,
+ PP_OROR = OROR,
+ PP_QUESTION = QUESTION,
+ PP_COLON = COLON,
+ PP_FLOATING_LITERAL = FLOATING_LITERAL,
+ PP_QUOTE = QUOTE,
+ PP_SINGLEQUOTE = SINGLEQUOTE,
+ PP_DIGIT = DIGIT,
+ PP_CHARACTER = CHARACTER,
+ PP_WHITESPACE = WHITESPACE,
+ PP_NEWLINE = NEWLINE,
+ PP_CPP_COMMENT = CPP_COMMENT,
+ PP_C_COMMENT = C_COMMENT,
+ PP_BACKSLASH = BACKSLASH
+};
+
+// for debugging only
+#if defined(DEBUG_MOC)
+const char *tokenTypeName(Token t);
+#endif
+
+typedef Token PP_Token;
+
+QT_END_NAMESPACE
+
+#endif // TOKEN_H
diff --git a/src/tools/moc/util/generate.sh b/src/tools/moc/util/generate.sh
new file mode 100755
index 0000000000..ebfd4f789e
--- /dev/null
+++ b/src/tools/moc/util/generate.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+qmake
+make
+cat licenseheader.txt > ../keywords.cpp
+cat licenseheader.txt > ../ppkeywords.cpp
+./generate_keywords >> ../keywords.cpp
+./generate_keywords preprocessor >> ../ppkeywords.cpp
diff --git a/src/tools/moc/util/generate_keywords.cpp b/src/tools/moc/util/generate_keywords.cpp
new file mode 100644
index 0000000000..26f7a191da
--- /dev/null
+++ b/src/tools/moc/util/generate_keywords.cpp
@@ -0,0 +1,469 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <qbytearray.h>
+#include <qlist.h>
+
+struct Keyword
+{
+ const char *lexem;
+ const char *token;
+};
+
+static const Keyword pp_keywords[] = {
+ { "<", "PP_LANGLE" },
+ { ">", "PP_RANGLE" },
+ { "(", "PP_LPAREN"},
+ { ")", "PP_RPAREN"},
+ { ",", "PP_COMMA"},
+ { "\n", "PP_NEWLINE"},
+ { "#define", "PP_DEFINE"},
+ { "#if", "PP_IF"},
+ { "#undef", "PP_UNDEF"},
+ { "#ifdef", "PP_IFDEF"},
+ { "#ifndef", "PP_IFNDEF"},
+ { "#elif", "PP_ELIF"},
+ { "#else", "PP_ELSE"},
+ { "#endif", "PP_ENDIF"},
+ { "#include", "PP_INCLUDE"},
+ { "defined", "PP_DEFINED"},
+ { "+", "PP_PLUS" },
+ { "-", "PP_MINUS" },
+ { "*", "PP_STAR" },
+ { "/", "PP_SLASH" },
+ { "%", "PP_PERCENT" },
+ { "^", "PP_HAT" },
+ { "&", "PP_AND" },
+ { "bitand", "PP_AND" },
+ { "|", "PP_OR" },
+ { "bitor", "PP_OR" },
+ { "~", "PP_TILDE" },
+ { "compl", "PP_TILDE" },
+ { "!", "PP_NOT" },
+ { "not", "PP_NOT" },
+ { "<<", "PP_LTLT" },
+ { ">>", "PP_GTGT" },
+ { "==", "PP_EQEQ" },
+ { "!=", "PP_NE" },
+ { "not_eq", "PP_NE" },
+ { "<=", "PP_LE" },
+ { ">=", "PP_GE" },
+ { "&&", "PP_ANDAND" },
+ { "||", "PP_OROR" },
+ { "?", "PP_QUESTION" },
+ { ":", "PP_COLON" },
+ { "##", "PP_HASHHASH"},
+ { "%:%:", "PP_HASHHASH"},
+ { "#", "PP_HASH"},
+ { "\"", "PP_QUOTE"},
+ { "\'", "PP_SINGLEQUOTE"},
+ { " ", "PP_WHITESPACE" },
+ { "\t", "PP_WHITESPACE" },
+ { "//", "PP_CPP_COMMENT" },
+ { "/*", "PP_C_COMMENT" },
+ { "\\", "PP_BACKSLASH" },
+ { 0, "PP_NOTOKEN"}
+};
+
+static const Keyword keywords[] = {
+ { "<", "LANGLE" },
+ { ">", "RANGLE" },
+ { "(", "LPAREN" },
+ { ")", "RPAREN" },
+ { "...", "ELIPSIS" },
+ { ",", "COMMA" },
+ { "[", "LBRACK" },
+ { "]", "RBRACK" },
+ { "<:", "LBRACK" },
+ { ":>", "RBRACK" },
+ { "<::", "LANGLE_SCOPE" },
+ { "{", "LBRACE" },
+ { "<%", "LBRACE" },
+ { "}", "RBRACE" },
+ { "%>", "RBRACE" },
+ { "=", "EQ" },
+ { "::", "SCOPE" },
+ { ";", "SEMIC" },
+ { ":", "COLON" },
+ { ".*", "DOTSTAR" },
+ { "?", "QUESTION" },
+ { ".", "DOT" },
+ { "dynamic_cast", "DYNAMIC_CAST" },
+ { "static_cast", "STATIC_CAST" },
+ { "reinterpret_cast", "REINTERPRET_CAST" },
+ { "const_cast", "CONST_CAST" },
+ { "typeid", "TYPEID" },
+ { "this", "THIS" },
+ { "template", "TEMPLATE" },
+ { "throw", "THROW" },
+ { "try", "TRY" },
+ { "catch", "CATCH" },
+ { "typedef", "TYPEDEF" },
+ { "friend", "FRIEND" },
+ { "class", "CLASS" },
+ { "namespace", "NAMESPACE" },
+ { "enum", "ENUM" },
+ { "struct", "STRUCT" },
+ { "union", "UNION" },
+ { "virtual", "VIRTUAL" },
+ { "private", "PRIVATE" },
+ { "protected", "PROTECTED" },
+ { "public", "PUBLIC" },
+ { "export", "EXPORT" },
+ { "auto", "AUTO" },
+ { "register", "REGISTER" },
+ { "extern", "EXTERN" },
+ { "mutable", "MUTABLE" },
+ { "asm", "ASM" },
+ { "using", "USING" },
+ { "inline", "INLINE" },
+ { "explicit", "EXPLICIT" },
+ { "static", "STATIC" },
+ { "const", "CONST" },
+ { "volatile", "VOLATILE" },
+ { "operator", "OPERATOR" },
+ { "sizeof", "SIZEOF" },
+ { "new", "NEW" },
+ { "delete", "DELETE" },
+ { "+", "PLUS" },
+ { "-", "MINUS" },
+ { "*", "STAR" },
+ { "/", "SLASH" },
+ { "%", "PERCENT" },
+ { "^", "HAT" },
+ { "&", "AND" },
+ { "bitand", "AND" },
+ { "|", "OR" },
+ { "bitor", "OR" },
+ { "~", "TILDE" },
+ { "compl", "TILDE" },
+ { "!", "NOT" },
+ { "not", "NOT" },
+ { "+=", "PLUS_EQ" },
+ { "-=", "MINUS_EQ" },
+ { "*=", "STAR_EQ" },
+ { "/=", "SLASH_EQ" },
+ { "%=", "PERCENT_EQ" },
+ { "^=", "HAT_EQ" },
+ { "&=", "AND_EQ" },
+ { "|=", "OR_EQ" },
+ { "<<", "LTLT" },
+ { ">>", "GTGT" },
+ { ">>=", "GTGT_EQ" },
+ { "<<=", "LTLT_EQ" },
+ { "==", "EQEQ" },
+ { "!=", "NE" },
+ { "not_eq", "NE" },
+ { "<=", "LE" },
+ { ">=", "GE" },
+ { "&&", "ANDAND" },
+ { "||", "OROR" },
+ { "++", "INCR" },
+ { "--", "DECR" },
+ { ",", "COMMA" },
+ { "->*", "ARROW_STAR" },
+ { "->", "ARROW" },
+ { "char", "CHAR" },
+ { "wchar", "WCHAR" },
+ { "bool", "BOOL" },
+ { "short", "SHORT" },
+ { "int", "INT" },
+ { "long", "LONG" },
+ { "signed", "SIGNED" },
+ { "unsigned", "UNSIGNED" },
+ { "float", "FLOAT" },
+ { "double", "DOUBLE" },
+ { "void", "VOID" },
+ { "case", "CASE" },
+ { "default", "DEFAULT" },
+ { "if", "IF" },
+ { "else", "ELSE" },
+ { "switch", "SWITCH" },
+ { "while", "WHILE" },
+ { "do", "DO" },
+ { "for", "FOR" },
+ { "break", "BREAK" },
+ { "continue", "CONTINUE" },
+ { "goto", "GOTO" },
+ { "return", "RETURN" },
+ { "Q_OBJECT", "Q_OBJECT_TOKEN" },
+ { "Q_GADGET", "Q_GADGET_TOKEN" },
+ { "Q_PROPERTY", "Q_PROPERTY_TOKEN" },
+ { "Q_ENUMS", "Q_ENUMS_TOKEN" },
+ { "Q_FLAGS", "Q_FLAGS_TOKEN" },
+ { "Q_DECLARE_FLAGS", "Q_DECLARE_FLAGS_TOKEN" },
+ { "Q_DECLARE_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
+ { "Q_DECLARE_METATYPE", "Q_DECLARE_METATYPE_TOKEN" },
+ { "Q_DECLARE_EXTENSION_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
+ { "Q_SETS", "Q_FLAGS_TOKEN" },
+ { "Q_CLASSINFO", "Q_CLASSINFO_TOKEN" },
+ { "Q_INTERFACES", "Q_INTERFACES_TOKEN" },
+ { "signals", "SIGNALS" },
+ { "slots", "SLOTS" },
+ { "Q_SIGNALS", "Q_SIGNALS_TOKEN" },
+ { "Q_SLOTS", "Q_SLOTS_TOKEN" },
+ { "Q_PRIVATE_SLOT", "Q_PRIVATE_SLOT_TOKEN" },
+ { "QT_MOC_COMPAT", "Q_MOC_COMPAT_TOKEN" },
+ { "QT3_SUPPORT", "Q_QT3_SUPPORT_TOKEN" },
+ { "Q_INVOKABLE", "Q_INVOKABLE_TOKEN" },
+ { "Q_SIGNAL", "Q_SIGNAL_TOKEN" },
+ { "Q_SLOT", "Q_SLOT_TOKEN" },
+ { "Q_SCRIPTABLE", "Q_SCRIPTABLE_TOKEN" },
+ { "Q_PRIVATE_PROPERTY", "Q_PRIVATE_PROPERTY_TOKEN" },
+ { "Q_REVISION", "Q_REVISION_TOKEN" },
+ { "\n", "NEWLINE" },
+ { "\"", "QUOTE" },
+ { "\'", "SINGLEQUOTE" },
+ { " ", "WHITESPACE" },
+ { "\t", "WHITESPACE" },
+ { "#", "HASH" },
+ { "\\", "BACKSLASH" },
+ { "//", "CPP_COMMENT" },
+ { "/*", "C_COMMENT" },
+ { 0, "NOTOKEN"}
+};
+
+
+inline bool is_ident_start(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || s == '_'
+ );
+}
+
+inline bool is_ident_char(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || (s >= '0' && s <= '9')
+ || s == '_'
+ );
+}
+struct State
+{
+ State(const char* token):token(token), nextindex(0),
+ defchar(0), defnext(0), ident(0) {
+ memset( next, 0, sizeof(next));
+ }
+ QByteArray token;
+ int next[128];
+ int nextindex;
+
+ char defchar;
+ int defnext;
+
+ const char *ident;
+
+ bool operator==(const State& o) const
+ {
+ return (token == o.token
+ && nextindex == o.nextindex
+ && defchar == o.defchar
+ && defnext == o.defnext
+ && ident == o.ident);
+ }
+};
+
+void newState(QList<State> &states, const char *token, const char *lexem, bool pre)
+{
+ const char * ident = 0;
+ if (is_ident_start(*lexem))
+ ident = pre?"PP_CHARACTER" : "CHARACTER";
+ else if (*lexem == '#')
+ ident = pre?"PP_HASH" : "HASH";
+
+ int state = 0;
+ while (*lexem) {
+ int next = states[state].next[(int)*lexem];
+ if (!next) {
+ const char * t = 0;
+ if (ident)
+ t = ident;
+ else
+ t = pre?"PP_INCOMPLETE":"INCOMPLETE";
+ next = states.size();
+ states += State(t);
+ states[state].next[(int)*lexem] = next;
+ states[next].ident = ident;
+ }
+ state = next;
+ ++lexem;
+ if (ident && !is_ident_char(*lexem))
+ ident = 0;
+ }
+ states[state].token = token;
+}
+
+void newState(QList<State> &states, const char *token, char lexem)
+{
+ int next = states[0].next[(int)lexem];
+ if (!next) {
+ next = states.size();
+ states += State(token);
+ states[0].next[(int)lexem] = next;
+ } else {
+ states[next].token = token;
+ }
+}
+
+
+void makeTable(const Keyword keywords[])
+{
+ int i,c;
+ bool pre = (keywords == pp_keywords);
+ QList<State> states;
+ states += State(pre?"PP_NOTOKEN":"NOTOKEN");
+
+ // identifiers
+ for (c = 'a'; c <= 'z'; ++c)
+ newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
+ for (c = 'A'; c <= 'Z'; ++c)
+ newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
+ c = '_';
+ newState(states, pre?"PP_CHARACTER":"CHARACTER", c);
+
+ // add digits
+ for (c = '0'; c <= '9'; ++c)
+ newState(states, pre?"PP_DIGIT":"DIGIT", c);
+
+ // keywords
+ for (i = 0; keywords[i].lexem; ++i)
+ newState(states, keywords[i].token, keywords[i].lexem, pre);
+
+ // some floats
+ for (c = '0'; c <= '9'; ++c)
+ newState(states, pre?"PP_FLOATING_LITERAL":"FLOATING_LITERAL",
+ QByteArray(".") + char(c), pre);
+
+ // simplify table with default transitions
+ int transindex = -1;
+ for (i = 0; i < states.size(); ++i) {
+ int n = 0;
+ int defchar = -1;
+ for (c = 0; c < 128; ++c)
+ if (states[i].next[c]) {
+ ++n;
+ defchar = c;
+ }
+ if (!n)
+ continue;
+ if (n == 1) {
+ states[i].defnext = states[i].next[defchar];
+ states[i].defchar = defchar;
+ continue;
+ }
+ states[i].nextindex = ++transindex;
+ }
+
+#if 1
+ // compress table
+ int j, k;
+ for (i = 0; i < states.size(); ++i) {
+ for (j = i + 1; j < states.size(); ++j) {
+ if ( states[i] == states[j] ) {
+ for (k = 0; k < states.size(); ++k) {
+ if (states[k].defnext == j)
+ states[k].defnext = i;
+ if (states[k].defnext > j)
+ --states[k].defnext;
+ for (c = 0; c < 128; ++c) {
+ if (states[k].next[c] == j)
+ states[k].next[c] = i;
+ if (states[k].next[c] > j)
+ --states[k].next[c];
+ }
+ }
+ states.removeAt(j);
+ --j;
+ }
+ }
+ }
+#endif
+ printf("static const short %skeyword_trans[][128] = {\n",
+ pre?"pp_":"");
+ for (i = 0; i < states.size(); ++i) {
+ if (i && !states[i].nextindex)
+ continue;
+ printf("%s {", i?",\n":"");
+ for (c = 0; c < 128; ++c)
+ printf("%s%s%d",
+ c?",":"",
+ (!c || c%16)?"":"\n ",
+ states[i].next[c]
+ );
+ printf("}");
+ }
+ printf("\n};\n\n");
+
+ printf("static const struct\n{\n"
+ " %sToken token;\n"
+ " short next;\n"
+ " char defchar;\n"
+ " short defnext;\n"
+ " %sToken ident;\n"
+ "} %skeywords[] = {\n",
+ pre ? "PP_":"",
+ pre ? "PP_":"",
+ pre ? "pp_":"");
+ for (i = 0; i < states.size(); ++i) {
+ printf("%s {%s, %d, %d, %d, %s}",
+ i?",\n":"",
+ states[i].token.data(),
+ states[i].nextindex,
+ states[i].defchar,
+ states[i].defnext,
+ states[i].ident?states[i].ident:(pre?"PP_NOTOKEN":"NOTOKEN"));
+ }
+ printf("\n};\n");
+}
+
+int main(int argc, char **)
+{
+ printf("// auto generated\n"
+ "// DO NOT EDIT.\n\n");
+ if ( argc > 1 )
+ makeTable(pp_keywords);
+ else
+ makeTable(keywords);
+ return 0;
+}
diff --git a/src/tools/moc/util/generate_keywords.pro b/src/tools/moc/util/generate_keywords.pro
new file mode 100644
index 0000000000..eb04409922
--- /dev/null
+++ b/src/tools/moc/util/generate_keywords.pro
@@ -0,0 +1,12 @@
+######################################################################
+# Automatically generated by qmake (1.08a) Mon Feb 23 13:08:28 2004
+######################################################################
+
+TEMPLATE = app
+CONFIG -= moc
+mac:CONFIG -= app_bundle
+INCLUDEPATH += .
+
+# Input
+SOURCES += generate_keywords.cpp
+CONFIG += qt create_prl link_prl
diff --git a/src/tools/moc/util/licenseheader.txt b/src/tools/moc/util/licenseheader.txt
new file mode 100644
index 0000000000..ac5571e7ab
--- /dev/null
+++ b/src/tools/moc/util/licenseheader.txt
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
diff --git a/src/tools/moc/utils.h b/src/tools/moc/utils.h
new file mode 100644
index 0000000000..758f4a6454
--- /dev/null
+++ b/src/tools/moc/utils.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+inline bool is_whitespace(char s)
+{
+ return (s == ' ' || s == '\t' || s == '\n');
+}
+
+inline bool is_space(char s)
+{
+ return (s == ' ' || s == '\t');
+}
+
+inline bool is_ident_start(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || s == '_'
+ );
+}
+
+inline bool is_ident_char(char s)
+{
+ return ((s >= 'a' && s <= 'z')
+ || (s >= 'A' && s <= 'Z')
+ || (s >= '0' && s <= '9')
+ || s == '_'
+ );
+}
+
+inline bool is_digit_char(char s)
+{
+ return (s >= '0' && s <= '9');
+}
+
+inline bool is_octal_char(char s)
+{
+ return (s >= '0' && s <= '7');
+}
+
+inline bool is_hex_char(char s)
+{
+ return ((s >= 'a' && s <= 'f')
+ || (s >= 'A' && s <= 'F')
+ || (s >= '0' && s <= '9')
+ );
+}
+
+inline const char *skipQuote(const char *data)
+{
+ while (*data && (*data != '\"')) {
+ if (*data == '\\') {
+ ++data;
+ if (!*data) break;
+ }
+ ++data;
+ }
+
+ if (*data) //Skip last quote
+ ++data;
+ return data;
+}
+
+QT_END_NAMESPACE
+
+#endif // UTILS_H
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
new file mode 100644
index 0000000000..d91391af26
--- /dev/null
+++ b/src/tools/rcc/main.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <rcc.h>
+#include "../../corelib/kernel/qcorecmdlineargs_p.h"
+
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+void showHelp(const QString &argv0, const QString &error)
+{
+ fprintf(stderr, "Qt resource compiler\n");
+ if (!error.isEmpty())
+ fprintf(stderr, "%s: %s\n", qPrintable(argv0), qPrintable(error));
+ fprintf(stderr, "Usage: %s [options] <inputs>\n\n"
+ "Options:\n"
+ " -o file write output to file rather than stdout\n"
+ " -name name create an external initialization function with name\n"
+ " -threshold level threshold to consider compressing files\n"
+ " -compress level compress input files by level\n"
+ " -root path prefix resource access path with root path\n"
+ " -no-compress disable all compression\n"
+ " -binary output a binary file for use as a dynamic resource\n"
+ " -namespace turn off namespace macros\n"
+ " -project Output a resource file containing all\n"
+ " files from the current directory\n"
+ " -version display version\n"
+ " -help display this information\n",
+ qPrintable(argv0));
+}
+
+void dumpRecursive(const QDir &dir, QTextStream &out)
+{
+ QFileInfoList entries = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot
+ | QDir::NoSymLinks);
+ foreach (QFileInfo entry, entries) {
+ if (entry.isDir()) {
+ dumpRecursive(entry.filePath(), out);
+ } else {
+ out << QLatin1String("<file>")
+ << entry.filePath()
+ << QLatin1String("</file>\n");
+ }
+ }
+}
+
+int createProject(const QString &outFileName)
+{
+ QDir currentDir = QDir::current();
+ QString currentDirName = currentDir.dirName();
+ if (currentDirName.isEmpty())
+ currentDirName = QLatin1String("root");
+
+ QFile file;
+ bool isOk = false;
+ if (outFileName.isEmpty()) {
+ isOk = file.open(stdout, QFile::WriteOnly | QFile::Text);
+ } else {
+ file.setFileName(outFileName);
+ isOk = file.open(QFile::WriteOnly | QFile::Text);
+ }
+ if (!isOk) {
+ fprintf(stderr, "Unable to open %s: %s\n",
+ outFileName.isEmpty() ? qPrintable(outFileName) : "standard output",
+ qPrintable(file.errorString()));
+ return 1;
+ }
+
+ QTextStream out(&file);
+ out << QLatin1String("<!DOCTYPE RCC><RCC version=\"1.0\">\n"
+ "<qresource>\n");
+
+ // use "." as dir to get relative file pathes
+ dumpRecursive(QDir(QLatin1String(".")), out);
+
+ out << QLatin1String("</qresource>\n"
+ "</RCC>\n");
+
+ return 0;
+}
+
+int runRcc(int argc, char *argv[])
+{
+ QString outFilename;
+ bool helpRequested = false;
+ bool list = false;
+ bool projectRequested = false;
+ QStringList filenamesIn;
+
+ QStringList args = qCmdLineArgs(argc, argv);
+
+ RCCResourceLibrary library;
+
+ //parse options
+ QString errorMsg;
+ for (int i = 1; i < args.count() && errorMsg.isEmpty(); i++) {
+ if (args[i].isEmpty())
+ continue;
+ if (args[i][0] == QLatin1Char('-')) { // option
+ QString opt = args[i];
+ if (opt == QLatin1String("-o")) {
+ if (!(i < argc-1)) {
+ errorMsg = QLatin1String("Missing output name");
+ break;
+ }
+ outFilename = args[++i];
+ } else if (opt == QLatin1String("-name")) {
+ if (!(i < argc-1)) {
+ errorMsg = QLatin1String("Missing target name");
+ break;
+ }
+ library.setInitName(args[++i]);
+ } else if (opt == QLatin1String("-root")) {
+ if (!(i < argc-1)) {
+ errorMsg = QLatin1String("Missing root path");
+ break;
+ }
+ library.setResourceRoot(QDir::cleanPath(args[++i]));
+ if (library.resourceRoot().isEmpty()
+ || library.resourceRoot().at(0) != QLatin1Char('/'))
+ errorMsg = QLatin1String("Root must start with a /");
+ } else if (opt == QLatin1String("-compress")) {
+ if (!(i < argc-1)) {
+ errorMsg = QLatin1String("Missing compression level");
+ break;
+ }
+ library.setCompressLevel(args[++i].toInt());
+ } else if (opt == QLatin1String("-threshold")) {
+ if (!(i < argc-1)) {
+ errorMsg = QLatin1String("Missing compression threshold");
+ break;
+ }
+ library.setCompressThreshold(args[++i].toInt());
+ } else if (opt == QLatin1String("-binary")) {
+ library.setFormat(RCCResourceLibrary::Binary);
+ } else if (opt == QLatin1String("-namespace")) {
+ library.setUseNameSpace(!library.useNameSpace());
+ } else if (opt == QLatin1String("-verbose")) {
+ library.setVerbose(true);
+ } else if (opt == QLatin1String("-list")) {
+ list = true;
+ } else if (opt == QLatin1String("-version") || opt == QLatin1String("-v")) {
+ fprintf(stderr, "Qt Resource Compiler version %s\n", QT_VERSION_STR);
+ return 1;
+ } else if (opt == QLatin1String("-help") || opt == QLatin1String("-h")) {
+ helpRequested = true;
+ } else if (opt == QLatin1String("-no-compress")) {
+ library.setCompressLevel(-2);
+ } else if (opt == QLatin1String("-project")) {
+ projectRequested = true;
+ } else {
+ errorMsg = QString::fromLatin1("Unknown option: '%1'").arg(args[i]);
+ }
+ } else {
+ if (!QFile::exists(args[i])) {
+ qWarning("%s: File does not exist '%s'",
+ qPrintable(args[0]), qPrintable(args[i]));
+ return 1;
+ }
+ filenamesIn.append(args[i]);
+ }
+ }
+
+ if (projectRequested && !helpRequested) {
+ return createProject(outFilename);
+ }
+
+ if (!filenamesIn.size() || !errorMsg.isEmpty() || helpRequested) {
+ showHelp(args[0], errorMsg);
+ return 1;
+ }
+ QFile errorDevice;
+ errorDevice.open(stderr, QIODevice::WriteOnly|QIODevice::Text);
+
+ if (library.verbose())
+ errorDevice.write("Qt resource compiler\n");
+
+ library.setInputFiles(filenamesIn);
+
+ if (!library.readFiles(list, errorDevice))
+ return 1;
+
+ // open output
+ QFile out;
+ QIODevice::OpenMode mode = QIODevice::WriteOnly;
+ if (library.format() == RCCResourceLibrary::C_Code)
+ mode |= QIODevice::Text;
+
+ if (outFilename.isEmpty() || outFilename == QLatin1String("-")) {
+ // using this overload close() only flushes.
+ out.open(stdout, mode);
+ } else {
+ out.setFileName(outFilename);
+ if (!out.open(mode)) {
+ const QString msg = QString::fromUtf8("Unable to open %1 for writing: %2\n").arg(outFilename).arg(out.errorString());
+ errorDevice.write(msg.toUtf8());
+ return 1;
+ }
+ }
+
+ // do the task
+ if (list) {
+ const QStringList data = library.dataFiles();
+ for (int i = 0; i < data.size(); ++i) {
+ out.write(qPrintable(QDir::cleanPath(data.at(i))));
+ out.write("\n");
+ }
+ return 0;
+ }
+
+ return library.output(out, errorDevice) ? 0 : 1;
+}
+
+QT_END_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ return QT_PREPEND_NAMESPACE(runRcc)(argc, argv);
+}
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
new file mode 100644
index 0000000000..010a785df4
--- /dev/null
+++ b/src/tools/rcc/rcc.cpp
@@ -0,0 +1,987 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rcc.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDateTime>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QDirIterator>
+#include <QtCore/QFile>
+#include <QtCore/QIODevice>
+#include <QtCore/QLocale>
+#include <QtCore/QStack>
+
+#include <QtXml/QDomDocument>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ CONSTANT_USENAMESPACE = 1,
+ CONSTANT_COMPRESSLEVEL_DEFAULT = -1,
+ CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 70
+};
+
+
+#define writeString(s) write(s, sizeof(s))
+
+void RCCResourceLibrary::write(const char *str, int len)
+{
+ --len; // trailing \0 on string literals...
+ int n = m_out.size();
+ m_out.resize(n + len);
+ memcpy(m_out.data() + n, str, len);
+}
+
+void RCCResourceLibrary::writeByteArray(const QByteArray &other)
+{
+ m_out.append(other);
+}
+
+static inline QString msgOpenReadFailed(const QString &fname, const QString &why)
+{
+ return QString::fromUtf8("Unable to open %1 for reading: %2\n").arg(fname).arg(why);
+}
+
+
+///////////////////////////////////////////////////////////
+//
+// RCCFileInfo
+//
+///////////////////////////////////////////////////////////
+
+class RCCFileInfo
+{
+public:
+ enum Flags
+ {
+ NoFlags = 0x00,
+ Compressed = 0x01,
+ Directory = 0x02
+ };
+
+ RCCFileInfo(const QString &name = QString(), const QFileInfo &fileInfo = QFileInfo(),
+ QLocale::Language language = QLocale::C,
+ QLocale::Country country = QLocale::AnyCountry,
+ uint flags = NoFlags,
+ int compressLevel = CONSTANT_COMPRESSLEVEL_DEFAULT,
+ int compressThreshold = CONSTANT_COMPRESSTHRESHOLD_DEFAULT);
+ ~RCCFileInfo();
+
+ QString resourceName() const;
+
+public:
+ qint64 writeDataBlob(RCCResourceLibrary &lib, qint64 offset, QString *errorMessage);
+ qint64 writeDataName(RCCResourceLibrary &, qint64 offset);
+ void writeDataInfo(RCCResourceLibrary &lib);
+
+ int m_flags;
+ QString m_name;
+ QLocale::Language m_language;
+ QLocale::Country m_country;
+ QFileInfo m_fileInfo;
+ RCCFileInfo *m_parent;
+ QHash<QString, RCCFileInfo*> m_children;
+ int m_compressLevel;
+ int m_compressThreshold;
+
+ qint64 m_nameOffset;
+ qint64 m_dataOffset;
+ qint64 m_childOffset;
+};
+
+RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo,
+ QLocale::Language language, QLocale::Country country, uint flags,
+ int compressLevel, int compressThreshold)
+{
+ m_name = name;
+ m_fileInfo = fileInfo;
+ m_language = language;
+ m_country = country;
+ m_flags = flags;
+ m_parent = 0;
+ m_nameOffset = 0;
+ m_dataOffset = 0;
+ m_childOffset = 0;
+ m_compressLevel = compressLevel;
+ m_compressThreshold = compressThreshold;
+}
+
+RCCFileInfo::~RCCFileInfo()
+{
+ qDeleteAll(m_children);
+}
+
+QString RCCFileInfo::resourceName() const
+{
+ QString resource = m_name;
+ for (RCCFileInfo *p = m_parent; p; p = p->m_parent)
+ resource = resource.prepend(p->m_name + QLatin1Char('/'));
+ return QLatin1Char(':') + resource;
+}
+
+void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
+{
+ const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
+ //some info
+ if (text) {
+ if (m_language != QLocale::C) {
+ lib.writeString(" // ");
+ lib.writeByteArray(resourceName().toLocal8Bit());
+ lib.writeString(" [");
+ lib.writeByteArray(QByteArray::number(m_country));
+ lib.writeString("::");
+ lib.writeByteArray(QByteArray::number(m_language));
+ lib.writeString("[\n ");
+ } else {
+ lib.writeString(" // ");
+ lib.writeByteArray(resourceName().toLocal8Bit());
+ lib.writeString("\n ");
+ }
+ }
+
+ //pointer data
+ if (m_flags & RCCFileInfo::Directory) {
+ // name offset
+ lib.writeNumber4(m_nameOffset);
+
+ // flags
+ lib.writeNumber2(m_flags);
+
+ // child count
+ lib.writeNumber4(m_children.size());
+
+ // first child offset
+ lib.writeNumber4(m_childOffset);
+ } else {
+ // name offset
+ lib.writeNumber4(m_nameOffset);
+
+ // flags
+ lib.writeNumber2(m_flags);
+
+ // locale
+ lib.writeNumber2(m_country);
+ lib.writeNumber2(m_language);
+
+ //data offset
+ lib.writeNumber4(m_dataOffset);
+ }
+ if (text)
+ lib.writeChar('\n');
+}
+
+qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
+ QString *errorMessage)
+{
+ const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
+
+ //capture the offset
+ m_dataOffset = offset;
+
+ //find the data to be written
+ QFile file(m_fileInfo.absoluteFilePath());
+ if (!file.open(QFile::ReadOnly)) {
+ *errorMessage = msgOpenReadFailed(m_fileInfo.absoluteFilePath(), file.errorString());
+ return 0;
+ }
+ QByteArray data = file.readAll();
+
+#ifndef QT_NO_COMPRESS
+ // Check if compression is useful for this file
+ if (m_compressLevel != 0 && data.size() != 0) {
+ QByteArray compressed =
+ qCompress(reinterpret_cast<uchar *>(data.data()), data.size(), m_compressLevel);
+
+ int compressRatio = int(100.0 * (data.size() - compressed.size()) / data.size());
+ if (compressRatio >= m_compressThreshold) {
+ data = compressed;
+ m_flags |= Compressed;
+ }
+ }
+#endif // QT_NO_COMPRESS
+
+ // some info
+ if (text) {
+ lib.writeString(" // ");
+ lib.writeByteArray(m_fileInfo.absoluteFilePath().toLocal8Bit());
+ lib.writeString("\n ");
+ }
+
+ // write the length
+
+ lib.writeNumber4(data.size());
+ if (text)
+ lib.writeString("\n ");
+ offset += 4;
+
+ // write the payload
+ const char *p = data.constData();
+ if (text) {
+ for (int i = data.size(), j = 0; --i >= 0; --j) {
+ lib.writeHex(*p++);
+ if (j == 0) {
+ lib.writeString("\n ");
+ j = 16;
+ }
+ }
+ } else {
+ for (int i = data.size(); --i >= 0; )
+ lib.writeChar(*p++);
+ }
+ offset += data.size();
+
+ // done
+ if (text)
+ lib.writeString("\n ");
+ return offset;
+}
+
+qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
+{
+ const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
+
+ // capture the offset
+ m_nameOffset = offset;
+
+ // some info
+ if (text) {
+ lib.writeString(" // ");
+ lib.writeByteArray(m_name.toLocal8Bit());
+ lib.writeString("\n ");
+ }
+
+ // write the length
+ lib.writeNumber2(m_name.length());
+ if (text)
+ lib.writeString("\n ");
+ offset += 2;
+
+ // write the hash
+ lib.writeNumber4(qHash(m_name));
+ if (text)
+ lib.writeString("\n ");
+ offset += 4;
+
+ // write the m_name
+ const QChar *unicode = m_name.unicode();
+ for (int i = 0; i < m_name.length(); ++i) {
+ lib.writeNumber2(unicode[i].unicode());
+ if (text && i % 16 == 0)
+ lib.writeString("\n ");
+ }
+ offset += m_name.length()*2;
+
+ // done
+ if (text)
+ lib.writeString("\n ");
+ return offset;
+}
+
+
+///////////////////////////////////////////////////////////
+//
+// RCCResourceLibrary
+//
+///////////////////////////////////////////////////////////
+
+RCCResourceLibrary::Strings::Strings() :
+ TAG_RCC(QLatin1String("RCC")),
+ TAG_RESOURCE(QLatin1String("qresource")),
+ TAG_FILE(QLatin1String("file")),
+ ATTRIBUTE_LANG(QLatin1String("lang")),
+ ATTRIBUTE_PREFIX(QLatin1String("prefix")),
+ ATTRIBUTE_ALIAS(QLatin1String("alias")),
+ ATTRIBUTE_THRESHOLD(QLatin1String("threshold")),
+ ATTRIBUTE_COMPRESS(QLatin1String("compress"))
+{
+}
+
+RCCResourceLibrary::RCCResourceLibrary()
+ : m_root(0),
+ m_format(C_Code),
+ m_verbose(false),
+ m_compressLevel(CONSTANT_COMPRESSLEVEL_DEFAULT),
+ m_compressThreshold(CONSTANT_COMPRESSTHRESHOLD_DEFAULT),
+ m_treeOffset(0),
+ m_namesOffset(0),
+ m_dataOffset(0),
+ m_useNameSpace(CONSTANT_USENAMESPACE),
+ m_errorDevice(0)
+{
+ m_out.reserve(30 * 1000 * 1000);
+}
+
+RCCResourceLibrary::~RCCResourceLibrary()
+{
+ delete m_root;
+}
+
+bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
+ const QString &fname, QString currentPath, bool ignoreErrors)
+{
+ Q_ASSERT(m_errorDevice);
+ const QChar slash = QLatin1Char('/');
+ if (!currentPath.isEmpty() && !currentPath.endsWith(slash))
+ currentPath += slash;
+
+ QDomDocument document;
+ {
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+ if (!document.setContent(inputDevice, &errorMsg, &errorLine, &errorColumn)) {
+ if (ignoreErrors)
+ return true;
+ const QString msg = QString::fromUtf8("RCC Parse Error: '%1' Line: %2 Column: %3 [%4]\n").arg(fname).arg(errorLine).arg(errorColumn).arg(errorMsg);
+ m_errorDevice->write(msg.toUtf8());
+ return false;
+ }
+ }
+
+ QDomElement domRoot = document.firstChildElement(m_strings.TAG_RCC).toElement();
+ if (!domRoot.isNull() && domRoot.tagName() == m_strings.TAG_RCC) {
+ for (QDomNode node = domRoot.firstChild(); !node.isNull(); node = node.nextSibling()) {
+ if (!node.isElement())
+ continue;
+
+ QDomElement child = node.toElement();
+ if (!child.isNull() && child.tagName() == m_strings.TAG_RESOURCE) {
+ QLocale::Language language = QLocale::c().language();
+ QLocale::Country country = QLocale::c().country();
+
+ if (child.hasAttribute(m_strings.ATTRIBUTE_LANG)) {
+ QString attribute = child.attribute(m_strings.ATTRIBUTE_LANG);
+ QLocale lang = QLocale(attribute);
+ language = lang.language();
+ if (2 == attribute.length()) {
+ // Language only
+ country = QLocale::AnyCountry;
+ } else {
+ country = lang.country();
+ }
+ }
+
+ QString prefix;
+ if (child.hasAttribute(m_strings.ATTRIBUTE_PREFIX))
+ prefix = child.attribute(m_strings.ATTRIBUTE_PREFIX);
+ if (!prefix.startsWith(slash))
+ prefix.prepend(slash);
+ if (!prefix.endsWith(slash))
+ prefix += slash;
+
+ for (QDomNode res = child.firstChild(); !res.isNull(); res = res.nextSibling()) {
+ if (res.isElement() && res.toElement().tagName() == m_strings.TAG_FILE) {
+
+ QString fileName(res.firstChild().toText().data());
+ if (fileName.isEmpty()) {
+ const QString msg = QString::fromUtf8("RCC: Warning: Null node in XML of '%1'\n").arg(fname);
+ m_errorDevice->write(msg.toUtf8());
+ }
+ QString alias;
+ if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_ALIAS))
+ alias = res.toElement().attribute(m_strings.ATTRIBUTE_ALIAS);
+ else
+ alias = fileName;
+
+ int compressLevel = m_compressLevel;
+ if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_COMPRESS))
+ compressLevel = res.toElement().attribute(m_strings.ATTRIBUTE_COMPRESS).toInt();
+ int compressThreshold = m_compressThreshold;
+ if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_THRESHOLD))
+ compressThreshold = res.toElement().attribute(m_strings.ATTRIBUTE_THRESHOLD).toInt();
+
+ // Special case for -no-compress. Overrides all other settings.
+ if (m_compressLevel == -2)
+ compressLevel = 0;
+
+ alias = QDir::cleanPath(alias);
+ while (alias.startsWith(QLatin1String("../")))
+ alias.remove(0, 3);
+ alias = QDir::cleanPath(m_resourceRoot) + prefix + alias;
+
+ QString absFileName = fileName;
+ if (QDir::isRelativePath(absFileName))
+ absFileName.prepend(currentPath);
+ QFileInfo file(absFileName);
+ if (!file.exists()) {
+ m_failedResources.push_back(absFileName);
+ const QString msg = QString::fromUtf8("RCC: Error in '%1': Cannot find file '%2'\n").arg(fname).arg(fileName);
+ m_errorDevice->write(msg.toUtf8());
+ if (ignoreErrors)
+ continue;
+ else
+ return false;
+ } else if (file.isFile()) {
+ const bool arc =
+ addFile(alias,
+ RCCFileInfo(alias.section(slash, -1),
+ file,
+ language,
+ country,
+ RCCFileInfo::NoFlags,
+ compressLevel,
+ compressThreshold)
+ );
+ if (!arc)
+ m_failedResources.push_back(absFileName);
+ } else {
+ QDir dir;
+ if (file.isDir()) {
+ dir.setPath(file.filePath());
+ } else {
+ dir.setPath(file.path());
+ dir.setNameFilters(QStringList(file.fileName()));
+ if (alias.endsWith(file.fileName()))
+ alias = alias.left(alias.length()-file.fileName().length());
+ }
+ if (!alias.endsWith(slash))
+ alias += slash;
+ QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ it.next();
+ QFileInfo child(it.fileInfo());
+ if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) {
+ const bool arc =
+ addFile(alias + child.fileName(),
+ RCCFileInfo(child.fileName(),
+ child,
+ language,
+ country,
+ RCCFileInfo::NoFlags,
+ compressLevel,
+ compressThreshold)
+ );
+ if (!arc)
+ m_failedResources.push_back(child.fileName());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (m_root == 0) {
+ const QString msg = QString::fromUtf8("RCC: Warning: No resources in '%1'.\n").arg(fname);
+ m_errorDevice->write(msg.toUtf8());
+ if (!ignoreErrors && m_format == Binary) {
+ // create dummy entry, otherwise loading qith QResource will crash
+ m_root = new RCCFileInfo(QString(), QFileInfo(),
+ QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory);
+ }
+ }
+
+ return true;
+}
+
+bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file)
+{
+ Q_ASSERT(m_errorDevice);
+ if (file.m_fileInfo.size() > 0xffffffff) {
+ const QString msg = QString::fromUtf8("File too big: %1\n").arg(file.m_fileInfo.absoluteFilePath());
+ m_errorDevice->write(msg.toUtf8());
+ return false;
+ }
+ if (!m_root)
+ m_root = new RCCFileInfo(QString(), QFileInfo(), QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory);
+
+ RCCFileInfo *parent = m_root;
+ const QStringList nodes = alias.split(QLatin1Char('/'));
+ for (int i = 1; i < nodes.size()-1; ++i) {
+ const QString node = nodes.at(i);
+ if (node.isEmpty())
+ continue;
+ if (!parent->m_children.contains(node)) {
+ RCCFileInfo *s = new RCCFileInfo(node, QFileInfo(), QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory);
+ s->m_parent = parent;
+ parent->m_children.insert(node, s);
+ parent = s;
+ } else {
+ parent = parent->m_children[node];
+ }
+ }
+
+ const QString filename = nodes.at(nodes.size()-1);
+ RCCFileInfo *s = new RCCFileInfo(file);
+ s->m_parent = parent;
+ if (parent->m_children.contains(filename)) {
+ foreach (const QString &fileName, m_fileNames)
+ qWarning("%s: Warning: potential duplicate alias detected: '%s'",
+ qPrintable(fileName), qPrintable(filename));
+ }
+ parent->m_children.insertMulti(filename, s);
+ return true;
+}
+
+void RCCResourceLibrary::reset()
+{
+ if (m_root) {
+ delete m_root;
+ m_root = 0;
+ }
+ m_errorDevice = 0;
+ m_failedResources.clear();
+}
+
+
+bool RCCResourceLibrary::readFiles(bool ignoreErrors, QIODevice &errorDevice)
+{
+ reset();
+ m_errorDevice = &errorDevice;
+ //read in data
+ if (m_verbose) {
+ const QString msg = QString::fromUtf8("Processing %1 files [%2]\n")
+ .arg(m_fileNames.size()).arg(static_cast<int>(ignoreErrors));
+ m_errorDevice->write(msg.toUtf8());
+ }
+ for (int i = 0; i < m_fileNames.size(); ++i) {
+ QFile fileIn;
+ QString fname = m_fileNames.at(i);
+ QString pwd;
+ if (fname == QLatin1String("-")) {
+ fname = QLatin1String("(stdin)");
+ pwd = QDir::currentPath();
+ fileIn.setFileName(fname);
+ if (!fileIn.open(stdin, QIODevice::ReadOnly)) {
+ m_errorDevice->write(msgOpenReadFailed(fname, fileIn.errorString()).toUtf8());
+ return false;
+ }
+ } else {
+ pwd = QFileInfo(fname).path();
+ fileIn.setFileName(fname);
+ if (!fileIn.open(QIODevice::ReadOnly)) {
+ m_errorDevice->write(msgOpenReadFailed(fname, fileIn.errorString()).toUtf8());
+ return false;
+ }
+ }
+ if (m_verbose) {
+ const QString msg = QString::fromUtf8("Interpreting %1\n").arg(fname);
+ m_errorDevice->write(msg.toUtf8());
+ }
+
+ if (!interpretResourceFile(&fileIn, fname, pwd, ignoreErrors))
+ return false;
+ }
+ return true;
+}
+
+QStringList RCCResourceLibrary::dataFiles() const
+{
+ QStringList ret;
+ QStack<RCCFileInfo*> pending;
+
+ if (!m_root)
+ return ret;
+ pending.push(m_root);
+ while (!pending.isEmpty()) {
+ RCCFileInfo *file = pending.pop();
+ for (QHash<QString, RCCFileInfo*>::iterator it = file->m_children.begin();
+ it != file->m_children.end(); ++it) {
+ RCCFileInfo *child = it.value();
+ if (child->m_flags & RCCFileInfo::Directory)
+ pending.push(child);
+ ret.append(child->m_fileInfo.filePath());
+ }
+ }
+ return ret;
+}
+
+// Determine map of resource identifier (':/newPrefix/images/p1.png') to file via recursion
+static void resourceDataFileMapRecursion(const RCCFileInfo *m_root, const QString &path, RCCResourceLibrary::ResourceDataFileMap &m)
+{
+ typedef QHash<QString, RCCFileInfo*>::const_iterator ChildConstIterator;
+ const QChar slash = QLatin1Char('/');
+ const ChildConstIterator cend = m_root->m_children.constEnd();
+ for (ChildConstIterator it = m_root->m_children.constBegin(); it != cend; ++it) {
+ const RCCFileInfo *child = it.value();
+ QString childName = path;
+ childName += slash;
+ childName += child->m_name;
+ if (child->m_flags & RCCFileInfo::Directory) {
+ resourceDataFileMapRecursion(child, childName, m);
+ } else {
+ m.insert(childName, child->m_fileInfo.filePath());
+ }
+ }
+}
+
+RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap() const
+{
+ ResourceDataFileMap rc;
+ if (m_root)
+ resourceDataFileMapRecursion(m_root, QString(QLatin1Char(':')), rc);
+ return rc;
+}
+
+bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &errorDevice)
+{
+ m_errorDevice = &errorDevice;
+ //write out
+ if (m_verbose)
+ m_errorDevice->write("Outputting code\n");
+ if (!writeHeader()) {
+ m_errorDevice->write("Could not write header\n");
+ return false;
+ }
+ if (m_root) {
+ if (!writeDataBlobs()) {
+ m_errorDevice->write("Could not write data blobs.\n");
+ return false;
+ }
+ if (!writeDataNames()) {
+ m_errorDevice->write("Could not write file names\n");
+ return false;
+ }
+ if (!writeDataStructure()) {
+ m_errorDevice->write("Could not write data tree\n");
+ return false;
+ }
+ }
+ if (!writeInitializer()) {
+ m_errorDevice->write("Could not write footer\n");
+ return false;
+ }
+ outDevice.write(m_out, m_out.size());
+ return true;
+}
+
+void RCCResourceLibrary::writeHex(quint8 tmp)
+{
+ const char * const digits = "0123456789abcdef";
+ writeChar('0');
+ writeChar('x');
+ if (tmp < 16) {
+ writeChar(digits[tmp]);
+ } else {
+ writeChar(digits[tmp >> 4]);
+ writeChar(digits[tmp & 0xf]);
+ }
+ writeChar(',');
+}
+
+void RCCResourceLibrary::writeNumber2(quint16 number)
+{
+ if (m_format == RCCResourceLibrary::Binary) {
+ writeChar(number >> 8);
+ writeChar(number);
+ } else {
+ writeHex(number >> 8);
+ writeHex(number);
+ }
+}
+
+void RCCResourceLibrary::writeNumber4(quint32 number)
+{
+ if (m_format == RCCResourceLibrary::Binary) {
+ writeChar(number >> 24);
+ writeChar(number >> 16);
+ writeChar(number >> 8);
+ writeChar(number);
+ } else {
+ writeHex(number >> 24);
+ writeHex(number >> 16);
+ writeHex(number >> 8);
+ writeHex(number);
+ }
+}
+
+bool RCCResourceLibrary::writeHeader()
+{
+ if (m_format == C_Code) {
+ writeString("/****************************************************************************\n");
+ writeString("** Resource object code\n");
+ writeString("**\n");
+ writeString("** Created: ");
+ writeByteArray(QDateTime::currentDateTime().toString().toLatin1());
+ writeString("\n** by: The Resource Compiler for Qt version ");
+ writeByteArray(QT_VERSION_STR);
+ writeString("\n**\n");
+ writeString("** WARNING! All changes made in this file will be lost!\n");
+ writeString( "*****************************************************************************/\n\n");
+ writeString("#include <QtCore/qglobal.h>\n\n");
+ } else if (m_format == Binary) {
+ writeString("qres");
+ writeNumber4(0);
+ writeNumber4(0);
+ writeNumber4(0);
+ writeNumber4(0);
+ }
+ return true;
+}
+
+bool RCCResourceLibrary::writeDataBlobs()
+{
+ Q_ASSERT(m_errorDevice);
+ if (m_format == C_Code)
+ writeString("static const unsigned char qt_resource_data[] = {\n");
+ else if (m_format == Binary)
+ m_dataOffset = m_out.size();
+ QStack<RCCFileInfo*> pending;
+
+ if (!m_root)
+ return false;
+
+ pending.push(m_root);
+ qint64 offset = 0;
+ QString errorMessage;
+ while (!pending.isEmpty()) {
+ RCCFileInfo *file = pending.pop();
+ for (QHash<QString, RCCFileInfo*>::iterator it = file->m_children.begin();
+ it != file->m_children.end(); ++it) {
+ RCCFileInfo *child = it.value();
+ if (child->m_flags & RCCFileInfo::Directory)
+ pending.push(child);
+ else {
+ offset = child->writeDataBlob(*this, offset, &errorMessage);
+ if (offset == 0)
+ m_errorDevice->write(errorMessage.toUtf8());
+ }
+ }
+ }
+ if (m_format == C_Code)
+ writeString("\n};\n\n");
+ return true;
+}
+
+bool RCCResourceLibrary::writeDataNames()
+{
+ if (m_format == C_Code)
+ writeString("static const unsigned char qt_resource_name[] = {\n");
+ else if (m_format == Binary)
+ m_namesOffset = m_out.size();
+
+ QHash<QString, int> names;
+ QStack<RCCFileInfo*> pending;
+
+ if (!m_root)
+ return false;
+
+ pending.push(m_root);
+ qint64 offset = 0;
+ while (!pending.isEmpty()) {
+ RCCFileInfo *file = pending.pop();
+ for (QHash<QString, RCCFileInfo*>::iterator it = file->m_children.begin();
+ it != file->m_children.end(); ++it) {
+ RCCFileInfo *child = it.value();
+ if (child->m_flags & RCCFileInfo::Directory)
+ pending.push(child);
+ if (names.contains(child->m_name)) {
+ child->m_nameOffset = names.value(child->m_name);
+ } else {
+ names.insert(child->m_name, offset);
+ offset = child->writeDataName(*this, offset);
+ }
+ }
+ }
+ if (m_format == C_Code)
+ writeString("\n};\n\n");
+ return true;
+}
+
+static bool qt_rcc_compare_hash(const RCCFileInfo *left, const RCCFileInfo *right)
+{
+ return qHash(left->m_name) < qHash(right->m_name);
+}
+
+bool RCCResourceLibrary::writeDataStructure()
+{
+ if (m_format == C_Code)
+ writeString("static const unsigned char qt_resource_struct[] = {\n");
+ else if (m_format == Binary)
+ m_treeOffset = m_out.size();
+ QStack<RCCFileInfo*> pending;
+
+ if (!m_root)
+ return false;
+
+ //calculate the child offsets (flat)
+ pending.push(m_root);
+ int offset = 1;
+ while (!pending.isEmpty()) {
+ RCCFileInfo *file = pending.pop();
+ file->m_childOffset = offset;
+
+ //sort by hash value for binary lookup
+ QList<RCCFileInfo*> m_children = file->m_children.values();
+ qSort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
+
+ //write out the actual data now
+ for (int i = 0; i < m_children.size(); ++i) {
+ RCCFileInfo *child = m_children.at(i);
+ ++offset;
+ if (child->m_flags & RCCFileInfo::Directory)
+ pending.push(child);
+ }
+ }
+
+ //write out the structure (ie iterate again!)
+ pending.push(m_root);
+ m_root->writeDataInfo(*this);
+ while (!pending.isEmpty()) {
+ RCCFileInfo *file = pending.pop();
+
+ //sort by hash value for binary lookup
+ QList<RCCFileInfo*> m_children = file->m_children.values();
+ qSort(m_children.begin(), m_children.end(), qt_rcc_compare_hash);
+
+ //write out the actual data now
+ for (int i = 0; i < m_children.size(); ++i) {
+ RCCFileInfo *child = m_children.at(i);
+ child->writeDataInfo(*this);
+ if (child->m_flags & RCCFileInfo::Directory)
+ pending.push(child);
+ }
+ }
+ if (m_format == C_Code)
+ writeString("\n};\n\n");
+
+ return true;
+}
+
+void RCCResourceLibrary::writeMangleNamespaceFunction(const QByteArray &name)
+{
+ if (m_useNameSpace) {
+ writeString("QT_MANGLE_NAMESPACE(");
+ writeByteArray(name);
+ writeChar(')');
+ } else {
+ writeByteArray(name);
+ }
+}
+
+void RCCResourceLibrary::writeAddNamespaceFunction(const QByteArray &name)
+{
+ if (m_useNameSpace) {
+ writeString("QT_PREPEND_NAMESPACE(");
+ writeByteArray(name);
+ writeChar(')');
+ } else {
+ writeByteArray(name);
+ }
+}
+
+bool RCCResourceLibrary::writeInitializer()
+{
+ if (m_format == C_Code) {
+ //write("\nQT_BEGIN_NAMESPACE\n");
+ QString initName = m_initName;
+ if (!initName.isEmpty()) {
+ initName.prepend(QLatin1Char('_'));
+ initName.replace(QRegExp(QLatin1String("[^a-zA-Z0-9_]")), QLatin1String("_"));
+ }
+
+ //init
+ if (m_useNameSpace)
+ writeString("QT_BEGIN_NAMESPACE\n\n");
+ if (m_root) {
+ writeString("extern Q_CORE_EXPORT bool qRegisterResourceData\n "
+ "(int, const unsigned char *, "
+ "const unsigned char *, const unsigned char *);\n\n");
+ writeString("extern Q_CORE_EXPORT bool qUnregisterResourceData\n "
+ "(int, const unsigned char *, "
+ "const unsigned char *, const unsigned char *);\n\n");
+ }
+ if (m_useNameSpace)
+ writeString("QT_END_NAMESPACE\n\n\n");
+ QString initResources = QLatin1String("qInitResources");
+ initResources += initName;
+ writeString("int ");
+ writeMangleNamespaceFunction(initResources.toLatin1());
+ writeString("()\n{\n");
+
+ if (m_root) {
+ writeString(" ");
+ writeAddNamespaceFunction("qRegisterResourceData");
+ writeString("\n (0x01, qt_resource_struct, "
+ "qt_resource_name, qt_resource_data);\n");
+ }
+ writeString(" return 1;\n");
+ writeString("}\n\n");
+ writeString("Q_CONSTRUCTOR_FUNCTION(");
+ writeMangleNamespaceFunction(initResources.toLatin1());
+ writeString(")\n\n");
+
+ //cleanup
+ QString cleanResources = QLatin1String("qCleanupResources");
+ cleanResources += initName;
+ writeString("int ");
+ writeMangleNamespaceFunction(cleanResources.toLatin1());
+ writeString("()\n{\n");
+ if (m_root) {
+ writeString(" ");
+ writeAddNamespaceFunction("qUnregisterResourceData");
+ writeString("\n (0x01, qt_resource_struct, "
+ "qt_resource_name, qt_resource_data);\n");
+ }
+ writeString(" return 1;\n");
+ writeString("}\n\n");
+ writeString("Q_DESTRUCTOR_FUNCTION(");
+ writeMangleNamespaceFunction(cleanResources.toLatin1());
+ writeString(")\n\n");
+ } else if (m_format == Binary) {
+ int i = 4;
+ char *p = m_out.data();
+ p[i++] = 0; // 0x01
+ p[i++] = 0;
+ p[i++] = 0;
+ p[i++] = 1;
+
+ p[i++] = (m_treeOffset >> 24) & 0xff;
+ p[i++] = (m_treeOffset >> 16) & 0xff;
+ p[i++] = (m_treeOffset >> 8) & 0xff;
+ p[i++] = (m_treeOffset >> 0) & 0xff;
+
+ p[i++] = (m_dataOffset >> 24) & 0xff;
+ p[i++] = (m_dataOffset >> 16) & 0xff;
+ p[i++] = (m_dataOffset >> 8) & 0xff;
+ p[i++] = (m_dataOffset >> 0) & 0xff;
+
+ p[i++] = (m_namesOffset >> 24) & 0xff;
+ p[i++] = (m_namesOffset >> 16) & 0xff;
+ p[i++] = (m_namesOffset >> 8) & 0xff;
+ p[i++] = (m_namesOffset >> 0) & 0xff;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h
new file mode 100644
index 0000000000..666cc09625
--- /dev/null
+++ b/src/tools/rcc/rcc.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RCC_H
+#define RCC_H
+
+#include <QtCore/QStringList>
+#include <QtCore/QHash>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class RCCFileInfo;
+class QIODevice;
+class QTextStream;
+
+
+class RCCResourceLibrary
+{
+ RCCResourceLibrary(const RCCResourceLibrary &);
+ RCCResourceLibrary &operator=(const RCCResourceLibrary &);
+
+public:
+ RCCResourceLibrary();
+ ~RCCResourceLibrary();
+
+ bool output(QIODevice &out, QIODevice &errorDevice);
+
+ bool readFiles(bool ignoreErrors, QIODevice &errorDevice);
+
+ enum Format { Binary, C_Code };
+ void setFormat(Format f) { m_format = f; }
+ Format format() const { return m_format; }
+
+ void setInputFiles(const QStringList &files) { m_fileNames = files; }
+ QStringList inputFiles() const { return m_fileNames; }
+
+ QStringList dataFiles() const;
+
+ // Return a map of resource identifier (':/newPrefix/images/p1.png') to file.
+ typedef QHash<QString, QString> ResourceDataFileMap;
+ ResourceDataFileMap resourceDataFileMap() const;
+
+ void setVerbose(bool b) { m_verbose = b; }
+ bool verbose() const { return m_verbose; }
+
+ void setInitName(const QString &name) { m_initName = name; }
+ QString initName() const { return m_initName; }
+
+ void setCompressLevel(int c) { m_compressLevel = c; }
+ int compressLevel() const { return m_compressLevel; }
+
+ void setCompressThreshold(int t) { m_compressThreshold = t; }
+ int compressThreshold() const { return m_compressThreshold; }
+
+ void setResourceRoot(const QString &root) { m_resourceRoot = root; }
+ QString resourceRoot() const { return m_resourceRoot; }
+
+ void setUseNameSpace(bool v) { m_useNameSpace = v; }
+ bool useNameSpace() const { return m_useNameSpace; }
+
+ QStringList failedResources() const { return m_failedResources; }
+
+private:
+ struct Strings {
+ Strings();
+ const QString TAG_RCC;
+ const QString TAG_RESOURCE;
+ const QString TAG_FILE;
+ const QString ATTRIBUTE_LANG;
+ const QString ATTRIBUTE_PREFIX;
+ const QString ATTRIBUTE_ALIAS;
+ const QString ATTRIBUTE_THRESHOLD;
+ const QString ATTRIBUTE_COMPRESS;
+ };
+ friend class RCCFileInfo;
+ void reset();
+ bool addFile(const QString &alias, const RCCFileInfo &file);
+ bool interpretResourceFile(QIODevice *inputDevice, const QString &file,
+ QString currentPath = QString(), bool ignoreErrors = false);
+ bool writeHeader();
+ bool writeDataBlobs();
+ bool writeDataNames();
+ bool writeDataStructure();
+ bool writeInitializer();
+ void writeMangleNamespaceFunction(const QByteArray &name);
+ void writeAddNamespaceFunction(const QByteArray &name);
+ void writeHex(quint8 number);
+ void writeNumber2(quint16 number);
+ void writeNumber4(quint32 number);
+ void writeChar(char c) { m_out.append(c); }
+ void writeByteArray(const QByteArray &);
+ void write(const char *, int len);
+
+ const Strings m_strings;
+ RCCFileInfo *m_root;
+ QStringList m_fileNames;
+ QString m_resourceRoot;
+ QString m_initName;
+ Format m_format;
+ bool m_verbose;
+ int m_compressLevel;
+ int m_compressThreshold;
+ int m_treeOffset;
+ int m_namesOffset;
+ int m_dataOffset;
+ bool m_useNameSpace;
+ QStringList m_failedResources;
+ QIODevice *m_errorDevice;
+ QByteArray m_out;
+};
+
+QT_END_NAMESPACE
+
+#endif // RCC_H
diff --git a/src/tools/rcc/rcc.pri b/src/tools/rcc/rcc.pri
new file mode 100644
index 0000000000..534f2acbff
--- /dev/null
+++ b/src/tools/rcc/rcc.pri
@@ -0,0 +1,3 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/rcc.h
+SOURCES += $$PWD/rcc.cpp
diff --git a/src/tools/rcc/rcc.pro b/src/tools/rcc/rcc.pro
new file mode 100644
index 0000000000..edc85a1d15
--- /dev/null
+++ b/src/tools/rcc/rcc.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = rcc
+
+DESTDIR = ../../../bin
+DEFINES += QT_RCC
+INCLUDEPATH += .
+DEPENDPATH += .
+
+include(rcc.pri)
+HEADERS += ../../corelib/kernel/qcorecmdlineargs_p.h
+SOURCES += main.cpp
+include(../bootstrap/bootstrap.pri)
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+include(../../qt_targets.pri)
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
new file mode 100644
index 0000000000..4736d09cbe
--- /dev/null
+++ b/src/tools/tools.pro
@@ -0,0 +1,73 @@
+TEMPLATE = subdirs
+
+TOOLS_SUBDIRS = src_tools_bootstrap src_tools_moc src_tools_rcc
+!contains(QT_CONFIG, no-gui): TOOLS_SUBDIRS += src_tools_uic
+!cross_compile {
+ contains(QT_CONFIG, qt3support): SRC_SUBDIRS += src_tools_uic3
+ win32:!wince*: SRC_SUBDIRS += src_tools_idc
+}
+
+# Set subdir and respective target name
+src_tools_bootstrap.subdir = $$QT_SOURCE_TREE/src/tools/bootstrap
+src_tools_bootstrap.target = sub-tools-bootstrap
+src_tools_moc.subdir = $$QT_SOURCE_TREE/src/tools/moc
+src_tools_moc.target = sub-moc
+src_tools_rcc.subdir = $$QT_SOURCE_TREE/src/tools/rcc
+src_tools_rcc.target = sub-rcc
+src_tools_uic.subdir = $$QT_SOURCE_TREE/src/tools/uic
+src_tools_uic.target = sub-uic
+src_tools_uic3.subdir = $$QT_SOURCE_TREE/src/tools/uic3
+src_tools_uic3.target = sub-uic3
+src_tools_idc.subdir = $$QT_SOURCE_TREE/src/tools/idc
+src_tools_idc.target = sub-idc
+
+!wince*:!ordered {
+ # Set dependencies for each subdir
+ src_tools_moc.depends = src_tools_bootstrap
+ src_tools_rcc.depends = src_tools_bootstrap
+ src_tools_uic.depends = src_tools_bootstrap
+}
+
+# Special handling, depending on type of project, if it used debug/release or only has one configuration
+EXTRA_DEBUG_TARGETS =
+EXTRA_RELEASE_TARGETS =
+!symbian {
+ for(subname, TOOLS_SUBDIRS) {
+ subdir = $$subname
+ !isEmpty($${subname}.subdir):subdir = $$eval($${subname}.subdir)
+ subpro = $$subdir/$${basename(subdir)}.pro
+ !exists($$subpro):next()
+ subtarget = $$replace(subdir, [^A-Za-z0-9], _)
+ reg_src = $$replace(QT_SOURCE_TREE, \\\\, \\\\)
+ subdir = $$replace(subdir, $$reg_src, $$QT_BUILD_TREE)
+ subdir = $$replace(subdir, /, $$QMAKE_DIR_SEP)
+ subdir = $$replace(subdir, \\\\, $$QMAKE_DIR_SEP)
+ SUB_TEMPLATE = $$list($$fromfile($$subpro, TEMPLATE))
+ !isEqual(subname, src_tools_bootstrap):if(isEqual($$SUB_TEMPLATE, lib) | isEqual($$SUB_TEMPLATE, subdirs) | isEqual(subname, src_tools_idc) | isEqual(subname, src_tools_uic3)):!separate_debug_info {
+ #debug
+ debug-$${subtarget}.depends = $${subdir}$${QMAKE_DIR_SEP}$(MAKEFILE) $$EXTRA_DEBUG_TARGETS
+ debug-$${subtarget}.commands = (cd $$subdir && $(MAKE) -f $(MAKEFILE) debug)
+ EXTRA_DEBUG_TARGETS += debug-$${subtarget}
+ QMAKE_EXTRA_TARGETS += debug-$${subtarget}
+ #release
+ release-$${subtarget}.depends = $${subdir}$${QMAKE_DIR_SEP}$(MAKEFILE) $$EXTRA_RELEASE_TARGETS
+ release-$${subtarget}.commands = (cd $$subdir && $(MAKE) -f $(MAKEFILE) release)
+ EXTRA_RELEASE_TARGETS += release-$${subtarget}
+ QMAKE_EXTRA_TARGETS += release-$${subtarget}
+ } else { #do not have a real debug target/release
+ #debug
+ debug-$${subtarget}.depends = $${subdir}$${QMAKE_DIR_SEP}$(MAKEFILE) $$EXTRA_DEBUG_TARGETS
+ debug-$${subtarget}.commands = (cd $$subdir && $(MAKE) -f $(MAKEFILE) first)
+ EXTRA_DEBUG_TARGETS += debug-$${subtarget}
+ QMAKE_EXTRA_TARGETS += debug-$${subtarget}
+ #release
+ release-$${subtarget}.depends = $${subdir}$${QMAKE_DIR_SEP}$(MAKEFILE) $$EXTRA_RELEASE_TARGETS
+ release-$${subtarget}.commands = (cd $$subdir && $(MAKE) -f $(MAKEFILE) first)
+ EXTRA_RELEASE_TARGETS += release-$${subtarget}
+ QMAKE_EXTRA_TARGETS += release-$${subtarget}
+ }
+ }
+}
+
+SUBDIRS = $$TOOLS_SUBDIRS $$SUBDIRS
+isEqual(TARGET,tools): SUBDIRS += $$SRC_SUBDIRS
diff --git a/src/tools/uic/cpp/cpp.pri b/src/tools/uic/cpp/cpp.pri
new file mode 100644
index 0000000000..49c71a6dfa
--- /dev/null
+++ b/src/tools/uic/cpp/cpp.pri
@@ -0,0 +1,20 @@
+INCLUDEPATH += $$PWD $$QT_BUILD_TREE/src/tools/uic
+
+DEFINES += QT_UIC_CPP_GENERATOR
+
+# Input
+HEADERS += $$PWD/cppextractimages.h \
+ $$PWD/cppwritedeclaration.h \
+ $$PWD/cppwriteicondata.h \
+ $$PWD/cppwriteicondeclaration.h \
+ $$PWD/cppwriteiconinitialization.h \
+ $$PWD/cppwriteincludes.h \
+ $$PWD/cppwriteinitialization.h
+
+SOURCES += $$PWD/cppextractimages.cpp \
+ $$PWD/cppwritedeclaration.cpp \
+ $$PWD/cppwriteicondata.cpp \
+ $$PWD/cppwriteicondeclaration.cpp \
+ $$PWD/cppwriteiconinitialization.cpp \
+ $$PWD/cppwriteincludes.cpp \
+ $$PWD/cppwriteinitialization.cpp
diff --git a/src/tools/uic/cpp/cppextractimages.cpp b/src/tools/uic/cpp/cppextractimages.cpp
new file mode 100644
index 0000000000..0b1391d343
--- /dev/null
+++ b/src/tools/uic/cpp/cppextractimages.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppextractimages.h"
+#include "cppwriteicondata.h"
+#include "driver.h"
+#include "ui4.h"
+#include "utils.h"
+#include "uic.h"
+
+#include <QtCore/QDataStream>
+#include <QtCore/QTextStream>
+#include <QtCore/QTextCodec>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+namespace CPP {
+
+ExtractImages::ExtractImages(const Option &opt)
+ : m_output(0), m_option(opt)
+{
+}
+
+void ExtractImages::acceptUI(DomUI *node)
+{
+ if (!m_option.extractImages)
+ return;
+
+ if (node->elementImages() == 0)
+ return;
+
+ QString className = node->elementClass() + m_option.postfix;
+
+ QFile f;
+ if (m_option.qrcOutputFile.size()) {
+ f.setFileName(m_option.qrcOutputFile);
+ if (!f.open(QIODevice::WriteOnly | QFile::Text)) {
+ fprintf(stderr, "%s: Error: Could not create resource file\n", qPrintable(m_option.messagePrefix()));
+ return;
+ }
+
+ QFileInfo fi(m_option.qrcOutputFile);
+ QDir dir = fi.absoluteDir();
+ if (!dir.exists(QLatin1String("images")) && !dir.mkdir(QLatin1String("images"))) {
+ fprintf(stderr, "%s: Error: Could not create image dir\n", qPrintable(m_option.messagePrefix()));
+ return;
+ }
+ dir.cd(QLatin1String("images"));
+ m_imagesDir = dir;
+
+ m_output = new QTextStream(&f);
+ m_output->setCodec(QTextCodec::codecForName("UTF-8"));
+
+ QTextStream &out = *m_output;
+
+ out << "<RCC>\n";
+ out << " <qresource prefix=\"/" << className << "\" >\n";
+ TreeWalker::acceptUI(node);
+ out << " </qresource>\n";
+ out << "</RCC>\n";
+
+ f.close();
+ delete m_output;
+ m_output = 0;
+ }
+}
+
+void ExtractImages::acceptImages(DomImages *images)
+{
+ TreeWalker::acceptImages(images);
+}
+
+void ExtractImages::acceptImage(DomImage *image)
+{
+ QString format = image->elementData()->attributeFormat();
+ QString extension = format.left(format.indexOf(QLatin1Char('.'))).toLower();
+ QString fname = m_imagesDir.absoluteFilePath(image->attributeName() + QLatin1Char('.') + extension);
+
+ *m_output << " <file>images/" << image->attributeName() << QLatin1Char('.') + extension << "</file>\n";
+
+ QFile f;
+ f.setFileName(fname);
+ const bool isXPM_GZ = format == QLatin1String("XPM.GZ");
+ QIODevice::OpenMode openMode = QIODevice::WriteOnly;
+ if (isXPM_GZ)
+ openMode |= QIODevice::Text;
+ if (!f.open(openMode)) {
+ fprintf(stderr, "%s: Error: Could not create image file %s: %s",
+ qPrintable(m_option.messagePrefix()),
+ qPrintable(fname), qPrintable(f.errorString()));
+ return;
+ }
+
+ if (isXPM_GZ) {
+ QTextStream *imageOut = new QTextStream(&f);
+ imageOut->setCodec(QTextCodec::codecForName("UTF-8"));
+
+ CPP::WriteIconData::writeImage(*imageOut, QString(), m_option.limitXPM_LineLength, image);
+ delete imageOut;
+ } else {
+ CPP::WriteIconData::writeImage(f, image);
+ }
+
+ f.close();
+}
+
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppextractimages.h b/src/tools/uic/cpp/cppextractimages.h
new file mode 100644
index 0000000000..ce8cdc1d72
--- /dev/null
+++ b/src/tools/uic/cpp/cppextractimages.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPEXTRACTIMAGES_H
+#define CPPEXTRACTIMAGES_H
+
+#include "treewalker.h"
+#include <QtCore/QDir>
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class Driver;
+class Uic;
+
+struct Option;
+
+namespace CPP {
+
+class ExtractImages : public TreeWalker
+{
+public:
+ ExtractImages(const Option &opt);
+
+ void acceptUI(DomUI *node);
+ void acceptImages(DomImages *images);
+ void acceptImage(DomImage *image);
+
+private:
+ QTextStream *m_output;
+ const Option &m_option;
+ QDir m_imagesDir;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPEXTRACTIMAGES_H
diff --git a/src/tools/uic/cpp/cppwritedeclaration.cpp b/src/tools/uic/cpp/cppwritedeclaration.cpp
new file mode 100644
index 0000000000..d5ae0beef7
--- /dev/null
+++ b/src/tools/uic/cpp/cppwritedeclaration.cpp
@@ -0,0 +1,279 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppwritedeclaration.h"
+#include "cppwriteicondeclaration.h"
+#include "cppwriteinitialization.h"
+#include "cppwriteiconinitialization.h"
+#include "cppextractimages.h"
+#include "driver.h"
+#include "ui4.h"
+#include "uic.h"
+#include "databaseinfo.h"
+#include "customwidgetsinfo.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ void openNameSpaces(const QStringList &namespaceList, QTextStream &output) {
+ if (namespaceList.empty())
+ return;
+ const QStringList::const_iterator cend = namespaceList.constEnd();
+ for (QStringList::const_iterator it = namespaceList.constBegin(); it != cend; ++it) {
+ if (!it->isEmpty()) {
+ output << "namespace " << *it << " {\n";
+ }
+ }
+ }
+
+ void closeNameSpaces(const QStringList &namespaceList, QTextStream &output) {
+ if (namespaceList.empty())
+ return;
+
+ QListIterator<QString> it(namespaceList);
+ it.toBack();
+ while (it.hasPrevious()) {
+ const QString ns = it.previous();
+ if (!ns.isEmpty()) {
+ output << "} // namespace " << ns << "\n";
+ }
+ }
+ }
+
+ void writeScriptContextClass(const QString &indent, QTextStream &str) {
+ str << indent << "class ScriptContext\n"
+ << indent << "{\n"
+ << indent << "public:\n"
+ << indent << " void run(const QString &script, QWidget *widget, const QWidgetList &childWidgets)\n"
+ << indent << " {\n"
+ << indent << " QScriptValue widgetObject = scriptEngine.newQObject(widget);\n"
+ << indent << " QScriptValue childWidgetArray = scriptEngine.newArray (childWidgets.size());\n"
+ << indent << " for (int i = 0; i < childWidgets.size(); i++)\n"
+ << indent << " childWidgetArray.setProperty(i, scriptEngine.newQObject(childWidgets[i]));\n"
+ << indent << " QScriptContext *ctx = scriptEngine.pushContext();\n"
+ << indent << " ctx ->activationObject().setProperty(QLatin1String(\"widget\"), widgetObject);\n"
+ << indent << " ctx ->activationObject().setProperty(QLatin1String(\"childWidgets\"), childWidgetArray);\n\n"
+ << indent << " scriptEngine.evaluate(script);\n"
+ << indent << " if (scriptEngine.hasUncaughtException ()) {\n"
+ << indent << " qWarning() << \"An exception occurred at line \" << scriptEngine.uncaughtExceptionLineNumber()\n"
+ << indent << " << \" of the script for \" << widget->objectName() << \": \" << engineError() << '\\n'\n"
+ << indent << " << script;\n"
+ << indent << " }\n\n"
+ << indent << " scriptEngine.popContext();\n"
+ << indent << " }\n\n"
+ << indent << "private:\n"
+ << indent << " QString engineError()\n"
+ << indent << " {\n"
+ << indent << " QScriptValue error = scriptEngine.evaluate(\"Error\");\n"
+ << indent << " return error.toString();\n"
+ << indent << " }\n\n"
+ << indent << " QScriptEngine scriptEngine;\n"
+ << indent << "};\n\n";
+ }
+}
+
+namespace CPP {
+
+WriteDeclaration::WriteDeclaration(Uic *uic, bool activateScripts) :
+ m_uic(uic),
+ m_driver(uic->driver()),
+ m_output(uic->output()),
+ m_option(uic->option()),
+ m_activateScripts(activateScripts)
+{
+}
+
+void WriteDeclaration::acceptUI(DomUI *node)
+{
+ QString qualifiedClassName = node->elementClass() + m_option.postfix;
+ QString className = qualifiedClassName;
+
+ QString varName = m_driver->findOrInsertWidget(node->elementWidget());
+ QString widgetClassName = node->elementWidget()->attributeClass();
+
+ QString exportMacro = node->elementExportMacro();
+ if (!exportMacro.isEmpty())
+ exportMacro.append(QLatin1Char(' '));
+
+ QStringList namespaceList = qualifiedClassName.split(QLatin1String("::"));
+ if (namespaceList.count()) {
+ className = namespaceList.last();
+ namespaceList.removeLast();
+ }
+
+ // This is a bit of the hack but covers the cases Qt in/without namespaces
+ // and User defined classes in/without namespaces. The "strange" case
+ // is a User using Qt-in-namespace having his own classes not in a namespace.
+ // In this case the generated Ui helper classes will also end up in
+ // the Qt namespace (which is harmless, but not "pretty")
+ const bool needsMacro = namespaceList.count() == 0
+ || namespaceList[0] == QLatin1String("qdesigner_internal");
+
+ if (needsMacro)
+ m_output << "QT_BEGIN_NAMESPACE\n\n";
+
+ openNameSpaces(namespaceList, m_output);
+
+ if (namespaceList.count())
+ m_output << "\n";
+
+ m_output << "class " << exportMacro << m_option.prefix << className << "\n"
+ << "{\n"
+ << "public:\n";
+
+ const QStringList connections = m_uic->databaseInfo()->connections();
+ for (int i=0; i<connections.size(); ++i) {
+ const QString connection = connections.at(i);
+
+ if (connection == QLatin1String("(default)"))
+ continue;
+
+ m_output << m_option.indent << "QSqlDatabase " << connection << "Connection;\n";
+ }
+
+ TreeWalker::acceptWidget(node->elementWidget());
+ if (const DomButtonGroups *domButtonGroups = node->elementButtonGroups())
+ acceptButtonGroups(domButtonGroups);
+
+ m_output << "\n";
+
+ WriteInitialization(m_uic, m_activateScripts).acceptUI(node);
+
+ if (node->elementImages()) {
+ if (m_option.extractImages) {
+ ExtractImages(m_uic->option()).acceptUI(node);
+ } else {
+ m_output << "\n"
+ << "protected:\n"
+ << m_option.indent << "enum IconID\n"
+ << m_option.indent << "{\n";
+ WriteIconDeclaration(m_uic).acceptUI(node);
+
+ m_output << m_option.indent << m_option.indent << "unknown_ID\n"
+ << m_option.indent << "};\n";
+
+ WriteIconInitialization(m_uic).acceptUI(node);
+ }
+ }
+
+ if (m_activateScripts) {
+ m_output << "\nprivate:\n\n";
+ writeScriptContextClass(m_option.indent, m_output);
+ }
+
+ m_output << "};\n\n";
+
+ closeNameSpaces(namespaceList, m_output);
+
+ if (namespaceList.count())
+ m_output << "\n";
+
+ if (m_option.generateNamespace && !m_option.prefix.isEmpty()) {
+ namespaceList.append(QLatin1String("Ui"));
+
+ openNameSpaces(namespaceList, m_output);
+
+ m_output << m_option.indent << "class " << exportMacro << className << ": public " << m_option.prefix << className << " {};\n";
+
+ closeNameSpaces(namespaceList, m_output);
+
+ if (namespaceList.count())
+ m_output << "\n";
+ }
+
+ if (needsMacro)
+ m_output << "QT_END_NAMESPACE\n\n";
+}
+
+void WriteDeclaration::acceptWidget(DomWidget *node)
+{
+ QString className = QLatin1String("QWidget");
+ if (node->hasAttributeClass())
+ className = node->attributeClass();
+
+ m_output << m_option.indent << m_uic->customWidgetsInfo()->realClassName(className) << " *" << m_driver->findOrInsertWidget(node) << ";\n";
+
+ TreeWalker::acceptWidget(node);
+}
+
+void WriteDeclaration::acceptSpacer(DomSpacer *node)
+{
+ m_output << m_option.indent << "QSpacerItem *" << m_driver->findOrInsertSpacer(node) << ";\n";
+ TreeWalker::acceptSpacer(node);
+}
+
+void WriteDeclaration::acceptLayout(DomLayout *node)
+{
+ QString className = QLatin1String("QLayout");
+ if (node->hasAttributeClass())
+ className = node->attributeClass();
+
+ m_output << m_option.indent << className << " *" << m_driver->findOrInsertLayout(node) << ";\n";
+
+ TreeWalker::acceptLayout(node);
+}
+
+void WriteDeclaration::acceptActionGroup(DomActionGroup *node)
+{
+ m_output << m_option.indent << "QActionGroup *" << m_driver->findOrInsertActionGroup(node) << ";\n";
+
+ TreeWalker::acceptActionGroup(node);
+}
+
+void WriteDeclaration::acceptAction(DomAction *node)
+{
+ m_output << m_option.indent << "QAction *" << m_driver->findOrInsertAction(node) << ";\n";
+
+ TreeWalker::acceptAction(node);
+}
+
+void WriteDeclaration::acceptButtonGroup(const DomButtonGroup *buttonGroup)
+{
+ m_output << m_option.indent << "QButtonGroup *" << m_driver->findOrInsertButtonGroup(buttonGroup) << ";\n";
+ TreeWalker::acceptButtonGroup(buttonGroup);
+}
+
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppwritedeclaration.h b/src/tools/uic/cpp/cppwritedeclaration.h
new file mode 100644
index 0000000000..7900e01203
--- /dev/null
+++ b/src/tools/uic/cpp/cppwritedeclaration.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPWRITEDECLARATION_H
+#define CPPWRITEDECLARATION_H
+
+#include "treewalker.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class Driver;
+class Uic;
+
+struct Option;
+
+namespace CPP {
+
+struct WriteDeclaration : public TreeWalker
+{
+ WriteDeclaration(Uic *uic, bool activateScripts);
+
+ void acceptUI(DomUI *node);
+ void acceptWidget(DomWidget *node);
+ void acceptSpacer(DomSpacer *node);
+ void acceptLayout(DomLayout *node);
+ void acceptActionGroup(DomActionGroup *node);
+ void acceptAction(DomAction *node);
+ void acceptButtonGroup(const DomButtonGroup *buttonGroup);
+
+private:
+ Uic *m_uic;
+ Driver *m_driver;
+ QTextStream &m_output;
+ const Option &m_option;
+ const bool m_activateScripts;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPWRITEDECLARATION_H
diff --git a/src/tools/uic/cpp/cppwriteicondata.cpp b/src/tools/uic/cpp/cppwriteicondata.cpp
new file mode 100644
index 0000000000..e09b081b8f
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteicondata.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppwriteicondata.h"
+#include "driver.h"
+#include "ui4.h"
+#include "uic.h"
+
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace CPP {
+
+static QByteArray transformImageData(QString data)
+{
+ int baSize = data.length() / 2;
+ uchar *ba = new uchar[baSize];
+ for (int i = 0; i < baSize; ++i) {
+ char h = data[2 * (i)].toLatin1();
+ char l = data[2 * (i) + 1].toLatin1();
+ uchar r = 0;
+ if (h <= '9')
+ r += h - '0';
+ else
+ r += h - 'a' + 10;
+ r = r << 4;
+ if (l <= '9')
+ r += l - '0';
+ else
+ r += l - 'a' + 10;
+ ba[i] = r;
+ }
+ QByteArray ret(reinterpret_cast<const char *>(ba), baSize);
+ delete [] ba;
+ return ret;
+}
+
+static QByteArray unzipXPM(QString data, ulong& length)
+{
+#ifndef QT_NO_COMPRESS
+ const int lengthOffset = 4;
+ QByteArray ba(lengthOffset, ' ');
+
+ // qUncompress() expects the first 4 bytes to be the expected length of the
+ // uncompressed data
+ ba[0] = (length & 0xff000000) >> 24;
+ ba[1] = (length & 0x00ff0000) >> 16;
+ ba[2] = (length & 0x0000ff00) >> 8;
+ ba[3] = (length & 0x000000ff);
+ ba.append(transformImageData(data));
+ QByteArray baunzip = qUncompress(ba);
+ return baunzip;
+#else
+ Q_UNUSED(data);
+ Q_UNUSED(length);
+ return QByteArray();
+#endif
+}
+
+
+WriteIconData::WriteIconData(Uic *uic)
+ : driver(uic->driver()), output(uic->output()), option(uic->option())
+{
+}
+
+void WriteIconData::acceptUI(DomUI *node)
+{
+ TreeWalker::acceptUI(node);
+}
+
+void WriteIconData::acceptImages(DomImages *images)
+{
+ TreeWalker::acceptImages(images);
+}
+
+void WriteIconData::acceptImage(DomImage *image)
+{
+ // Limit line length when writing code.
+ writeImage(output, option.indent, true, image);
+}
+
+void WriteIconData::writeImage(QTextStream &output, const QString &indent,
+ bool limitXPM_LineLength, const DomImage *image)
+{
+ QString img = image->attributeName() + QLatin1String("_data");
+ QString data = image->elementData()->text();
+ QString fmt = image->elementData()->attributeFormat();
+ int size = image->elementData()->attributeLength();
+
+ if (fmt == QLatin1String("XPM.GZ")) {
+ ulong length = size;
+ QByteArray baunzip = unzipXPM(data, length);
+ length = baunzip.size();
+ // shouldn't we test the initial 'length' against the
+ // resulting 'length' to catch corrupt UIC files?
+ int a = 0;
+ int column = 0;
+ bool inQuote = false;
+ output << indent << "/* XPM */\n"
+ << indent << "static const char* const " << img << "[] = { \n";
+ while (baunzip[a] != '\"')
+ a++;
+ for (; a < (int) length; a++) {
+ output << baunzip[a];
+ if (baunzip[a] == '\n') {
+ column = 0;
+ } else if (baunzip[a] == '"') {
+ inQuote = !inQuote;
+ }
+
+ column++;
+ if (limitXPM_LineLength && column >= 512 && inQuote) {
+ output << "\"\n\""; // be nice with MSVC & Co.
+ column = 1;
+ }
+ }
+
+ if (! baunzip.trimmed ().endsWith ("};"))
+ output << "};";
+
+ output << "\n\n";
+ } else {
+ output << indent << "static const unsigned char " << img << "[] = { \n";
+ output << indent;
+ int a ;
+ for (a = 0; a < (int) (data.length()/2)-1; a++) {
+ output << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << ',';
+ if (a % 12 == 11)
+ output << '\n' << indent;
+ else
+ output << ' ';
+ }
+ output << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << '\n';
+ output << "};\n\n";
+ }
+}
+
+void WriteIconData::writeImage(QIODevice &output, DomImage *image)
+{
+ QByteArray array = transformImageData(image->elementData()->text());
+ output.write(array, array.size());
+}
+
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppwriteicondata.h b/src/tools/uic/cpp/cppwriteicondata.h
new file mode 100644
index 0000000000..c971e17914
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteicondata.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPWRITEICONDATA_H
+#define CPPWRITEICONDATA_H
+
+#include "treewalker.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class QIODevice;
+class Driver;
+class Uic;
+
+struct Option;
+
+namespace CPP {
+
+class WriteIconData : public TreeWalker
+{
+public:
+ WriteIconData(Uic *uic);
+
+ void acceptUI(DomUI *node);
+ void acceptImages(DomImages *images);
+ void acceptImage(DomImage *image);
+
+ static void writeImage(QTextStream &output, const QString &indent,
+ bool limitXPM_LineLength, const DomImage *image);
+ static void writeImage(QIODevice &output, DomImage *image);
+
+private:
+ Driver *driver;
+ QTextStream &output;
+ const Option &option;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPWRITEICONDATA_H
diff --git a/src/tools/uic/cpp/cppwriteicondeclaration.cpp b/src/tools/uic/cpp/cppwriteicondeclaration.cpp
new file mode 100644
index 0000000000..21f88c3bd6
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteicondeclaration.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppwriteicondeclaration.h"
+#include "driver.h"
+#include "ui4.h"
+#include "uic.h"
+
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+namespace CPP {
+
+WriteIconDeclaration::WriteIconDeclaration(Uic *uic)
+ : driver(uic->driver()), output(uic->output()), option(uic->option())
+{
+}
+
+void WriteIconDeclaration::acceptUI(DomUI *node)
+{
+ TreeWalker::acceptUI(node);
+}
+
+void WriteIconDeclaration::acceptImages(DomImages *images)
+{
+ TreeWalker::acceptImages(images);
+}
+
+void WriteIconDeclaration::acceptImage(DomImage *image)
+{
+ QString name = image->attributeName();
+ if (name.isEmpty())
+ return;
+
+ driver->insertPixmap(name);
+ output << option.indent << option.indent << name << "_ID,\n";
+}
+
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppwriteicondeclaration.h b/src/tools/uic/cpp/cppwriteicondeclaration.h
new file mode 100644
index 0000000000..5ad2a6f6ba
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteicondeclaration.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPWRITEICONDECLARATION_H
+#define CPPWRITEICONDECLARATION_H
+
+#include "treewalker.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class Driver;
+class Uic;
+
+struct Option;
+
+namespace CPP {
+
+class WriteIconDeclaration : public TreeWalker
+{
+public:
+ WriteIconDeclaration(Uic *uic);
+
+ void acceptUI(DomUI *node);
+ void acceptImages(DomImages *images);
+ void acceptImage(DomImage *image);
+
+private:
+ Driver *driver;
+ QTextStream &output;
+ const Option &option;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPWRITEICONDECLARATION_H
diff --git a/src/tools/uic/cpp/cppwriteiconinitialization.cpp b/src/tools/uic/cpp/cppwriteiconinitialization.cpp
new file mode 100644
index 0000000000..d9d24c1bc7
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteiconinitialization.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppwriteiconinitialization.h"
+#include "cppwriteicondata.h"
+#include "driver.h"
+#include "ui4.h"
+#include "utils.h"
+#include "uic.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace CPP {
+
+WriteIconInitialization::WriteIconInitialization(Uic *uic)
+ : driver(uic->driver()), output(uic->output()), option(uic->option())
+{
+ this->uic = uic;
+}
+
+void WriteIconInitialization::acceptUI(DomUI *node)
+{
+ if (node->elementImages() == 0)
+ return;
+
+ QString className = node->elementClass() + option.postfix;
+
+ output << option.indent << "static QPixmap " << iconFromDataFunction() << "(IconID id)\n"
+ << option.indent << "{\n";
+
+ WriteIconData(uic).acceptUI(node);
+
+ output << option.indent << "switch (id) {\n";
+
+ TreeWalker::acceptUI(node);
+
+ output << option.indent << option.indent << "default: return QPixmap();\n";
+
+ output << option.indent << "} // switch\n"
+ << option.indent << "} // icon\n\n";
+}
+
+QString WriteIconInitialization::iconFromDataFunction()
+{
+ return QLatin1String("qt_get_icon");
+}
+
+void WriteIconInitialization::acceptImages(DomImages *images)
+{
+ TreeWalker::acceptImages(images);
+}
+
+void WriteIconInitialization::acceptImage(DomImage *image)
+{
+ QString img = image->attributeName() + QLatin1String("_data");
+ QString data = image->elementData()->text();
+ QString fmt = image->elementData()->attributeFormat();
+
+ QString imageId = image->attributeName() + QLatin1String("_ID");
+ QString imageData = image->attributeName() + QLatin1String("_data");
+ QString ind = option.indent + option.indent;
+
+ output << ind << "case " << imageId << ": ";
+
+ if (fmt == QLatin1String("XPM.GZ")) {
+ output << "return " << "QPixmap((const char**)" << imageData << ");\n";
+ } else {
+ output << " { QImage img; img.loadFromData(" << imageData << ", sizeof(" << imageData << "), " << fixString(fmt, ind) << "); return QPixmap::fromImage(img); }\n";
+ }
+}
+
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppwriteiconinitialization.h b/src/tools/uic/cpp/cppwriteiconinitialization.h
new file mode 100644
index 0000000000..b3cf270838
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteiconinitialization.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPWRITEICONINITIALIZATION_H
+#define CPPWRITEICONINITIALIZATION_H
+
+#include "treewalker.h"
+
+class QString;
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class Driver;
+class Uic;
+
+struct Option;
+
+namespace CPP {
+
+class WriteIconInitialization : public TreeWalker
+{
+public:
+ WriteIconInitialization(Uic *uic);
+
+ void acceptUI(DomUI *node);
+ void acceptImages(DomImages *images);
+ void acceptImage(DomImage *image);
+
+ static QString iconFromDataFunction();
+
+private:
+ Uic *uic;
+ Driver *driver;
+ QTextStream &output;
+ const Option &option;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPWRITEICONINITIALIZATION_H
diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp
new file mode 100644
index 0000000000..d09c712b7b
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteincludes.cpp
@@ -0,0 +1,342 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppwriteincludes.h"
+#include "driver.h"
+#include "ui4.h"
+#include "uic.h"
+#include "databaseinfo.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QTextStream>
+
+#include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+enum { debugWriteIncludes = 0 };
+enum { warnHeaderGeneration = 0 };
+
+struct ClassInfoEntry
+{
+ const char *klass;
+ const char *module;
+ const char *header;
+};
+
+static const ClassInfoEntry qclass_lib_map[] = {
+#define QT_CLASS_LIB(klass, module, header) { #klass, #module, #header },
+#include "qclass_lib_map.h"
+
+#undef QT_CLASS_LIB
+};
+
+// Format a module header as 'QtCore/QObject'
+static inline QString moduleHeader(const QString &module, const QString &header)
+{
+ QString rc = module;
+ rc += QLatin1Char('/');
+ rc += header;
+ return rc;
+}
+
+namespace CPP {
+
+WriteIncludes::WriteIncludes(Uic *uic)
+ : m_uic(uic), m_output(uic->output()), m_scriptsActivated(false)
+{
+ // When possible (no namespace) use the "QtModule/QClass" convention
+ // and create a re-mapping of the old header "qclass.h" to it. Do not do this
+ // for the "Phonon::Someclass" classes, however.
+ const QString namespaceDelimiter = QLatin1String("::");
+ const ClassInfoEntry *classLibEnd = qclass_lib_map + sizeof(qclass_lib_map)/sizeof(ClassInfoEntry);
+ for(const ClassInfoEntry *it = qclass_lib_map; it < classLibEnd; ++it) {
+ const QString klass = QLatin1String(it->klass);
+ const QString module = QLatin1String(it->module);
+ QLatin1String header = QLatin1String(it->header);
+ if (klass.contains(namespaceDelimiter)) {
+ m_classToHeader.insert(klass, moduleHeader(module, header));
+ } else {
+ const QString newHeader = moduleHeader(module, klass);
+ m_classToHeader.insert(klass, newHeader);
+ m_oldHeaderToNewHeader.insert(header, newHeader);
+ }
+ }
+}
+
+void WriteIncludes::acceptUI(DomUI *node)
+{
+ m_scriptsActivated = false;
+ m_localIncludes.clear();
+ m_globalIncludes.clear();
+ m_knownClasses.clear();
+ m_includeBaseNames.clear();
+
+ if (node->elementIncludes())
+ acceptIncludes(node->elementIncludes());
+
+ if (node->elementCustomWidgets())
+ TreeWalker::acceptCustomWidgets(node->elementCustomWidgets());
+
+ add(QLatin1String("QApplication"));
+ add(QLatin1String("QVariant"));
+ add(QLatin1String("QAction"));
+
+ add(QLatin1String("QButtonGroup")); // ### only if it is really necessary
+ add(QLatin1String("QHeaderView"));
+
+ if (m_uic->hasExternalPixmap() && m_uic->pixmapFunction() == QLatin1String("qPixmapFromMimeSource")) {
+#ifdef QT_NO_QT3_SUPPORT
+ qWarning("%s: Warning: The form file has external pixmaps or qPixmapFromMimeSource() set as a pixmap function. "
+ "This requires Qt 3 support, which is disabled. The resulting code will not compile.",
+ qPrintable(m_uic->option().messagePrefix()));
+#endif
+ add(QLatin1String("Q3MimeSourceFactory"));
+ }
+
+ if (m_uic->databaseInfo()->connections().size()) {
+ add(QLatin1String("QSqlDatabase"));
+ add(QLatin1String("Q3SqlCursor"));
+ add(QLatin1String("QSqlRecord"));
+ add(QLatin1String("Q3SqlForm"));
+ }
+
+ TreeWalker::acceptUI(node);
+
+ writeHeaders(m_globalIncludes, true);
+ writeHeaders(m_localIncludes, false);
+
+ m_output << QLatin1Char('\n');
+}
+
+void WriteIncludes::acceptWidget(DomWidget *node)
+{
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s '%s'\n", Q_FUNC_INFO, qPrintable(node->attributeClass()));
+
+ add(node->attributeClass());
+ TreeWalker::acceptWidget(node);
+}
+
+void WriteIncludes::acceptLayout(DomLayout *node)
+{
+ add(node->attributeClass());
+ TreeWalker::acceptLayout(node);
+}
+
+void WriteIncludes::acceptSpacer(DomSpacer *node)
+{
+ add(QLatin1String("QSpacerItem"));
+ TreeWalker::acceptSpacer(node);
+}
+
+void WriteIncludes::acceptProperty(DomProperty *node)
+{
+ if (node->kind() == DomProperty::Date)
+ add(QLatin1String("QDate"));
+ if (node->kind() == DomProperty::Locale)
+ add(QLatin1String("QLocale"));
+ TreeWalker::acceptProperty(node);
+}
+
+void WriteIncludes::insertIncludeForClass(const QString &className, QString header, bool global)
+{
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s %s '%s' %d\n", Q_FUNC_INFO, qPrintable(className), qPrintable(header), global);
+
+ do {
+ if (!header.isEmpty())
+ break;
+
+ // Known class
+ const StringMap::const_iterator it = m_classToHeader.constFind(className);
+ if (it != m_classToHeader.constEnd()) {
+ header = it.value();
+ global = true;
+ break;
+ }
+
+ // Quick check by class name to detect includehints provided for custom widgets.
+ // Remove namespaces
+ QString lowerClassName = className.toLower();
+ static const QString namespaceSeparator = QLatin1String("::");
+ const int namespaceIndex = lowerClassName.lastIndexOf(namespaceSeparator);
+ if (namespaceIndex != -1)
+ lowerClassName.remove(0, namespaceIndex + namespaceSeparator.size());
+ if (m_includeBaseNames.contains(lowerClassName)) {
+ header.clear();
+ break;
+ }
+
+ // Last resort: Create default header
+ if (!m_uic->option().implicitIncludes)
+ break;
+ header = lowerClassName;
+ header += QLatin1String(".h");
+ if (warnHeaderGeneration) {
+ qWarning("%s: Warning: generated header '%s' for class '%s'.",
+ qPrintable(m_uic->option().messagePrefix()),
+ qPrintable(header), qPrintable(className));
+
+ }
+
+ global = true;
+ } while (false);
+
+ if (!header.isEmpty())
+ insertInclude(header, global);
+}
+
+void WriteIncludes::add(const QString &className, bool determineHeader, const QString &header, bool global)
+{
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s %s '%s' %d\n", Q_FUNC_INFO, qPrintable(className), qPrintable(header), global);
+
+ if (className.isEmpty() || m_knownClasses.contains(className))
+ return;
+
+ m_knownClasses.insert(className);
+
+ if (className == QLatin1String("Line")) { // ### hmm, deprecate me!
+ add(QLatin1String("QFrame"));
+ return;
+ }
+
+ if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ListView")) ||
+ m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3Table"))) {
+ add(QLatin1String("Q3Header"));
+ }
+ if (determineHeader)
+ insertIncludeForClass(className, header, global);
+}
+
+void WriteIncludes::acceptCustomWidget(DomCustomWidget *node)
+{
+ const QString className = node->elementClass();
+ if (className.isEmpty())
+ return;
+
+ if (const DomScript *domScript = node->elementScript())
+ if (!domScript->text().isEmpty())
+ activateScripts();
+
+ if (!node->elementHeader() || node->elementHeader()->text().isEmpty()) {
+ add(className, false); // no header specified
+ } else {
+ // custom header unless it is a built-in qt class
+ QString header;
+ bool global = false;
+ if (!m_classToHeader.contains(className)) {
+ global = node->elementHeader()->attributeLocation().toLower() == QLatin1String("global");
+ header = node->elementHeader()->text();
+ }
+ add(className, true, header, global);
+ }
+}
+
+void WriteIncludes::acceptCustomWidgets(DomCustomWidgets *node)
+{
+ Q_UNUSED(node);
+}
+
+void WriteIncludes::acceptIncludes(DomIncludes *node)
+{
+ TreeWalker::acceptIncludes(node);
+}
+
+void WriteIncludes::acceptInclude(DomInclude *node)
+{
+ bool global = true;
+ if (node->hasAttributeLocation())
+ global = node->attributeLocation() == QLatin1String("global");
+ insertInclude(node->text(), global);
+}
+
+void WriteIncludes::insertInclude(const QString &header, bool global)
+{
+ if (debugWriteIncludes)
+ fprintf(stderr, "%s %s %d\n", Q_FUNC_INFO, qPrintable(header), global);
+
+ OrderedSet &includes = global ? m_globalIncludes : m_localIncludes;
+ if (includes.contains(header))
+ return;
+ // Insert. Also remember base name for quick check of suspicious custom plugins
+ includes.insert(header, false);
+ const QString lowerBaseName = QFileInfo(header).completeBaseName ().toLower();
+ m_includeBaseNames.insert(lowerBaseName);
+}
+
+void WriteIncludes::writeHeaders(const OrderedSet &headers, bool global)
+{
+ const QChar openingQuote = global ? QLatin1Char('<') : QLatin1Char('"');
+ const QChar closingQuote = global ? QLatin1Char('>') : QLatin1Char('"');
+
+ // Check for the old headers 'qslider.h' and replace by 'QtGui/QSlider'
+ const OrderedSet::const_iterator cend = headers.constEnd();
+ for (OrderedSet::const_iterator sit = headers.constBegin(); sit != cend; ++sit) {
+ const StringMap::const_iterator hit = m_oldHeaderToNewHeader.constFind(sit.key());
+ const bool mapped = hit != m_oldHeaderToNewHeader.constEnd();
+ const QString header = mapped ? hit.value() : sit.key();
+ if (!header.trimmed().isEmpty()) {
+ m_output << "#include " << openingQuote << header << closingQuote << QLatin1Char('\n');
+ }
+ }
+}
+
+void WriteIncludes::acceptWidgetScripts(const DomScripts &scripts, DomWidget *, const DomWidgets &)
+{
+ if (!scripts.empty()) {
+ activateScripts();
+ }
+}
+
+void WriteIncludes::activateScripts()
+{
+ if (!m_scriptsActivated) {
+ add(QLatin1String("QScriptEngine"));
+ add(QLatin1String("QDebug"));
+ m_scriptsActivated = true;
+ }
+}
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppwriteincludes.h b/src/tools/uic/cpp/cppwriteincludes.h
new file mode 100644
index 0000000000..2b98fe9616
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteincludes.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPWRITEINCLUDES_H
+#define CPPWRITEINCLUDES_H
+
+#include "treewalker.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QMap>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class Driver;
+class Uic;
+
+namespace CPP {
+
+struct WriteIncludes : public TreeWalker
+{
+ WriteIncludes(Uic *uic);
+
+ void acceptUI(DomUI *node);
+ void acceptWidget(DomWidget *node);
+ void acceptLayout(DomLayout *node);
+ void acceptSpacer(DomSpacer *node);
+ void acceptProperty(DomProperty *node);
+ void acceptWidgetScripts(const DomScripts &, DomWidget *, const DomWidgets &);
+
+//
+// custom widgets
+//
+ void acceptCustomWidgets(DomCustomWidgets *node);
+ void acceptCustomWidget(DomCustomWidget *node);
+
+//
+// include hints
+//
+ void acceptIncludes(DomIncludes *node);
+ void acceptInclude(DomInclude *node);
+
+ bool scriptsActivated() const { return m_scriptsActivated; }
+
+private:
+ void add(const QString &className, bool determineHeader = true, const QString &header = QString(), bool global = false);
+
+private:
+ typedef QMap<QString, bool> OrderedSet;
+ void insertIncludeForClass(const QString &className, QString header = QString(), bool global = false);
+ void insertInclude(const QString &header, bool global);
+ void writeHeaders(const OrderedSet &headers, bool global);
+ QString headerForClassName(const QString &className) const;
+ void activateScripts();
+
+ const Uic *m_uic;
+ QTextStream &m_output;
+
+ OrderedSet m_localIncludes;
+ OrderedSet m_globalIncludes;
+ QSet<QString> m_includeBaseNames;
+
+ QSet<QString> m_knownClasses;
+
+ typedef QMap<QString, QString> StringMap;
+ StringMap m_classToHeader;
+ StringMap m_oldHeaderToNewHeader;
+
+ bool m_scriptsActivated;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPWRITEINCLUDES_H
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
new file mode 100644
index 0000000000..37d012c109
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -0,0 +1,3012 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppwriteinitialization.h"
+#include "cppwriteiconinitialization.h"
+#include "driver.h"
+#include "ui4.h"
+#include "utils.h"
+#include "uic.h"
+#include "databaseinfo.h"
+#include "globaldefs.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+
+#include <ctype.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ // Fixup an enumeration name from class Qt.
+ // They are currently stored as "BottomToolBarArea" instead of "Qt::BottomToolBarArea".
+ // due to MO issues. This might be fixed in the future.
+ void fixQtEnumerationName(QString& name) {
+ static const QLatin1String prefix("Qt::");
+ if (name.indexOf(prefix) != 0)
+ name.prepend(prefix);
+ }
+ // figure out the toolbar area of a DOM attrib list.
+ // By legacy, it is stored as an integer. As of 4.3.0, it is the enumeration value.
+ QString toolBarAreaStringFromDOMAttributes(const CPP::WriteInitialization::DomPropertyMap &attributes) {
+ const DomProperty *pstyle = attributes.value(QLatin1String("toolBarArea"));
+ if (!pstyle)
+ return QString();
+
+ switch (pstyle->kind()) {
+ case DomProperty::Number: {
+ QString area = QLatin1String("static_cast<Qt::ToolBarArea>(");
+ area += QString::number(pstyle->elementNumber());
+ area += QLatin1String("), ");
+ return area;
+ }
+ case DomProperty::Enum: {
+ QString area = pstyle->elementEnum();
+ fixQtEnumerationName(area);
+ area += QLatin1String(", ");
+ return area;
+ }
+ default:
+ break;
+ }
+ return QString();
+ }
+
+ // Write a statement to create a spacer item.
+ void writeSpacerItem(const DomSpacer *node, QTextStream &output) {
+ const QHash<QString, DomProperty *> properties = propertyMap(node->elementProperty());
+ output << "new QSpacerItem(";
+
+ if (properties.contains(QLatin1String("sizeHint"))) {
+ const DomSize *sizeHint = properties.value(QLatin1String("sizeHint"))->elementSize();
+ output << sizeHint->elementWidth() << ", " << sizeHint->elementHeight() << ", ";
+ }
+
+ // size type
+ QString sizeType = properties.contains(QLatin1String("sizeType")) ?
+ properties.value(QLatin1String("sizeType"))->elementEnum() :
+ QString::fromLatin1("Expanding");
+
+ if (!sizeType.startsWith(QLatin1String("QSizePolicy::")))
+ sizeType.prepend(QLatin1String("QSizePolicy::"));
+ // orientation
+ bool isVspacer = false;
+ if (properties.contains(QLatin1String("orientation"))) {
+ const QString orientation = properties.value(QLatin1String("orientation"))->elementEnum();
+ if (orientation == QLatin1String("Qt::Vertical") || orientation == QLatin1String("Vertical")) isVspacer = true;
+ }
+
+ if (isVspacer)
+ output << "QSizePolicy::Minimum, " << sizeType << ')';
+ else
+ output << sizeType << ", QSizePolicy::Minimum)";
+ }
+
+
+ // Helper for implementing comparison functions for integers.
+ int compareInt(int i1, int i2) {
+ if (i1 < i2) return -1;
+ if (i1 > i2) return 1;
+ return 0;
+ }
+
+ // Write object->setFoo(x);
+ template <class Value>
+ void writeSetter(const QString &indent, const QString &varName,const QString &setter, Value v, QTextStream &str) {
+ str << indent << varName << "->" << setter << '(' << v << ");\n";
+ }
+
+ void writeSetupUIScriptVariableDeclarations(const QString &indent, QTextStream &str) {
+ str << indent << "ScriptContext scriptContext;\n"
+ << indent << "QWidgetList childWidgets;\n";
+ }
+
+ static inline bool iconHasStatePixmaps(const DomResourceIcon *i) {
+ return i->hasElementNormalOff() || i->hasElementNormalOn() ||
+ i->hasElementDisabledOff() || i->hasElementDisabledOn() ||
+ i->hasElementActiveOff() || i->hasElementActiveOn() ||
+ i->hasElementSelectedOff() || i->hasElementSelectedOn();
+ }
+
+ static inline bool isIconFormat44(const DomResourceIcon *i) {
+ return iconHasStatePixmaps(i) || !i->attributeTheme().isEmpty();
+ }
+
+ // Check on properties. Filter out empty legacy pixmap/icon properties
+ // as Designer pre 4.4 used to remove missing resource references.
+ // This can no longer be handled by the code as we have 'setIcon(QIcon())' as well as 'QIcon icon'
+ static bool checkProperty(const QString &fileName, const DomProperty *p) {
+ switch (p->kind()) {
+ case DomProperty::IconSet:
+ if (const DomResourceIcon *dri = p->elementIconSet()) {
+ if (!isIconFormat44(dri)) {
+ if (dri->text().isEmpty()) {
+ const QString msg = QString::fromUtf8("%1: Warning: An invalid icon property '%2' was encountered.").arg(fileName).arg(p->attributeName());
+ qWarning("%s", qPrintable(msg));
+ return false;
+ }
+ }
+ }
+ break;
+ case DomProperty::Pixmap:
+ if (const DomResourcePixmap *drp = p->elementPixmap())
+ if (drp->text().isEmpty()) {
+ const QString msg = QString::fromUtf8("%1: Warning: An invalid pixmap property '%2' was encountered.").arg(fileName).arg(p->attributeName());
+ qWarning("%s", qPrintable(msg));
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ inline void openIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#ifndef ") << symbol << endl; }
+ inline void closeIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#endif // ") << symbol << endl; }
+
+ const char *accessibilityDefineC = "QT_NO_ACCESSIBILITY";
+ const char *toolTipDefineC = "QT_NO_TOOLTIP";
+ const char *whatsThisDefineC = "QT_NO_WHATSTHIS";
+ const char *statusTipDefineC = "QT_NO_STATUSTIP";
+ const char *shortcutDefineC = "QT_NO_SHORTCUT";
+}
+
+namespace CPP {
+
+FontHandle::FontHandle(const DomFont *domFont) :
+ m_domFont(domFont)
+{
+}
+
+int FontHandle::compare(const FontHandle &rhs) const
+{
+ const QString family = m_domFont->hasElementFamily() ? m_domFont->elementFamily() : QString();
+ const QString rhsFamily = rhs.m_domFont->hasElementFamily() ? rhs.m_domFont->elementFamily() : QString();
+
+ if (const int frc = family.compare(rhsFamily))
+ return frc;
+
+ const int pointSize = m_domFont->hasElementPointSize() ? m_domFont->elementPointSize() : -1;
+ const int rhsPointSize = rhs.m_domFont->hasElementPointSize() ? rhs.m_domFont->elementPointSize() : -1;
+
+ if (const int crc = compareInt(pointSize, rhsPointSize))
+ return crc;
+
+ const int bold = m_domFont->hasElementBold() ? (m_domFont->elementBold() ? 1 : 0) : -1;
+ const int rhsBold = rhs.m_domFont->hasElementBold() ? (rhs.m_domFont->elementBold() ? 1 : 0) : -1;
+ if (const int crc = compareInt(bold, rhsBold))
+ return crc;
+
+ const int italic = m_domFont->hasElementItalic() ? (m_domFont->elementItalic() ? 1 : 0) : -1;
+ const int rhsItalic = rhs.m_domFont->hasElementItalic() ? (rhs.m_domFont->elementItalic() ? 1 : 0) : -1;
+ if (const int crc = compareInt(italic, rhsItalic))
+ return crc;
+
+ const int underline = m_domFont->hasElementUnderline() ? (m_domFont->elementUnderline() ? 1 : 0) : -1;
+ const int rhsUnderline = rhs.m_domFont->hasElementUnderline() ? (rhs.m_domFont->elementUnderline() ? 1 : 0) : -1;
+ if (const int crc = compareInt(underline, rhsUnderline))
+ return crc;
+
+ const int weight = m_domFont->hasElementWeight() ? m_domFont->elementWeight() : -1;
+ const int rhsWeight = rhs.m_domFont->hasElementWeight() ? rhs.m_domFont->elementWeight() : -1;
+ if (const int crc = compareInt(weight, rhsWeight))
+ return crc;
+
+ const int strikeOut = m_domFont->hasElementStrikeOut() ? (m_domFont->elementStrikeOut() ? 1 : 0) : -1;
+ const int rhsStrikeOut = rhs.m_domFont->hasElementStrikeOut() ? (rhs.m_domFont->elementStrikeOut() ? 1 : 0) : -1;
+ if (const int crc = compareInt(strikeOut, rhsStrikeOut))
+ return crc;
+
+ const int kerning = m_domFont->hasElementKerning() ? (m_domFont->elementKerning() ? 1 : 0) : -1;
+ const int rhsKerning = rhs.m_domFont->hasElementKerning() ? (rhs.m_domFont->elementKerning() ? 1 : 0) : -1;
+ if (const int crc = compareInt(kerning, rhsKerning))
+ return crc;
+
+ const int antialiasing = m_domFont->hasElementAntialiasing() ? (m_domFont->elementAntialiasing() ? 1 : 0) : -1;
+ const int rhsAntialiasing = rhs.m_domFont->hasElementAntialiasing() ? (rhs.m_domFont->elementAntialiasing() ? 1 : 0) : -1;
+ if (const int crc = compareInt(antialiasing, rhsAntialiasing))
+ return crc;
+
+ const QString styleStrategy = m_domFont->hasElementStyleStrategy() ? m_domFont->elementStyleStrategy() : QString();
+ const QString rhsStyleStrategy = rhs.m_domFont->hasElementStyleStrategy() ? rhs.m_domFont->elementStyleStrategy() : QString();
+
+ if (const int src = styleStrategy.compare(rhsStyleStrategy))
+ return src;
+
+ return 0;
+}
+
+IconHandle::IconHandle(const DomResourceIcon *domIcon) :
+ m_domIcon(domIcon)
+{
+}
+
+int IconHandle::compare(const IconHandle &rhs) const
+{
+ if (const int comp = m_domIcon->attributeTheme().compare(rhs.m_domIcon->attributeTheme()))
+ return comp;
+
+ const QString normalOff = m_domIcon->hasElementNormalOff() ? m_domIcon->elementNormalOff()->text() : QString();
+ const QString rhsNormalOff = rhs.m_domIcon->hasElementNormalOff() ? rhs.m_domIcon->elementNormalOff()->text() : QString();
+ if (const int comp = normalOff.compare(rhsNormalOff))
+ return comp;
+
+ const QString normalOn = m_domIcon->hasElementNormalOn() ? m_domIcon->elementNormalOn()->text() : QString();
+ const QString rhsNormalOn = rhs.m_domIcon->hasElementNormalOn() ? rhs.m_domIcon->elementNormalOn()->text() : QString();
+ if (const int comp = normalOn.compare(rhsNormalOn))
+ return comp;
+
+ const QString disabledOff = m_domIcon->hasElementDisabledOff() ? m_domIcon->elementDisabledOff()->text() : QString();
+ const QString rhsDisabledOff = rhs.m_domIcon->hasElementDisabledOff() ? rhs.m_domIcon->elementDisabledOff()->text() : QString();
+ if (const int comp = disabledOff.compare(rhsDisabledOff))
+ return comp;
+
+ const QString disabledOn = m_domIcon->hasElementDisabledOn() ? m_domIcon->elementDisabledOn()->text() : QString();
+ const QString rhsDisabledOn = rhs.m_domIcon->hasElementDisabledOn() ? rhs.m_domIcon->elementDisabledOn()->text() : QString();
+ if (const int comp = disabledOn.compare(rhsDisabledOn))
+ return comp;
+
+ const QString activeOff = m_domIcon->hasElementActiveOff() ? m_domIcon->elementActiveOff()->text() : QString();
+ const QString rhsActiveOff = rhs.m_domIcon->hasElementActiveOff() ? rhs.m_domIcon->elementActiveOff()->text() : QString();
+ if (const int comp = activeOff.compare(rhsActiveOff))
+ return comp;
+
+ const QString activeOn = m_domIcon->hasElementActiveOn() ? m_domIcon->elementActiveOn()->text() : QString();
+ const QString rhsActiveOn = rhs.m_domIcon->hasElementActiveOn() ? rhs.m_domIcon->elementActiveOn()->text() : QString();
+ if (const int comp = activeOn.compare(rhsActiveOn))
+ return comp;
+
+ const QString selectedOff = m_domIcon->hasElementSelectedOff() ? m_domIcon->elementSelectedOff()->text() : QString();
+ const QString rhsSelectedOff = rhs.m_domIcon->hasElementSelectedOff() ? rhs.m_domIcon->elementSelectedOff()->text() : QString();
+ if (const int comp = selectedOff.compare(rhsSelectedOff))
+ return comp;
+
+ const QString selectedOn = m_domIcon->hasElementSelectedOn() ? m_domIcon->elementSelectedOn()->text() : QString();
+ const QString rhsSelectedOn = rhs.m_domIcon->hasElementSelectedOn() ? rhs.m_domIcon->elementSelectedOn()->text() : QString();
+ if (const int comp = selectedOn.compare(rhsSelectedOn))
+ return comp;
+ // Pre 4.4 Legacy
+ if (const int comp = m_domIcon->text().compare(rhs.m_domIcon->text()))
+ return comp;
+
+ return 0;
+}
+
+
+#if defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
+inline uint qHash(const SizePolicyHandle &handle) { return qHash(handle.m_domSizePolicy); }
+inline uint qHash(const FontHandle &handle) { return qHash(handle.m_domFont); }
+inline uint qHash(const IconHandle &handle) { return qHash(handle.m_domIcon); }
+#endif
+
+SizePolicyHandle::SizePolicyHandle(const DomSizePolicy *domSizePolicy) :
+ m_domSizePolicy(domSizePolicy)
+{
+}
+
+int SizePolicyHandle::compare(const SizePolicyHandle &rhs) const
+{
+
+ const int hSizeType = m_domSizePolicy->hasElementHSizeType() ? m_domSizePolicy->elementHSizeType() : -1;
+ const int rhsHSizeType = rhs.m_domSizePolicy->hasElementHSizeType() ? rhs.m_domSizePolicy->elementHSizeType() : -1;
+ if (const int crc = compareInt(hSizeType, rhsHSizeType))
+ return crc;
+
+ const int vSizeType = m_domSizePolicy->hasElementVSizeType() ? m_domSizePolicy->elementVSizeType() : -1;
+ const int rhsVSizeType = rhs.m_domSizePolicy->hasElementVSizeType() ? rhs.m_domSizePolicy->elementVSizeType() : -1;
+ if (const int crc = compareInt(vSizeType, rhsVSizeType))
+ return crc;
+
+ const int hStretch = m_domSizePolicy->hasElementHorStretch() ? m_domSizePolicy->elementHorStretch() : -1;
+ const int rhsHStretch = rhs.m_domSizePolicy->hasElementHorStretch() ? rhs.m_domSizePolicy->elementHorStretch() : -1;
+ if (const int crc = compareInt(hStretch, rhsHStretch))
+ return crc;
+
+ const int vStretch = m_domSizePolicy->hasElementVerStretch() ? m_domSizePolicy->elementVerStretch() : -1;
+ const int rhsVStretch = rhs.m_domSizePolicy->hasElementVerStretch() ? rhs.m_domSizePolicy->elementVerStretch() : -1;
+ if (const int crc = compareInt(vStretch, rhsVStretch))
+ return crc;
+
+ const QString attributeHSizeType = m_domSizePolicy->hasAttributeHSizeType() ? m_domSizePolicy->attributeHSizeType() : QString();
+ const QString rhsAttributeHSizeType = rhs.m_domSizePolicy->hasAttributeHSizeType() ? rhs.m_domSizePolicy->attributeHSizeType() : QString();
+
+ if (const int hrc = attributeHSizeType.compare(rhsAttributeHSizeType))
+ return hrc;
+
+ const QString attributeVSizeType = m_domSizePolicy->hasAttributeVSizeType() ? m_domSizePolicy->attributeVSizeType() : QString();
+ const QString rhsAttributeVSizeType = rhs.m_domSizePolicy->hasAttributeVSizeType() ? rhs.m_domSizePolicy->attributeVSizeType() : QString();
+
+ return attributeVSizeType.compare(rhsAttributeVSizeType);
+}
+
+// --- WriteInitialization: LayoutDefaultHandler
+
+WriteInitialization::LayoutDefaultHandler::LayoutDefaultHandler()
+{
+ qFill(m_state, m_state + NumProperties, 0u);
+ qFill(m_defaultValues, m_defaultValues + NumProperties, 0);
+}
+
+
+
+void WriteInitialization::LayoutDefaultHandler::acceptLayoutDefault(DomLayoutDefault *node)
+{
+ if (!node)
+ return;
+ if (node->hasAttributeMargin()) {
+ m_state[Margin] |= HasDefaultValue;
+ m_defaultValues[Margin] = node->attributeMargin();
+ }
+ if (node->hasAttributeSpacing()) {
+ m_state[Spacing] |= HasDefaultValue;
+ m_defaultValues[Spacing] = node->attributeSpacing();
+ }
+}
+
+void WriteInitialization::LayoutDefaultHandler::acceptLayoutFunction(DomLayoutFunction *node)
+{
+ if (!node)
+ return;
+ if (node->hasAttributeMargin()) {
+ m_state[Margin] |= HasDefaultFunction;
+ m_functions[Margin] = node->attributeMargin();
+ m_functions[Margin] += QLatin1String("()");
+ }
+ if (node->hasAttributeSpacing()) {
+ m_state[Spacing] |= HasDefaultFunction;
+ m_functions[Spacing] = node->attributeSpacing();
+ m_functions[Spacing] += QLatin1String("()");
+ }
+}
+
+static inline void writeContentsMargins(const QString &indent, const QString &objectName, int value, QTextStream &str)
+{
+ QString contentsMargins;
+ QTextStream(&contentsMargins) << value << ", " << value << ", " << value << ", " << value;
+ writeSetter(indent, objectName, QLatin1String("setContentsMargins"), contentsMargins, str);
+ }
+
+void WriteInitialization::LayoutDefaultHandler::writeProperty(int p, const QString &indent, const QString &objectName,
+ const DomPropertyMap &properties, const QString &propertyName, const QString &setter,
+ int defaultStyleValue, bool suppressDefault, QTextStream &str) const
+{
+ // User value
+ const DomPropertyMap::const_iterator mit = properties.constFind(propertyName);
+ const bool found = mit != properties.constEnd();
+ if (found) {
+ const int value = mit.value()->elementNumber();
+ // Emulate the pre 4.3 behaviour: The value form default value was only used to determine
+ // the default value, layout properties were always written
+ const bool useLayoutFunctionPre43 = !suppressDefault && (m_state[p] == (HasDefaultFunction|HasDefaultValue)) && value == m_defaultValues[p];
+ if (!useLayoutFunctionPre43) {
+ bool ifndefMac = (!(m_state[p] & (HasDefaultFunction|HasDefaultValue))
+ && value == defaultStyleValue);
+ if (ifndefMac)
+ str << "#ifndef Q_OS_MAC\n";
+ if (p == Margin) { // Use setContentsMargins for numeric values
+ writeContentsMargins(indent, objectName, value, str);
+ } else {
+ writeSetter(indent, objectName, setter, value, str);
+ }
+ if (ifndefMac)
+ str << "#endif\n";
+ return;
+ }
+ }
+ if (suppressDefault)
+ return;
+ // get default.
+ if (m_state[p] & HasDefaultFunction) {
+ // Do not use setContentsMargins to avoid repetitive evaluations.
+ writeSetter(indent, objectName, setter, m_functions[p], str);
+ return;
+ }
+ if (m_state[p] & HasDefaultValue) {
+ if (p == Margin) { // Use setContentsMargins for numeric values
+ writeContentsMargins(indent, objectName, m_defaultValues[p], str);
+ } else {
+ writeSetter(indent, objectName, setter, m_defaultValues[p], str);
+ }
+ }
+ return;
+}
+
+
+void WriteInitialization::LayoutDefaultHandler::writeProperties(const QString &indent, const QString &varName,
+ const DomPropertyMap &properties, int marginType,
+ bool suppressMarginDefault,
+ QTextStream &str) const {
+ // Write out properties and ignore the ones found in
+ // subsequent writing of the property list.
+ int defaultSpacing = marginType == WriteInitialization::Use43UiFile ? -1 : 6;
+ writeProperty(Spacing, indent, varName, properties, QLatin1String("spacing"), QLatin1String("setSpacing"),
+ defaultSpacing, false, str);
+ // We use 9 as TopLevelMargin, since Designer seem to always use 9.
+ static const int layoutmargins[4] = {-1, 9, 9, 0};
+ writeProperty(Margin, indent, varName, properties, QLatin1String("margin"), QLatin1String("setMargin"),
+ layoutmargins[marginType], suppressMarginDefault, str);
+}
+
+static bool needsTranslation(DomString *str)
+{
+ if (!str)
+ return false;
+ return !str->hasAttributeNotr() || !toBool(str->attributeNotr());
+}
+
+// --- WriteInitialization
+WriteInitialization::WriteInitialization(Uic *uic, bool activateScripts) :
+ m_uic(uic),
+ m_driver(uic->driver()), m_output(uic->output()), m_option(uic->option()),
+ m_indent(m_option.indent + m_option.indent),
+ m_dindent(m_indent + m_option.indent),
+ m_stdsetdef(true),
+ m_layoutMarginType(TopLevelMargin),
+ m_mainFormUsedInRetranslateUi(false),
+ m_delayedOut(&m_delayedInitialization, QIODevice::WriteOnly),
+ m_refreshOut(&m_refreshInitialization, QIODevice::WriteOnly),
+ m_actionOut(&m_delayedActionInitialization, QIODevice::WriteOnly),
+ m_activateScripts(activateScripts), m_layoutWidget(false),
+ m_firstThemeIcon(true)
+{
+}
+
+void WriteInitialization::acceptUI(DomUI *node)
+{
+ m_registeredImages.clear();
+ m_actionGroupChain.push(0);
+ m_widgetChain.push(0);
+ m_layoutChain.push(0);
+
+ acceptLayoutDefault(node->elementLayoutDefault());
+ acceptLayoutFunction(node->elementLayoutFunction());
+
+ if (node->elementCustomWidgets())
+ TreeWalker::acceptCustomWidgets(node->elementCustomWidgets());
+
+ if (node->elementImages())
+ TreeWalker::acceptImages(node->elementImages());
+
+ if (m_option.generateImplemetation)
+ m_output << "#include <" << m_driver->headerFileName() << ">\n\n";
+
+ m_stdsetdef = true;
+ if (node->hasAttributeStdSetDef())
+ m_stdsetdef = node->attributeStdSetDef();
+
+ const QString className = node->elementClass() + m_option.postfix;
+ m_generatedClass = className;
+
+ const QString varName = m_driver->findOrInsertWidget(node->elementWidget());
+ m_mainFormVarName = varName;
+ m_registeredWidgets.insert(varName, node->elementWidget()); // register the main widget
+
+ const QString widgetClassName = node->elementWidget()->attributeClass();
+
+ m_output << m_option.indent << "void " << "setupUi(" << widgetClassName << " *" << varName << ")\n"
+ << m_option.indent << "{\n";
+
+ if (m_activateScripts)
+ writeSetupUIScriptVariableDeclarations(m_indent, m_output);
+
+ const QStringList connections = m_uic->databaseInfo()->connections();
+ for (int i=0; i<connections.size(); ++i) {
+ QString connection = connections.at(i);
+
+ if (connection == QLatin1String("(default)"))
+ continue;
+
+ const QString varConn = connection + QLatin1String("Connection");
+ m_output << m_indent << varConn << " = QSqlDatabase::database(" << fixString(connection, m_dindent) << ");\n";
+ }
+
+ acceptWidget(node->elementWidget());
+
+ if (m_buddies.size() > 0)
+ openIfndef(m_output, QLatin1String(shortcutDefineC));
+ for (int i=0; i<m_buddies.size(); ++i) {
+ const Buddy &b = m_buddies.at(i);
+
+ if (!m_registeredWidgets.contains(b.objName)) {
+ fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
+ qPrintable(m_option.messagePrefix()),
+ b.objName.toLatin1().data());
+ continue;
+ } else if (!m_registeredWidgets.contains(b.buddy)) {
+ fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n",
+ qPrintable(m_option.messagePrefix()),
+ b.buddy.toLatin1().data());
+ continue;
+ }
+
+ m_output << m_indent << b.objName << "->setBuddy(" << b.buddy << ");\n";
+ }
+ if (m_buddies.size() > 0)
+ closeIfndef(m_output, QLatin1String(shortcutDefineC));
+
+ if (node->elementTabStops())
+ acceptTabStops(node->elementTabStops());
+
+ if (m_delayedActionInitialization.size())
+ m_output << "\n" << m_delayedActionInitialization;
+
+ m_output << "\n" << m_indent << "retranslateUi(" << varName << ");\n";
+
+ if (node->elementConnections())
+ acceptConnections(node->elementConnections());
+
+ if (!m_delayedInitialization.isEmpty())
+ m_output << "\n" << m_delayedInitialization << "\n";
+
+ if (m_option.autoConnection)
+ m_output << "\n" << m_indent << "QMetaObject::connectSlotsByName(" << varName << ");\n";
+
+ m_output << m_option.indent << "} // setupUi\n\n";
+
+ if (!m_mainFormUsedInRetranslateUi) {
+ m_refreshInitialization += m_indent;
+ m_refreshInitialization += QLatin1String("Q_UNUSED(");
+ m_refreshInitialization += varName ;
+ m_refreshInitialization += QLatin1String(");\n");
+ }
+
+ m_output << m_option.indent << "void " << "retranslateUi(" << widgetClassName << " *" << varName << ")\n"
+ << m_option.indent << "{\n"
+ << m_refreshInitialization
+ << m_option.indent << "} // retranslateUi\n\n";
+
+ m_layoutChain.pop();
+ m_widgetChain.pop();
+ m_actionGroupChain.pop();
+}
+
+void WriteInitialization::addWizardPage(const QString &pageVarName, const DomWidget *page, const QString &parentWidget)
+{
+ /* If the node has a (free-format) string "pageId" attribute (which could
+ * an integer or an enumeration value), use setPage(), else addPage(). */
+ QString id;
+ const DomPropertyList attributes = page->elementAttribute();
+ if (!attributes.empty()) {
+ const DomPropertyList::const_iterator acend = attributes.constEnd();
+ for (DomPropertyList::const_iterator it = attributes.constBegin(); it != acend; ++it)
+ if ((*it)->attributeName() == QLatin1String("pageId")) {
+ if (const DomString *ds = (*it)->elementString())
+ id = ds->text();
+ break;
+ }
+ }
+ if (id.isEmpty()) {
+ m_output << m_indent << parentWidget << "->addPage(" << pageVarName << ");\n";
+ } else {
+ m_output << m_indent << parentWidget << "->setPage(" << id << ", " << pageVarName << ");\n";
+ }
+}
+
+void WriteInitialization::acceptWidget(DomWidget *node)
+{
+ m_layoutMarginType = m_widgetChain.count() == 1 ? TopLevelMargin : ChildMargin;
+ const QString className = node->attributeClass();
+ const QString varName = m_driver->findOrInsertWidget(node);
+ m_registeredWidgets.insert(varName, node); // register the current widget
+
+ QString parentWidget, parentClass;
+ if (m_widgetChain.top()) {
+ parentWidget = m_driver->findOrInsertWidget(m_widgetChain.top());
+ parentClass = m_widgetChain.top()->attributeClass();
+ }
+
+ const QString savedParentWidget = parentWidget;
+
+ if (m_uic->isContainer(parentClass) || m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3ToolBar")))
+ parentWidget.clear();
+
+ if (m_widgetChain.size() != 1)
+ m_output << m_indent << varName << " = new " << m_uic->customWidgetsInfo()->realClassName(className) << '(' << parentWidget << ");\n";
+
+ parentWidget = savedParentWidget;
+
+ if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ComboBox"))) {
+ initializeComboBox3(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))) {
+ initializeComboBox(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
+ initializeListWidget(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) {
+ initializeTreeWidget(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) {
+ initializeTableWidget(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ListBox"))) {
+ initializeQ3ListBox(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ListView"))) {
+ initializeQ3ListView(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3IconView"))) {
+ initializeQ3IconView(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3Table"))) {
+ initializeQ3Table(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DataTable"))) {
+ initializeQ3SqlDataTable(node);
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DataBrowser"))) {
+ initializeQ3SqlDataBrowser(node);
+ }
+
+ if (m_uic->isButton(className))
+ addButtonGroup(node, varName);
+
+ writeProperties(varName, className, node->elementProperty());
+
+ if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenu")) && parentWidget.size()) {
+ initializeMenu(node, parentWidget);
+ }
+
+ if (node->elementLayout().isEmpty())
+ m_layoutChain.push(0);
+
+ m_layoutWidget = false;
+ if (className == QLatin1String("QWidget") && !node->hasAttributeNative()) {
+ if (const DomWidget* parentWidget = m_widgetChain.top()) {
+ const QString parentClass = parentWidget->attributeClass();
+ if (parentClass != QLatin1String("QMainWindow")
+ && !m_uic->isCustomWidgetContainer(parentClass)
+ && !m_uic->isContainer(parentClass))
+ m_layoutWidget = true;
+ }
+ }
+ m_widgetChain.push(node);
+ m_layoutChain.push(0);
+ TreeWalker::acceptWidget(node);
+ m_layoutChain.pop();
+ m_widgetChain.pop();
+ m_layoutWidget = false;
+
+ const DomPropertyMap attributes = propertyMap(node->elementAttribute());
+
+ const QString pageDefaultString = QLatin1String("Page");
+
+ int id = -1;
+ if (const DomProperty *pid = attributes.value(QLatin1String("id"))) {
+ id = pid->elementNumber();
+ }
+
+ if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMainWindow"))
+ || m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3MainWindow"))) {
+
+ if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenuBar"))) {
+ if (!m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3MainWindow")))
+ m_output << m_indent << parentWidget << "->setMenuBar(" << varName <<");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBar"))) {
+ m_output << m_indent << parentWidget << "->addToolBar("
+ << toolBarAreaStringFromDOMAttributes(attributes) << varName << ");\n";
+
+ if (const DomProperty *pbreak = attributes.value(QLatin1String("toolBarBreak"))) {
+ if (pbreak->elementBool() == QLatin1String("true")) {
+ m_output << m_indent << parentWidget << "->insertToolBarBreak(" << varName << ");\n";
+ }
+ }
+
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"))) {
+ QString area;
+ if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) {
+ area += QLatin1String("static_cast<Qt::DockWidgetArea>(");
+ area += QString::number(pstyle->elementNumber());
+ area += QLatin1String("), ");
+ }
+
+ m_output << m_indent << parentWidget << "->addDockWidget(" << area << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) {
+ m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n";
+ } else if (!m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DockWindow"))
+ && !m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ToolBar"))) {
+ m_output << m_indent << parentWidget << "->setCentralWidget(" << varName << ");\n";
+ }
+ }
+
+ // Check for addPageMethod of a custom plugin first
+ const QString addPageMethod = m_uic->customWidgetsInfo()->customWidgetAddPageMethod(parentClass);
+ if (!addPageMethod.isEmpty()) {
+ m_output << m_indent << parentWidget << "->" << addPageMethod << '(' << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QStackedWidget"))) {
+ m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBar"))) {
+ m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3WidgetStack"))) {
+ m_output << m_indent << parentWidget << "->addWidget(" << varName << ", " << id << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QDockWidget"))) {
+ m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QScrollArea"))) {
+ m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QSplitter"))) {
+ m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMdiArea"))) {
+ m_output << m_indent << parentWidget << "->addSubWindow(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWorkspace"))) {
+ m_output << m_indent << parentWidget << "->addWindow(" << varName << ");\n";
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWizard"))) {
+ addWizardPage(varName, node, parentWidget);
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBox"))) {
+ QString icon;
+ if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) {
+ icon += QLatin1String(", ") ;
+ icon += iconCall(picon);
+ }
+
+ const DomProperty *plabel = attributes.value(QLatin1String("label"));
+ DomString *plabelString = plabel ? plabel->elementString() : 0;
+
+ m_output << m_indent << parentWidget << "->addItem(" << varName << icon << ", " << noTrCall(plabelString, pageDefaultString) << ");\n";
+
+ autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget << "->setItemText("
+ << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(plabelString, pageDefaultString) << ");\n";
+
+#ifndef QT_NO_TOOLTIP
+ if (DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
+ autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setItemToolTip("
+ << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n";
+ }
+#endif // QT_NO_TOOLTIP
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QTabWidget"))) {
+ QString icon;
+ if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) {
+ icon += QLatin1String(", ");
+ icon += iconCall(picon);
+ }
+
+ const DomProperty *ptitle = attributes.value(QLatin1String("title"));
+ DomString *ptitleString = ptitle ? ptitle->elementString() : 0;
+
+ m_output << m_indent << parentWidget << "->addTab(" << varName << icon << ", " << "QString());\n";
+
+ autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTabText("
+ << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptitleString, pageDefaultString) << ");\n";
+
+#ifndef QT_NO_TOOLTIP
+ if (const DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) {
+ autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setTabToolTip("
+ << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n";
+ }
+#endif // QT_NO_TOOLTIP
+#ifndef QT_NO_WHATSTHIS
+ if (const DomProperty *pwhatsThis = attributes.value(QLatin1String("whatsThis"))) {
+ autoTrOutput(pwhatsThis->elementString()) << m_indent << parentWidget << "->setTabWhatsThis("
+ << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(pwhatsThis->elementString()) << ");\n";
+ }
+#endif // QT_NO_WHATSTHIS
+ } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("Q3Wizard"))) {
+ const DomProperty *ptitle = attributes.value(QLatin1String("title"));
+ DomString *ptitleString = ptitle ? ptitle->elementString() : 0;
+
+ m_output << m_indent << parentWidget << "->addPage(" << varName << ", " << noTrCall(ptitleString, pageDefaultString) << ");\n";
+
+ autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTitle("
+ << varName << ", " << autoTrCall(ptitleString, pageDefaultString) << ");\n";
+
+ }
+
+ //
+ // Special handling for qtableview/qtreeview fake header attributes
+ //
+ static QStringList realPropertyNames =
+ (QStringList() << QLatin1String("visible")
+ << QLatin1String("cascadingSectionResizes")
+ << QLatin1String("defaultSectionSize")
+ << QLatin1String("highlightSections")
+ << QLatin1String("minimumSectionSize")
+ << QLatin1String("showSortIndicator")
+ << QLatin1String("stretchLastSection"));
+
+ if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeView"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) {
+ DomPropertyList headerProperties;
+ foreach (const QString &realPropertyName, realPropertyNames) {
+ const QString upperPropertyName = realPropertyName.at(0).toUpper()
+ + realPropertyName.mid(1);
+ const QString fakePropertyName = QLatin1String("header") + upperPropertyName;
+ if (DomProperty *fakeProperty = attributes.value(fakePropertyName)) {
+ fakeProperty->setAttributeName(realPropertyName);
+ headerProperties << fakeProperty;
+ }
+ }
+ writeProperties(varName + QLatin1String("->header()"), QLatin1String("QHeaderView"),
+ headerProperties, WritePropertyIgnoreObjectName);
+
+ } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableView"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) {
+
+ static QStringList headerPrefixes =
+ (QStringList() << QLatin1String("horizontalHeader")
+ << QLatin1String("verticalHeader"));
+
+ foreach (const QString &headerPrefix, headerPrefixes) {
+ DomPropertyList headerProperties;
+ foreach (const QString &realPropertyName, realPropertyNames) {
+ const QString upperPropertyName = realPropertyName.at(0).toUpper()
+ + realPropertyName.mid(1);
+ const QString fakePropertyName = headerPrefix + upperPropertyName;
+ if (DomProperty *fakeProperty = attributes.value(fakePropertyName)) {
+ fakeProperty->setAttributeName(realPropertyName);
+ headerProperties << fakeProperty;
+ }
+ }
+ writeProperties(varName + QLatin1String("->") + headerPrefix + QLatin1String("()"),
+ QLatin1String("QHeaderView"),
+ headerProperties, WritePropertyIgnoreObjectName);
+ }
+ }
+
+ if (node->elementLayout().isEmpty())
+ m_layoutChain.pop();
+
+ const QStringList zOrder = node->elementZOrder();
+ for (int i = 0; i < zOrder.size(); ++i) {
+ const QString name = zOrder.at(i);
+
+ if (!m_registeredWidgets.contains(name)) {
+ fprintf(stderr, "%s: Warning: Z-order assignment: '%s' is not a valid widget.\n",
+ qPrintable(m_option.messagePrefix()),
+ name.toLatin1().data());
+ continue;
+ }
+
+ if (name.isEmpty()) {
+ continue;
+ }
+
+ m_output << m_indent << name << "->raise();\n";
+ }
+}
+
+void WriteInitialization::addButtonGroup(const DomWidget *buttonNode, const QString &varName)
+{
+ const DomPropertyMap attributes = propertyMap(buttonNode->elementAttribute());
+ // Look up the button group name as specified in the attribute and find the uniquified name
+ const DomProperty *prop = attributes.value(QLatin1String("buttonGroup"));
+ if (!prop)
+ return;
+ const QString attributeName = toString(prop->elementString());
+ const DomButtonGroup *group = m_driver->findButtonGroup(attributeName);
+ // Legacy feature: Create missing groups on the fly as the UIC button group feature
+ // was present before the actual Designer support (4.5)
+ const bool createGroupOnTheFly = group == 0;
+ if (createGroupOnTheFly) {
+ DomButtonGroup *newGroup = new DomButtonGroup;
+ newGroup->setAttributeName(attributeName);
+ group = newGroup;
+ fprintf(stderr, "%s: Warning: Creating button group `%s'\n",
+ qPrintable(m_option.messagePrefix()),
+ attributeName.toLatin1().data());
+ }
+ const QString groupName = m_driver->findOrInsertButtonGroup(group);
+ // Create on demand
+ if (!m_buttonGroups.contains(groupName)) {
+ const QString className = QLatin1String("QButtonGroup");
+ m_output << m_indent;
+ if (createGroupOnTheFly)
+ m_output << className << " *";
+ m_output << groupName << " = new " << className << '(' << m_mainFormVarName << ");\n";
+ m_buttonGroups.insert(groupName);
+ writeProperties(groupName, className, group->elementProperty());
+ }
+ m_output << m_indent << groupName << "->addButton(" << varName << ");\n";
+}
+
+void WriteInitialization::acceptLayout(DomLayout *node)
+{
+ const QString className = node->attributeClass();
+ const QString varName = m_driver->findOrInsertLayout(node);
+
+ const DomPropertyMap properties = propertyMap(node->elementProperty());
+ const bool oldLayoutProperties = properties.constFind(QLatin1String("margin")) != properties.constEnd();
+
+ bool isGroupBox = false;
+
+ if (m_widgetChain.top()) {
+ const QString parentWidget = m_widgetChain.top()->attributeClass();
+
+ if (!m_layoutChain.top() && (m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3GroupBox"))
+ || m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3ButtonGroup")))) {
+ const QString parent = m_driver->findOrInsertWidget(m_widgetChain.top());
+
+ isGroupBox = true;
+ // special case for group box
+
+ m_output << m_indent << parent << "->setColumnLayout(0, Qt::Vertical);\n";
+ QString objectName = parent;
+ objectName += QLatin1String("->layout()");
+ int marginType = Use43UiFile;
+ if (oldLayoutProperties)
+ marginType = m_layoutMarginType;
+
+ m_LayoutDefaultHandler.writeProperties(m_indent,
+ objectName, properties, marginType, false, m_output);
+ }
+ }
+
+ m_output << m_indent << varName << " = new " << className << '(';
+
+ if (!m_layoutChain.top() && !isGroupBox)
+ m_output << m_driver->findOrInsertWidget(m_widgetChain.top());
+
+ m_output << ");\n";
+
+ if (isGroupBox) {
+ const QString tempName = m_driver->unique(QLatin1String("boxlayout"));
+ m_output << m_indent << "QBoxLayout *" << tempName << " = qobject_cast<QBoxLayout *>(" <<
+ m_driver->findOrInsertWidget(m_widgetChain.top()) << "->layout());\n";
+ m_output << m_indent << "if (" << tempName << ")\n";
+ m_output << m_dindent << tempName << "->addLayout(" << varName << ");\n";
+ }
+
+ if (isGroupBox) {
+ m_output << m_indent << varName << "->setAlignment(Qt::AlignTop);\n";
+ } else {
+ // Suppress margin on a read child layout
+ const bool suppressMarginDefault = m_layoutChain.top();
+ int marginType = Use43UiFile;
+ if (oldLayoutProperties)
+ marginType = m_layoutMarginType;
+ m_LayoutDefaultHandler.writeProperties(m_indent, varName, properties, marginType, suppressMarginDefault, m_output);
+ }
+
+ m_layoutMarginType = SubLayoutMargin;
+
+ DomPropertyList propList = node->elementProperty();
+ if (m_layoutWidget) {
+ bool left, top, right, bottom;
+ left = top = right = bottom = false;
+ for (int i = 0; i < propList.size(); ++i) {
+ const DomProperty *p = propList.at(i);
+ const QString propertyName = p->attributeName();
+ if (propertyName == QLatin1String("leftMargin") && p->kind() == DomProperty::Number)
+ left = true;
+ else if (propertyName == QLatin1String("topMargin") && p->kind() == DomProperty::Number)
+ top = true;
+ else if (propertyName == QLatin1String("rightMargin") && p->kind() == DomProperty::Number)
+ right = true;
+ else if (propertyName == QLatin1String("bottomMargin") && p->kind() == DomProperty::Number)
+ bottom = true;
+ }
+ if (!left) {
+ DomProperty *p = new DomProperty();
+ p->setAttributeName(QLatin1String("leftMargin"));
+ p->setElementNumber(0);
+ propList.append(p);
+ }
+ if (!top) {
+ DomProperty *p = new DomProperty();
+ p->setAttributeName(QLatin1String("topMargin"));
+ p->setElementNumber(0);
+ propList.append(p);
+ }
+ if (!right) {
+ DomProperty *p = new DomProperty();
+ p->setAttributeName(QLatin1String("rightMargin"));
+ p->setElementNumber(0);
+ propList.append(p);
+ }
+ if (!bottom) {
+ DomProperty *p = new DomProperty();
+ p->setAttributeName(QLatin1String("bottomMargin"));
+ p->setElementNumber(0);
+ propList.append(p);
+ }
+ m_layoutWidget = false;
+ }
+
+ writeProperties(varName, className, propList, WritePropertyIgnoreMargin|WritePropertyIgnoreSpacing);
+
+ m_layoutChain.push(node);
+ TreeWalker::acceptLayout(node);
+ m_layoutChain.pop();
+
+ // Stretch? (Unless we are compiling for UIC3)
+ const QString numberNull = QString(QLatin1Char('0'));
+ writePropertyList(varName, QLatin1String("setStretch"), node->attributeStretch(), numberNull);
+ writePropertyList(varName, QLatin1String("setRowStretch"), node->attributeRowStretch(), numberNull);
+ writePropertyList(varName, QLatin1String("setColumnStretch"), node->attributeColumnStretch(), numberNull);
+ writePropertyList(varName, QLatin1String("setColumnMinimumWidth"), node->attributeColumnMinimumWidth(), numberNull);
+ writePropertyList(varName, QLatin1String("setRowMinimumHeight"), node->attributeRowMinimumHeight(), numberNull);
+}
+
+// Apply a comma-separated list of values using a function "setSomething(int idx, value)"
+void WriteInitialization::writePropertyList(const QString &varName,
+ const QString &setFunction,
+ const QString &value,
+ const QString &defaultValue)
+{
+ if (value.isEmpty())
+ return;
+ const QStringList list = value.split(QLatin1Char(','));
+ const int count = list.count();
+ for (int i = 0; i < count; i++)
+ if (list.at(i) != defaultValue)
+ m_output << m_indent << varName << "->" << setFunction << '(' << i << ", " << list.at(i) << ");\n";
+}
+
+void WriteInitialization::acceptSpacer(DomSpacer *node)
+{
+ m_output << m_indent << m_driver->findOrInsertSpacer(node) << " = ";
+ writeSpacerItem(node, m_output);
+ m_output << ";\n";
+}
+
+static inline QString formLayoutRole(int column, int colspan)
+{
+ if (colspan > 1)
+ return QLatin1String("QFormLayout::SpanningRole");
+ return column == 0 ? QLatin1String("QFormLayout::LabelRole") : QLatin1String("QFormLayout::FieldRole");
+}
+
+void WriteInitialization::acceptLayoutItem(DomLayoutItem *node)
+{
+ TreeWalker::acceptLayoutItem(node);
+
+ DomLayout *layout = m_layoutChain.top();
+
+ if (!layout)
+ return;
+
+ const QString layoutName = m_driver->findOrInsertLayout(layout);
+ const QString itemName = m_driver->findOrInsertLayoutItem(node);
+
+ QString addArgs;
+ QString methodPrefix = QLatin1String("add"); //Consistent API-design galore!
+ if (layout->attributeClass() == QLatin1String("QGridLayout")) {
+ const int row = node->attributeRow();
+ const int col = node->attributeColumn();
+
+ const int rowSpan = node->hasAttributeRowSpan() ? node->attributeRowSpan() : 1;
+ const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
+
+ addArgs = QString::fromLatin1("%1, %2, %3, %4, %5").arg(itemName).arg(row).arg(col).arg(rowSpan).arg(colSpan);
+ if (!node->attributeAlignment().isEmpty())
+ addArgs += QLatin1String(", ") + node->attributeAlignment();
+ } else {
+ if (layout->attributeClass() == QLatin1String("QFormLayout")) {
+ methodPrefix = QLatin1String("set");
+ const int row = node->attributeRow();
+ const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1;
+ const QString role = formLayoutRole(node->attributeColumn(), colSpan);
+ addArgs = QString::fromLatin1("%1, %2, %3").arg(row).arg(role).arg(itemName);
+ } else {
+ addArgs = itemName;
+ if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty())
+ addArgs += QLatin1String(", 0, ") + node->attributeAlignment();
+ }
+ }
+
+ // figure out "add" method
+ m_output << "\n" << m_indent << layoutName << "->";
+ switch (node->kind()) {
+ case DomLayoutItem::Widget:
+ m_output << methodPrefix << "Widget(" << addArgs;
+ break;
+ case DomLayoutItem::Layout:
+ m_output << methodPrefix << "Layout(" << addArgs;
+ break;
+ case DomLayoutItem::Spacer:
+ m_output << methodPrefix << "Item(" << addArgs;
+ break;
+ case DomLayoutItem::Unknown:
+ Q_ASSERT( 0 );
+ break;
+ }
+ m_output << ");\n\n";
+}
+
+void WriteInitialization::acceptActionGroup(DomActionGroup *node)
+{
+ const QString actionName = m_driver->findOrInsertActionGroup(node);
+ QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
+
+ if (m_actionGroupChain.top())
+ varName = m_driver->findOrInsertActionGroup(m_actionGroupChain.top());
+
+ m_output << m_indent << actionName << " = new QActionGroup(" << varName << ");\n";
+ writeProperties(actionName, QLatin1String("QActionGroup"), node->elementProperty());
+
+ m_actionGroupChain.push(node);
+ TreeWalker::acceptActionGroup(node);
+ m_actionGroupChain.pop();
+}
+
+void WriteInitialization::acceptAction(DomAction *node)
+{
+ if (node->hasAttributeMenu())
+ return;
+
+ const QString actionName = m_driver->findOrInsertAction(node);
+ m_registeredActions.insert(actionName, node);
+ QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
+
+ if (m_actionGroupChain.top())
+ varName = m_driver->findOrInsertActionGroup(m_actionGroupChain.top());
+
+ m_output << m_indent << actionName << " = new QAction(" << varName << ");\n";
+ writeProperties(actionName, QLatin1String("QAction"), node->elementProperty());
+}
+
+void WriteInitialization::acceptActionRef(DomActionRef *node)
+{
+ QString actionName = node->attributeName();
+ const bool isSeparator = actionName == QLatin1String("separator");
+ bool isMenu = false;
+
+ QString varName = m_driver->findOrInsertWidget(m_widgetChain.top());
+
+ if (actionName.isEmpty() || !m_widgetChain.top()) {
+ return;
+ } else if (m_driver->actionGroupByName(actionName)) {
+ return;
+ } else if (DomWidget *w = m_driver->widgetByName(actionName)) {
+ isMenu = m_uic->isMenu(w->attributeClass());
+ bool inQ3ToolBar = m_uic->customWidgetsInfo()->extends(m_widgetChain.top()->attributeClass(), QLatin1String("Q3ToolBar"));
+ if (!isMenu && inQ3ToolBar) {
+ m_actionOut << m_indent << actionName << "->setParent(" << varName << ");\n";
+ return;
+ }
+ } else if (!(m_driver->actionByName(actionName) || isSeparator)) {
+ fprintf(stderr, "%s: Warning: action `%s' not declared\n",
+ qPrintable(m_option.messagePrefix()),
+ actionName.toLatin1().data());
+ return;
+ }
+
+ if (m_widgetChain.top() && isSeparator) {
+ // separator is always reserved!
+ m_actionOut << m_indent << varName << "->addSeparator();\n";
+ return;
+ }
+
+ if (isMenu)
+ actionName += QLatin1String("->menuAction()");
+
+ m_actionOut << m_indent << varName << "->addAction(" << actionName << ");\n";
+}
+
+void WriteInitialization::writeProperties(const QString &varName,
+ const QString &className,
+ const DomPropertyList &lst,
+ unsigned flags)
+{
+ const bool isTopLevel = m_widgetChain.count() == 1;
+
+ if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
+ DomPropertyMap properties = propertyMap(lst);
+ if (properties.contains(QLatin1String("control"))) {
+ DomProperty *p = properties.value(QLatin1String("control"));
+ m_output << m_indent << varName << "->setControl(QString::fromUtf8("
+ << fixString(toString(p->elementString()), m_dindent) << "));\n";
+ }
+ }
+
+ DomWidget *buttonGroupWidget = findWidget(QLatin1String("Q3ButtonGroup"));
+
+ QString indent;
+ if (!m_widgetChain.top()) {
+ indent = m_option.indent;
+ m_output << m_indent << "if (" << varName << "->objectName().isEmpty())\n";
+ }
+ if (!(flags & WritePropertyIgnoreObjectName))
+ m_output << m_indent << indent << varName
+ << "->setObjectName(QString::fromUtf8(" << fixString(varName, m_dindent) << "));\n";
+
+ int leftMargin, topMargin, rightMargin, bottomMargin;
+ leftMargin = topMargin = rightMargin = bottomMargin = -1;
+ bool frameShadowEncountered = false;
+
+ for (int i=0; i<lst.size(); ++i) {
+ const DomProperty *p = lst.at(i);
+ if (!checkProperty(m_option.inputFile, p))
+ continue;
+ const QString propertyName = p->attributeName();
+ QString propertyValue;
+
+ // special case for the property `geometry': Do not use position
+ if (isTopLevel && propertyName == QLatin1String("geometry") && p->elementRect()) {
+ const DomRect *r = p->elementRect();
+ m_output << m_indent << varName << "->resize(" << r->elementWidth() << ", " << r->elementHeight() << ");\n";
+ continue;
+ } else if (propertyName == QLatin1String("buttonGroupId")) { // Q3ButtonGroup support
+ if (buttonGroupWidget)
+ m_output << m_indent << m_driver->findOrInsertWidget(buttonGroupWidget) << "->insert("
+ << varName << ", " << p->elementNumber() << ");\n";
+ continue;
+ } else if (propertyName == QLatin1String("currentRow") // QListWidget::currentRow
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) {
+ m_delayedOut << m_indent << varName << "->setCurrentRow("
+ << p->elementNumber() << ");\n";
+ continue;
+ } else if (propertyName == QLatin1String("currentIndex") // set currentIndex later
+ && (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTabWidget"))
+ || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))) {
+ m_delayedOut << m_indent << varName << "->setCurrentIndex("
+ << p->elementNumber() << ");\n";
+ continue;
+ } else if (propertyName == QLatin1String("tabSpacing")
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))) {
+ m_delayedOut << m_indent << varName << "->layout()->setSpacing("
+ << p->elementNumber() << ");\n";
+ continue;
+ } else if (propertyName == QLatin1String("control") // ActiveQt support
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QAxWidget"))) {
+ // already done ;)
+ continue;
+ } else if (propertyName == QLatin1String("database")
+ && p->elementStringList()) {
+ // Sql support
+ continue;
+ } else if (propertyName == QLatin1String("frameworkCode")
+ && p->kind() == DomProperty::Bool) {
+ // Sql support
+ continue;
+ } else if (propertyName == QLatin1String("orientation")
+ && m_uic->customWidgetsInfo()->extends(className, QLatin1String("Line"))) {
+ // Line support
+ QString shape = QLatin1String("QFrame::HLine");
+ if (p->elementEnum() == QLatin1String("Qt::Vertical"))
+ shape = QLatin1String("QFrame::VLine");
+
+ m_output << m_indent << varName << "->setFrameShape(" << shape << ");\n";
+ // QFrame Default is 'Plain'. Make the line 'Sunken' unless otherwise specified
+ if (!frameShadowEncountered)
+ m_output << m_indent << varName << "->setFrameShadow(QFrame::Sunken);\n";
+ continue;
+ } else if ((flags & WritePropertyIgnoreMargin) && propertyName == QLatin1String("margin")) {
+ continue;
+ } else if ((flags & WritePropertyIgnoreSpacing) && propertyName == QLatin1String("spacing")) {
+ continue;
+ } else if (propertyName == QLatin1String("leftMargin") && p->kind() == DomProperty::Number) {
+ leftMargin = p->elementNumber();
+ continue;
+ } else if (propertyName == QLatin1String("topMargin") && p->kind() == DomProperty::Number) {
+ topMargin = p->elementNumber();
+ continue;
+ } else if (propertyName == QLatin1String("rightMargin") && p->kind() == DomProperty::Number) {
+ rightMargin = p->elementNumber();
+ continue;
+ } else if (propertyName == QLatin1String("bottomMargin") && p->kind() == DomProperty::Number) {
+ bottomMargin = p->elementNumber();
+ continue;
+ } else if (propertyName == QLatin1String("frameShadow"))
+ frameShadowEncountered = true;
+
+ bool stdset = m_stdsetdef;
+ if (p->hasAttributeStdset())
+ stdset = p->attributeStdset();
+
+ QString setFunction;
+
+ if (stdset) {
+ setFunction = QLatin1String("->set");
+ setFunction += propertyName.left(1).toUpper();
+ setFunction += propertyName.mid(1);
+ setFunction += QLatin1Char('(');
+ } else {
+ setFunction = QLatin1String("->setProperty(\"");
+ setFunction += propertyName;
+ setFunction += QLatin1String("\", QVariant(");
+ }
+
+ QString varNewName = varName;
+
+ switch (p->kind()) {
+ case DomProperty::Bool: {
+ propertyValue = p->elementBool();
+ break;
+ }
+ case DomProperty::Color:
+ propertyValue = domColor2QString(p->elementColor());
+ break;
+ case DomProperty::Cstring:
+ if (propertyName == QLatin1String("buddy") && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QLabel"))) {
+ m_buddies.append(Buddy(varName, p->elementCstring()));
+ } else {
+ if (stdset)
+ propertyValue = fixString(p->elementCstring(), m_dindent);
+ else {
+ propertyValue = QLatin1String("QByteArray(");
+ propertyValue += fixString(p->elementCstring(), m_dindent);
+ propertyValue += QLatin1Char(')');
+ }
+ }
+ break;
+ case DomProperty::Cursor:
+ propertyValue = QString::fromLatin1("QCursor(static_cast<Qt::CursorShape>(%1))")
+ .arg(p->elementCursor());
+ break;
+ case DomProperty::CursorShape:
+ if (p->hasAttributeStdset() && !p->attributeStdset())
+ varNewName += QLatin1String("->viewport()");
+ propertyValue = QString::fromLatin1("QCursor(Qt::%1)")
+ .arg(p->elementCursorShape());
+ break;
+ case DomProperty::Enum:
+ propertyValue = p->elementEnum();
+ if (!propertyValue.contains(QLatin1String("::"))) {
+ QString scope = className;
+ scope += QLatin1String("::");
+ propertyValue.prepend(scope);
+ }
+ break;
+ case DomProperty::Set:
+ propertyValue = p->elementSet();
+ break;
+ case DomProperty::Font:
+ propertyValue = writeFontProperties(p->elementFont());
+ break;
+ case DomProperty::IconSet:
+ propertyValue = writeIconProperties(p->elementIconSet());
+ break;
+ case DomProperty::Pixmap:
+ propertyValue = pixCall(p);
+ break;
+ case DomProperty::Palette: {
+ const DomPalette *pal = p->elementPalette();
+ const QString paletteName = m_driver->unique(QLatin1String("palette"));
+ m_output << m_indent << "QPalette " << paletteName << ";\n";
+
+ writeColorGroup(pal->elementActive(), QLatin1String("QPalette::Active"), paletteName);
+ writeColorGroup(pal->elementInactive(), QLatin1String("QPalette::Inactive"), paletteName);
+ writeColorGroup(pal->elementDisabled(), QLatin1String("QPalette::Disabled"), paletteName);
+
+ propertyValue = paletteName;
+ break;
+ }
+ case DomProperty::Point: {
+ const DomPoint *po = p->elementPoint();
+ propertyValue = QString::fromLatin1("QPoint(%1, %2)")
+ .arg(po->elementX()).arg(po->elementY());
+ break;
+ }
+ case DomProperty::PointF: {
+ const DomPointF *pof = p->elementPointF();
+ propertyValue = QString::fromLatin1("QPointF(%1, %2)")
+ .arg(pof->elementX()).arg(pof->elementY());
+ break;
+ }
+ case DomProperty::Rect: {
+ const DomRect *r = p->elementRect();
+ propertyValue = QString::fromLatin1("QRect(%1, %2, %3, %4)")
+ .arg(r->elementX()).arg(r->elementY())
+ .arg(r->elementWidth()).arg(r->elementHeight());
+ break;
+ }
+ case DomProperty::RectF: {
+ const DomRectF *rf = p->elementRectF();
+ propertyValue = QString::fromLatin1("QRectF(%1, %2, %3, %4)")
+ .arg(rf->elementX()).arg(rf->elementY())
+ .arg(rf->elementWidth()).arg(rf->elementHeight());
+ break;
+ }
+ case DomProperty::Locale: {
+ const DomLocale *locale = p->elementLocale();
+ propertyValue = QString::fromLatin1("QLocale(QLocale::%1, QLocale::%2)")
+ .arg(locale->attributeLanguage()).arg(locale->attributeCountry());
+ break;
+ }
+ case DomProperty::SizePolicy: {
+ const QString spName = writeSizePolicy( p->elementSizePolicy());
+ m_output << m_indent << spName << QString::fromLatin1(
+ ".setHeightForWidth(%1->sizePolicy().hasHeightForWidth());\n")
+ .arg(varName);
+
+ propertyValue = spName;
+ break;
+ }
+ case DomProperty::Size: {
+ const DomSize *s = p->elementSize();
+ propertyValue = QString::fromLatin1("QSize(%1, %2)")
+ .arg(s->elementWidth()).arg(s->elementHeight());
+ break;
+ }
+ case DomProperty::SizeF: {
+ const DomSizeF *sf = p->elementSizeF();
+ propertyValue = QString::fromLatin1("QSizeF(%1, %2)")
+ .arg(sf->elementWidth()).arg(sf->elementHeight());
+ break;
+ }
+ case DomProperty::String: {
+ if (propertyName == QLatin1String("objectName")) {
+ const QString v = p->elementString()->text();
+ if (v == varName)
+ break;
+
+ // ### qWarning("Deprecated: the property `objectName' is different from the variable name");
+ }
+
+ propertyValue = autoTrCall(p->elementString());
+ break;
+ }
+ case DomProperty::Number:
+ propertyValue = QString::number(p->elementNumber());
+ break;
+ case DomProperty::UInt:
+ propertyValue = QString::number(p->elementUInt());
+ propertyValue += QLatin1Char('u');
+ break;
+ case DomProperty::LongLong:
+ propertyValue = QLatin1String("Q_INT64_C(");
+ propertyValue += QString::number(p->elementLongLong());
+ propertyValue += QLatin1Char(')');;
+ break;
+ case DomProperty::ULongLong:
+ propertyValue = QLatin1String("Q_UINT64_C(");
+ propertyValue += QString::number(p->elementULongLong());
+ propertyValue += QLatin1Char(')');
+ break;
+ case DomProperty::Float:
+ propertyValue = QString::number(p->elementFloat());
+ break;
+ case DomProperty::Double:
+ propertyValue = QString::number(p->elementDouble());
+ break;
+ case DomProperty::Char: {
+ const DomChar *c = p->elementChar();
+ propertyValue = QString::fromLatin1("QChar(%1)")
+ .arg(c->elementUnicode());
+ break;
+ }
+ case DomProperty::Date: {
+ const DomDate *d = p->elementDate();
+ propertyValue = QString::fromLatin1("QDate(%1, %2, %3)")
+ .arg(d->elementYear())
+ .arg(d->elementMonth())
+ .arg(d->elementDay());
+ break;
+ }
+ case DomProperty::Time: {
+ const DomTime *t = p->elementTime();
+ propertyValue = QString::fromLatin1("QTime(%1, %2, %3)")
+ .arg(t->elementHour())
+ .arg(t->elementMinute())
+ .arg(t->elementSecond());
+ break;
+ }
+ case DomProperty::DateTime: {
+ const DomDateTime *dt = p->elementDateTime();
+ propertyValue = QString::fromLatin1("QDateTime(QDate(%1, %2, %3), QTime(%4, %5, %6))")
+ .arg(dt->elementYear())
+ .arg(dt->elementMonth())
+ .arg(dt->elementDay())
+ .arg(dt->elementHour())
+ .arg(dt->elementMinute())
+ .arg(dt->elementSecond());
+ break;
+ }
+ case DomProperty::StringList:
+ propertyValue = QLatin1String("QStringList()");
+ if (p->elementStringList()->elementString().size()) {
+ const QStringList lst = p->elementStringList()->elementString();
+ for (int i=0; i<lst.size(); ++i) {
+ propertyValue += QLatin1String(" << QString::fromUtf8(");
+ propertyValue += fixString(lst.at(i), m_dindent);
+ propertyValue += QLatin1Char(')');
+ }
+ }
+ break;
+
+ case DomProperty::Url: {
+ const DomUrl* u = p->elementUrl();
+ propertyValue = QString::fromLatin1("QUrl(%1)")
+ .arg(fixString(u->elementString()->text(), m_dindent));
+ break;
+ }
+ case DomProperty::Brush:
+ propertyValue = writeBrushInitialization(p->elementBrush());
+ break;
+ case DomProperty::Unknown:
+ break;
+ }
+
+ if (propertyValue.size()) {
+ const char* defineC = 0;
+ if (propertyName == QLatin1String("toolTip"))
+ defineC = toolTipDefineC;
+ else if (propertyName == QLatin1String("whatsThis"))
+ defineC = whatsThisDefineC;
+ else if (propertyName == QLatin1String("statusTip"))
+ defineC = statusTipDefineC;
+ else if (propertyName == QLatin1String("accessibleName") || propertyName == QLatin1String("accessibleDescription"))
+ defineC = accessibilityDefineC;
+
+ QTextStream &o = autoTrOutput(p->elementString());
+
+ if (defineC)
+ openIfndef(o, QLatin1String(defineC));
+ o << m_indent << varNewName << setFunction << propertyValue;
+ if (!stdset)
+ o << ')';
+ o << ");\n";
+ if (defineC)
+ closeIfndef(o, QLatin1String(defineC));
+
+ if (varName == m_mainFormVarName && &o == &m_refreshOut) {
+ // this is the only place (currently) where we output mainForm name to the retranslateUi().
+ // Other places output merely instances of a certain class (which cannot be main form, e.g. QListWidget).
+ m_mainFormUsedInRetranslateUi = true;
+ }
+ }
+ }
+ if (leftMargin != -1 || topMargin != -1 || rightMargin != -1 || bottomMargin != -1) {
+ QString objectName = varName;
+ if (m_widgetChain.top()) {
+ const QString parentWidget = m_widgetChain.top()->attributeClass();
+
+ if (!m_layoutChain.top() && (m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3GroupBox"))
+ || m_uic->customWidgetsInfo()->extends(parentWidget, QLatin1String("Q3ButtonGroup")))) {
+ objectName = m_driver->findOrInsertWidget(m_widgetChain.top()) + QLatin1String("->layout()");
+ }
+ }
+ m_output << m_indent << objectName << QLatin1String("->setContentsMargins(")
+ << leftMargin << QLatin1String(", ")
+ << topMargin << QLatin1String(", ")
+ << rightMargin << QLatin1String(", ")
+ << bottomMargin << QLatin1String(");\n");
+ }
+}
+
+QString WriteInitialization::writeSizePolicy(const DomSizePolicy *sp)
+{
+
+ // check cache
+ const SizePolicyHandle sizePolicyHandle(sp);
+ const SizePolicyNameMap::const_iterator it = m_sizePolicyNameMap.constFind(sizePolicyHandle);
+ if ( it != m_sizePolicyNameMap.constEnd()) {
+ return it.value();
+ }
+
+
+ // insert with new name
+ const QString spName = m_driver->unique(QLatin1String("sizePolicy"));
+ m_sizePolicyNameMap.insert(sizePolicyHandle, spName);
+
+ m_output << m_indent << "QSizePolicy " << spName;
+ do {
+ if (sp->hasElementHSizeType() && sp->hasElementVSizeType()) {
+ m_output << "(static_cast<QSizePolicy::Policy>(" << sp->elementHSizeType()
+ << "), static_cast<QSizePolicy::Policy>(" << sp->elementVSizeType() << "));\n";
+ break;
+ }
+ if (sp->hasAttributeHSizeType() && sp->hasAttributeVSizeType()) {
+ m_output << "(QSizePolicy::" << sp->attributeHSizeType() << ", QSizePolicy::"
+ << sp->attributeVSizeType() << ");\n";
+ break;
+ }
+ m_output << ";\n";
+ } while (false);
+
+ m_output << m_indent << spName << ".setHorizontalStretch("
+ << sp->elementHorStretch() << ");\n";
+ m_output << m_indent << spName << ".setVerticalStretch("
+ << sp->elementVerStretch() << ");\n";
+ return spName;
+}
+// Check for a font with the given properties in the FontPropertiesNameMap
+// or create a new one. Returns the name.
+
+QString WriteInitialization::writeFontProperties(const DomFont *f)
+{
+ // check cache
+ const FontHandle fontHandle(f);
+ const FontPropertiesNameMap::const_iterator it = m_fontPropertiesNameMap.constFind(fontHandle);
+ if ( it != m_fontPropertiesNameMap.constEnd()) {
+ return it.value();
+ }
+
+ // insert with new name
+ const QString fontName = m_driver->unique(QLatin1String("font"));
+ m_fontPropertiesNameMap.insert(FontHandle(f), fontName);
+
+ m_output << m_indent << "QFont " << fontName << ";\n";
+ if (f->hasElementFamily() && !f->elementFamily().isEmpty()) {
+ m_output << m_indent << fontName << ".setFamily(QString::fromUtf8(" << fixString(f->elementFamily(), m_dindent)
+ << "));\n";
+ }
+ if (f->hasElementPointSize() && f->elementPointSize() > 0) {
+ m_output << m_indent << fontName << ".setPointSize(" << f->elementPointSize()
+ << ");\n";
+ }
+
+ if (f->hasElementBold()) {
+ m_output << m_indent << fontName << ".setBold("
+ << (f->elementBold() ? "true" : "false") << ");\n";
+ }
+ if (f->hasElementItalic()) {
+ m_output << m_indent << fontName << ".setItalic("
+ << (f->elementItalic() ? "true" : "false") << ");\n";
+ }
+ if (f->hasElementUnderline()) {
+ m_output << m_indent << fontName << ".setUnderline("
+ << (f->elementUnderline() ? "true" : "false") << ");\n";
+ }
+ if (f->hasElementWeight() && f->elementWeight() > 0) {
+ m_output << m_indent << fontName << ".setWeight("
+ << f->elementWeight() << ");" << endl;
+ }
+ if (f->hasElementStrikeOut()) {
+ m_output << m_indent << fontName << ".setStrikeOut("
+ << (f->elementStrikeOut() ? "true" : "false") << ");\n";
+ }
+ if (f->hasElementKerning()) {
+ m_output << m_indent << fontName << ".setKerning("
+ << (f->elementKerning() ? "true" : "false") << ");\n";
+ }
+ if (f->hasElementAntialiasing()) {
+ m_output << m_indent << fontName << ".setStyleStrategy("
+ << (f->elementAntialiasing() ? "QFont::PreferDefault" : "QFont::NoAntialias") << ");\n";
+ }
+ if (f->hasElementStyleStrategy()) {
+ m_output << m_indent << fontName << ".setStyleStrategy(QFont::"
+ << f->elementStyleStrategy() << ");\n";
+ }
+ return fontName;
+}
+
+// Post 4.4 write resource icon
+static void writeResourceIcon(QTextStream &output,
+ const QString &iconName,
+ const QString &indent,
+ const DomResourceIcon *i)
+{
+ if (i->hasElementNormalOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOff()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::Off);\n";
+ if (i->hasElementNormalOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementNormalOn()->text(), indent) << "), QSize(), QIcon::Normal, QIcon::On);\n";
+ if (i->hasElementDisabledOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOff()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::Off);\n";
+ if (i->hasElementDisabledOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementDisabledOn()->text(), indent) << "), QSize(), QIcon::Disabled, QIcon::On);\n";
+ if (i->hasElementActiveOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOff()->text(), indent) << "), QSize(), QIcon::Active, QIcon::Off);\n";
+ if (i->hasElementActiveOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementActiveOn()->text(), indent) << "), QSize(), QIcon::Active, QIcon::On);\n";
+ if (i->hasElementSelectedOff())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOff()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::Off);\n";
+ if (i->hasElementSelectedOn())
+ output << indent << iconName << ".addFile(QString::fromUtf8(" << fixString(i->elementSelectedOn()->text(), indent) << "), QSize(), QIcon::Selected, QIcon::On);\n";
+}
+
+QString WriteInitialization::writeIconProperties(const DomResourceIcon *i)
+{
+ // check cache
+ const IconHandle iconHandle(i);
+ const IconPropertiesNameMap::const_iterator it = m_iconPropertiesNameMap.constFind(iconHandle);
+ if (it != m_iconPropertiesNameMap.constEnd()) {
+ return it.value();
+ }
+
+ // insert with new name
+ const QString iconName = m_driver->unique(QLatin1String("icon"));
+ m_iconPropertiesNameMap.insert(IconHandle(i), iconName);
+ if (isIconFormat44(i)) {
+ if (i->attributeTheme().isEmpty()) {
+ // No theme: Write resource icon as is
+ m_output << m_indent << "QIcon " << iconName << ";\n";
+ writeResourceIcon(m_output, iconName, m_indent, i);
+ } else {
+ // Theme: Generate code to check the theme and default to resource
+ const QString themeIconName = fixString(i->attributeTheme(), QString());
+ if (iconHasStatePixmaps(i)) {
+ // Theme + default state pixmaps:
+ // Generate code to check the theme and default to state pixmaps
+ m_output << m_indent << "QIcon " << iconName << ";\n";
+ const char themeNameStringVariableC[] = "iconThemeName";
+ // Store theme name in a variable
+ m_output << m_indent;
+ if (m_firstThemeIcon) { // Declare variable string
+ m_output << "QString ";
+ m_firstThemeIcon = false;
+ }
+ m_output << themeNameStringVariableC << " = QString::fromUtf8("
+ << themeIconName << ");\n";
+ m_output << m_indent << "if (QIcon::hasThemeIcon("
+ << themeNameStringVariableC
+ << ")) {\n"
+ << m_dindent << iconName << " = QIcon::fromTheme(" << themeNameStringVariableC << ");\n"
+ << m_indent << "} else {\n";
+ writeResourceIcon(m_output, iconName, m_dindent, i);
+ m_output << m_indent << "}\n";
+ } else {
+ // Theme, but no state pixmaps: Construct from theme directly.
+ m_output << m_indent << "QIcon " << iconName
+ << "(QIcon::fromTheme(QString::fromUtf8("
+ << themeIconName << ")));\n";
+ } // Theme, but not state
+ } // >= 4.4
+ } else { // pre-4.4 legacy
+ m_output << m_indent << "const QIcon " << iconName << " = " << pixCall(QLatin1String("QIcon"), i->text())<< ";\n";
+ }
+ return iconName;
+}
+
+QString WriteInitialization::domColor2QString(const DomColor *c)
+{
+ if (c->hasAttributeAlpha())
+ return QString::fromLatin1("QColor(%1, %2, %3, %4)")
+ .arg(c->elementRed())
+ .arg(c->elementGreen())
+ .arg(c->elementBlue())
+ .arg(c->attributeAlpha());
+ return QString::fromLatin1("QColor(%1, %2, %3)")
+ .arg(c->elementRed())
+ .arg(c->elementGreen())
+ .arg(c->elementBlue());
+}
+
+void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QString &group, const QString &paletteName)
+{
+ if (!colorGroup)
+ return;
+
+ // old format
+ const QList<DomColor*> colors = colorGroup->elementColor();
+ for (int i=0; i<colors.size(); ++i) {
+ const DomColor *color = colors.at(i);
+
+ m_output << m_indent << paletteName << ".setColor(" << group
+ << ", " << "static_cast<QPalette::ColorRole>(" << QString::number(i) << ')'
+ << ", " << domColor2QString(color)
+ << ");\n";
+ }
+
+ // new format
+ const QList<DomColorRole *> colorRoles = colorGroup->elementColorRole();
+ QListIterator<DomColorRole *> itRole(colorRoles);
+ while (itRole.hasNext()) {
+ const DomColorRole *colorRole = itRole.next();
+ if (colorRole->hasAttributeRole()) {
+ const QString brushName = writeBrushInitialization(colorRole->elementBrush());
+ m_output << m_indent << paletteName << ".setBrush(" << group
+ << ", " << "QPalette::" << colorRole->attributeRole()
+ << ", " << brushName << ");\n";
+ }
+ }
+}
+
+// Write initialization for brush unless it is found in the cache. Returns the name to use
+// in an expression.
+QString WriteInitialization::writeBrushInitialization(const DomBrush *brush)
+{
+ // Simple solid, colored brushes are cached
+ const bool solidColoredBrush = !brush->hasAttributeBrushStyle() || brush->attributeBrushStyle() == QLatin1String("SolidPattern");
+ uint rgb = 0;
+ if (solidColoredBrush) {
+ if (const DomColor *color = brush->elementColor()) {
+ rgb = ((color->elementRed() & 0xFF) << 24) |
+ ((color->elementGreen() & 0xFF) << 16) |
+ ((color->elementBlue() & 0xFF) << 8) |
+ ((color->attributeAlpha() & 0xFF));
+ const ColorBrushHash::const_iterator cit = m_colorBrushHash.constFind(rgb);
+ if (cit != m_colorBrushHash.constEnd())
+ return cit.value();
+ }
+ }
+ // Create and enter into cache if simple
+ const QString brushName = m_driver->unique(QLatin1String("brush"));
+ writeBrush(brush, brushName);
+ if (solidColoredBrush)
+ m_colorBrushHash.insert(rgb, brushName);
+ return brushName;
+}
+
+void WriteInitialization::writeBrush(const DomBrush *brush, const QString &brushName)
+{
+ QString style = QLatin1String("SolidPattern");
+ if (brush->hasAttributeBrushStyle())
+ style = brush->attributeBrushStyle();
+
+ if (style == QLatin1String("LinearGradientPattern") ||
+ style == QLatin1String("RadialGradientPattern") ||
+ style == QLatin1String("ConicalGradientPattern")) {
+ const DomGradient *gradient = brush->elementGradient();
+ const QString gradientType = gradient->attributeType();
+ const QString gradientName = m_driver->unique(QLatin1String("gradient"));
+ if (gradientType == QLatin1String("LinearGradient")) {
+ m_output << m_indent << "QLinearGradient " << gradientName
+ << '(' << gradient->attributeStartX()
+ << ", " << gradient->attributeStartY()
+ << ", " << gradient->attributeEndX()
+ << ", " << gradient->attributeEndY() << ");\n";
+ } else if (gradientType == QLatin1String("RadialGradient")) {
+ m_output << m_indent << "QRadialGradient " << gradientName
+ << '(' << gradient->attributeCentralX()
+ << ", " << gradient->attributeCentralY()
+ << ", " << gradient->attributeRadius()
+ << ", " << gradient->attributeFocalX()
+ << ", " << gradient->attributeFocalY() << ");\n";
+ } else if (gradientType == QLatin1String("ConicalGradient")) {
+ m_output << m_indent << "QConicalGradient " << gradientName
+ << '(' << gradient->attributeCentralX()
+ << ", " << gradient->attributeCentralY()
+ << ", " << gradient->attributeAngle() << ");\n";
+ }
+
+ m_output << m_indent << gradientName << ".setSpread(QGradient::"
+ << gradient->attributeSpread() << ");\n";
+
+ if (gradient->hasAttributeCoordinateMode()) {
+ m_output << m_indent << gradientName << ".setCoordinateMode(QGradient::"
+ << gradient->attributeCoordinateMode() << ");\n";
+ }
+
+ const QList<DomGradientStop *> stops = gradient->elementGradientStop();
+ QListIterator<DomGradientStop *> it(stops);
+ while (it.hasNext()) {
+ const DomGradientStop *stop = it.next();
+ const DomColor *color = stop->elementColor();
+ m_output << m_indent << gradientName << ".setColorAt("
+ << stop->attributePosition() << ", "
+ << domColor2QString(color) << ");\n";
+ }
+ m_output << m_indent << "QBrush " << brushName << '('
+ << gradientName << ");\n";
+ } else if (style == QLatin1String("TexturePattern")) {
+ const DomProperty *property = brush->elementTexture();
+ const QString iconValue = iconCall(property);
+
+ m_output << m_indent << "QBrush " << brushName << " = QBrush("
+ << iconValue << ");\n";
+ } else {
+ const DomColor *color = brush->elementColor();
+ m_output << m_indent << "QBrush " << brushName << '('
+ << domColor2QString(color) << ");\n";
+
+ m_output << m_indent << brushName << ".setStyle("
+ << "Qt::" << style << ");\n";
+ }
+}
+
+void WriteInitialization::acceptCustomWidget(DomCustomWidget *node)
+{
+ Q_UNUSED(node);
+}
+
+void WriteInitialization::acceptCustomWidgets(DomCustomWidgets *node)
+{
+ Q_UNUSED(node);
+}
+
+void WriteInitialization::acceptTabStops(DomTabStops *tabStops)
+{
+ QString lastName;
+
+ const QStringList l = tabStops->elementTabStop();
+ for (int i=0; i<l.size(); ++i) {
+ const QString name = l.at(i);
+
+ if (!m_registeredWidgets.contains(name)) {
+ fprintf(stderr, "%s: Warning: Tab-stop assignment: '%s' is not a valid widget.\n",
+ qPrintable(m_option.messagePrefix()),
+ name.toLatin1().data());
+ continue;
+ }
+
+ if (i == 0) {
+ lastName = name;
+ continue;
+ } else if (name.isEmpty() || lastName.isEmpty()) {
+ continue;
+ }
+
+ m_output << m_indent << "QWidget::setTabOrder(" << lastName << ", " << name << ");\n";
+
+ lastName = name;
+ }
+}
+
+void WriteInitialization::initializeQ3ListBox(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString className = w->attributeClass();
+
+ const QList<DomItem*> items = w->elementItem();
+
+ if (items.isEmpty())
+ return;
+
+ m_refreshOut << m_indent << varName << "->clear();\n";
+
+ for (int i=0; i<items.size(); ++i) {
+ const DomItem *item = items.at(i);
+
+ const DomPropertyMap properties = propertyMap(item->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+ if (!(text || pixmap))
+ continue;
+
+ m_refreshOut << m_indent << varName << "->insertItem(";
+ if (pixmap) {
+ m_refreshOut << pixCall(pixmap);
+
+ if (text)
+ m_refreshOut << ", ";
+ }
+ if (text)
+ m_refreshOut << trCall(text->elementString());
+ m_refreshOut << ");\n";
+ }
+}
+
+void WriteInitialization::initializeQ3IconView(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString className = w->attributeClass();
+
+ const QList<DomItem*> items = w->elementItem();
+
+ if (items.isEmpty())
+ return;
+
+ m_refreshOut << m_indent << varName << "->clear();\n";
+
+ for (int i=0; i<items.size(); ++i) {
+ const DomItem *item = items.at(i);
+
+ const DomPropertyMap properties = propertyMap(item->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+ if (!(text || pixmap))
+ continue;
+
+ const QString itemName = m_driver->unique(QLatin1String("__item"));
+ m_refreshOut << "\n";
+ m_refreshOut << m_indent << "Q3IconViewItem *" << itemName << " = new Q3IconViewItem(" << varName << ");\n";
+
+ if (pixmap) {
+ m_refreshOut << m_indent << itemName << "->setPixmap(" << pixCall(pixmap) << ");\n";
+ }
+
+ if (text) {
+ m_refreshOut << m_indent << itemName << "->setText(" << trCall(text->elementString()) << ");\n";
+ }
+ }
+}
+
+void WriteInitialization::initializeQ3ListView(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString className = w->attributeClass();
+
+ // columns
+ const QList<DomColumn*> columns = w->elementColumn();
+ for (int i=0; i<columns.size(); ++i) {
+ const DomColumn *column = columns.at(i);
+
+ const DomPropertyMap properties = propertyMap(column->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+ const DomProperty *clickable = properties.value(QLatin1String("clickable"));
+ const DomProperty *resizable = properties.value(QLatin1String("resizable"));
+
+ const QString txt = trCall(text->elementString());
+ m_output << m_indent << varName << "->addColumn(" << txt << ");\n";
+ m_refreshOut << m_indent << varName << "->header()->setLabel(" << i << ", " << txt << ");\n";
+
+ if (pixmap) {
+ m_output << m_indent << varName << "->header()->setLabel("
+ << varName << "->header()->count() - 1, " << pixCall(pixmap) << ", " << txt << ");\n";
+ }
+
+ if (clickable != 0) {
+ m_output << m_indent << varName << "->header()->setClickEnabled(" << clickable->elementBool() << ", " << varName << "->header()->count() - 1);\n";
+ }
+
+ if (resizable != 0) {
+ m_output << m_indent << varName << "->header()->setResizeEnabled(" << resizable->elementBool() << ", " << varName << "->header()->count() - 1);\n";
+ }
+ }
+
+ if (w->elementItem().size()) {
+ m_refreshOut << m_indent << varName << "->clear();\n";
+
+ initializeQ3ListViewItems(className, varName, w->elementItem());
+ }
+}
+
+void WriteInitialization::initializeQ3ListViewItems(const QString &className, const QString &varName, const QList<DomItem *> &items)
+{
+ if (items.isEmpty())
+ return;
+
+ // items
+ for (int i=0; i<items.size(); ++i) {
+ const DomItem *item = items.at(i);
+
+ const QString itemName = m_driver->unique(QLatin1String("__item"));
+ m_refreshOut << "\n";
+ m_refreshOut << m_indent << "Q3ListViewItem *" << itemName << " = new Q3ListViewItem(" << varName << ");\n";
+
+ int textCount = 0, pixCount = 0;
+ const DomPropertyList properties = item->elementProperty();
+ for (int i=0; i<properties.size(); ++i) {
+ const DomProperty *p = properties.at(i);
+ if (p->attributeName() == QLatin1String("text"))
+ m_refreshOut << m_indent << itemName << "->setText(" << textCount++ << ", "
+ << trCall(p->elementString()) << ");\n";
+
+ if (p->attributeName() == QLatin1String("pixmap"))
+ m_refreshOut << m_indent << itemName << "->setPixmap(" << pixCount++ << ", "
+ << pixCall(p) << ");\n";
+ }
+
+ if (item->elementItem().size()) {
+ m_refreshOut << m_indent << itemName << "->setOpen(true);\n";
+ initializeQ3ListViewItems(className, itemName, item->elementItem());
+ }
+ }
+}
+
+
+void WriteInitialization::initializeQ3Table(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString className = w->attributeClass();
+
+ // columns
+ const QList<DomColumn*> columns = w->elementColumn();
+
+ for (int i=0; i<columns.size(); ++i) {
+ const DomColumn *column = columns.at(i);
+
+ const DomPropertyMap properties = propertyMap(column->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+
+ m_refreshOut << m_indent << varName << "->horizontalHeader()->setLabel(" << i << ", ";
+ if (pixmap) {
+ m_refreshOut << pixCall(pixmap) << ", ";
+ }
+ m_refreshOut << trCall(text->elementString()) << ");\n";
+ }
+
+ // rows
+ const QList<DomRow*> rows = w->elementRow();
+ for (int i=0; i<rows.size(); ++i) {
+ const DomRow *row = rows.at(i);
+
+ const DomPropertyMap properties = propertyMap(row->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *pixmap = properties.value(QLatin1String("pixmap"));
+
+ m_refreshOut << m_indent << varName << "->verticalHeader()->setLabel(" << i << ", ";
+ if (pixmap) {
+ m_refreshOut << pixCall(pixmap) << ", ";
+ }
+ m_refreshOut << trCall(text->elementString()) << ");\n";
+ }
+
+
+ //initializeQ3TableItems(className, varName, w->elementItem());
+}
+
+void WriteInitialization::initializeQ3TableItems(const QString &className, const QString &varName, const QList<DomItem *> &items)
+{
+ Q_UNUSED(className);
+ Q_UNUSED(varName);
+ Q_UNUSED(items);
+}
+
+QString WriteInitialization::iconCall(const DomProperty *icon)
+{
+ if (icon->kind() == DomProperty::IconSet)
+ return writeIconProperties(icon->elementIconSet());
+ return pixCall(icon);
+}
+
+QString WriteInitialization::pixCall(const DomProperty *p) const
+{
+ QString type, s;
+ switch (p->kind()) {
+ case DomProperty::IconSet:
+ type = QLatin1String("QIcon");
+ s = p->elementIconSet()->text();
+ break;
+ case DomProperty::Pixmap:
+ type = QLatin1String("QPixmap");
+ s = p->elementPixmap()->text();
+ break;
+ default:
+ qWarning("%s: Warning: Unknown icon format encountered. The ui-file was generated with a too-recent version of Designer.",
+ qPrintable(m_option.messagePrefix()));
+ return QLatin1String("QIcon()");
+ break;
+ }
+ return pixCall(type, s);
+}
+
+QString WriteInitialization::pixCall(const QString &t, const QString &text) const
+{
+ QString type = t;
+ if (text.isEmpty()) {
+ type += QLatin1String("()");
+ return type;
+ }
+ if (const DomImage *image = findImage(text)) {
+ if (m_option.extractImages) {
+ const QString format = image->elementData()->attributeFormat();
+ const QString extension = format.left(format.indexOf(QLatin1Char('.'))).toLower();
+ QString rc = QLatin1String("QPixmap(QString::fromUtf8(\":/");
+ rc += m_generatedClass;
+ rc += QLatin1String("/images/");
+ rc += text;
+ rc += QLatin1Char('.');
+ rc += extension;
+ rc += QLatin1String("\"))");
+ return rc;
+ }
+ QString rc = WriteIconInitialization::iconFromDataFunction();
+ rc += QLatin1Char('(');
+ rc += text;
+ rc += QLatin1String("_ID)");
+ return rc;
+ }
+
+ QString pixFunc = m_uic->pixmapFunction();
+ if (pixFunc.isEmpty())
+ pixFunc = QLatin1String("QString::fromUtf8");
+
+ type += QLatin1Char('(');
+ type += pixFunc;
+ type += QLatin1Char('(');
+ type += fixString(text, m_dindent);
+ type += QLatin1String("))");
+ return type;
+}
+
+void WriteInitialization::initializeComboBox3(DomWidget *w)
+{
+ const QList<DomItem*> items = w->elementItem();
+ if (items.empty())
+ return;
+ // Basic legacy Qt3 support, write out translatable text items, ignore pixmaps
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString textProperty = QLatin1String("text");
+
+ m_refreshOut << m_indent << varName << "->clear();\n";
+ m_refreshOut << m_indent << varName << "->insertStringList(QStringList()" << '\n';
+ const int itemCount = items.size();
+ for (int i = 0; i< itemCount; ++i) {
+ const DomItem *item = items.at(i);
+ if (const DomProperty *text = propertyMap(item->elementProperty()).value(textProperty))
+ m_refreshOut << m_indent << " << " << autoTrCall(text->elementString()) << "\n";
+ }
+ m_refreshOut << m_indent << ", 0);\n";
+}
+
+void WriteInitialization::initializeComboBox(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString className = w->attributeClass();
+
+ const QList<DomItem*> items = w->elementItem();
+
+ if (items.isEmpty())
+ return;
+
+ // If possible use qcombobox's addItems() which is much faster then a bunch of addItem() calls
+ bool makeStringListCall = true;
+ bool translatable = false;
+ QStringList list;
+ for (int i=0; i<items.size(); ++i) {
+ const DomItem *item = items.at(i);
+ const DomPropertyMap properties = propertyMap(item->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *pixmap = properties.value(QLatin1String("icon"));
+ bool needsTr = needsTranslation(text->elementString());
+ if (pixmap != 0 || (i > 0 && translatable != needsTr)) {
+ makeStringListCall = false;
+ break;
+ }
+ translatable = needsTr;
+ list.append(autoTrCall(text->elementString())); // fix me here
+ }
+
+ if (makeStringListCall) {
+ QTextStream &o = translatable ? m_refreshOut : m_output;
+ if (translatable)
+ o << m_indent << varName << "->clear();\n";
+ o << m_indent << varName << "->insertItems(0, QStringList()" << '\n';
+ for (int i = 0; i < list.size(); ++i)
+ o << m_indent << " << " << list.at(i) << "\n";
+ o << m_indent << ");\n";
+ } else {
+ for (int i = 0; i < items.size(); ++i) {
+ const DomItem *item = items.at(i);
+ const DomPropertyMap properties = propertyMap(item->elementProperty());
+ const DomProperty *text = properties.value(QLatin1String("text"));
+ const DomProperty *icon = properties.value(QLatin1String("icon"));
+
+ QString iconValue;
+ if (icon)
+ iconValue = iconCall(icon);
+
+ m_output << m_indent << varName << "->addItem(";
+ if (icon)
+ m_output << iconValue << ", ";
+
+ if (needsTranslation(text->elementString())) {
+ m_output << "QString());\n";
+ m_refreshOut << m_indent << varName << "->setItemText(" << i << ", " << trCall(text->elementString()) << ");\n";
+ } else {
+ m_output << noTrCall(text->elementString()) << ");\n";
+ }
+ }
+ m_refreshOut << "\n";
+ }
+}
+
+QString WriteInitialization::disableSorting(DomWidget *w, const QString &varName)
+{
+ // turn off sortingEnabled to force programmatic item order (setItem())
+ QString tempName;
+ if (!w->elementItem().isEmpty()) {
+ tempName = m_driver->unique(QLatin1String("__sortingEnabled"));
+ m_refreshOut << "\n";
+ m_refreshOut << m_indent << "const bool " << tempName
+ << " = " << varName << "->isSortingEnabled();\n";
+ m_refreshOut << m_indent << varName << "->setSortingEnabled(false);\n";
+ }
+ return tempName;
+}
+
+void WriteInitialization::enableSorting(DomWidget *w, const QString &varName, const QString &tempName)
+{
+ if (!w->elementItem().isEmpty()) {
+ m_refreshOut << m_indent << varName << "->setSortingEnabled(" << tempName << ");\n\n";
+ }
+}
+
+/*
+ * Initializers are just strings containing the function call and need to be prepended
+ * the line indentation and the object they are supposed to initialize.
+ * String initializers come with a preprocessor conditional (ifdef), so the code
+ * compiles with QT_NO_xxx. A null pointer means no conditional. String initializers
+ * are written to the retranslateUi() function, others to setupUi().
+ */
+
+
+/*!
+ Create non-string inititializer.
+ \param value the value to initialize the attribute with. May be empty, in which case
+ the initializer is omitted.
+ See above for other parameters.
+*/
+void WriteInitialization::addInitializer(Item *item,
+ const QString &name, int column, const QString &value, const QString &directive, bool translatable) const
+{
+ if (!value.isEmpty())
+ item->addSetter(QLatin1String("->set") + name.at(0).toUpper() + name.mid(1) +
+ QLatin1Char('(') + (column < 0 ? QString() : QString::number(column) +
+ QLatin1String(", ")) + value + QLatin1String(");"), directive, translatable);
+}
+
+/*!
+ Create string inititializer.
+ \param initializers in/out list of inializers
+ \param properties map property name -> property to extract data from
+ \param name the property to extract
+ \param col the item column to generate the initializer for. This is relevant for
+ tree widgets only. If it is -1, no column index will be generated.
+ \param ifdef preprocessor symbol for disabling compilation of this initializer
+*/
+void WriteInitialization::addStringInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column, const QString &directive) const
+{
+ if (const DomProperty *p = properties.value(name)) {
+ DomString *str = p->elementString();
+ QString text = toString(str);
+ if (!text.isEmpty()) {
+ bool translatable = needsTranslation(str);
+ QString value = autoTrCall(str);
+ addInitializer(item, name, column, value, directive, translatable);
+ }
+ }
+}
+
+void WriteInitialization::addBrushInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column)
+{
+ if (const DomProperty *p = properties.value(name)) {
+ if (p->elementBrush())
+ addInitializer(item, name, column, writeBrushInitialization(p->elementBrush()));
+ else if (p->elementColor())
+ addInitializer(item, name, column, domColor2QString(p->elementColor()));
+ }
+}
+
+/*!
+ Create inititializer for a flag value in the Qt namespace.
+ If the named property is not in the map, the initializer is omitted.
+*/
+void WriteInitialization::addQtFlagsInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column) const
+{
+ if (const DomProperty *p = properties.value(name)) {
+ QString v = p->elementSet();
+ if (!v.isEmpty()) {
+ v.replace(QLatin1Char('|'), QLatin1String("|Qt::"));
+ addInitializer(item, name, column, QLatin1String("Qt::") + v);
+ }
+ }
+}
+
+/*!
+ Create inititializer for an enum value in the Qt namespace.
+ If the named property is not in the map, the initializer is omitted.
+*/
+void WriteInitialization::addQtEnumInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column) const
+{
+ if (const DomProperty *p = properties.value(name)) {
+ QString v = p->elementEnum();
+ if (!v.isEmpty())
+ addInitializer(item, name, column, QLatin1String("Qt::") + v);
+ }
+}
+
+/*!
+ Create inititializers for all common properties that may be bound to a column.
+*/
+void WriteInitialization::addCommonInitializers(Item *item,
+ const DomPropertyMap &properties, int column)
+{
+ if (const DomProperty *icon = properties.value(QLatin1String("icon")))
+ addInitializer(item, QLatin1String("icon"), column, iconCall(icon));
+ addBrushInitializer(item, properties, QLatin1String("foreground"), column);
+ addBrushInitializer(item, properties, QLatin1String("background"), column);
+ if (const DomProperty *font = properties.value(QLatin1String("font")))
+ addInitializer(item, QLatin1String("font"), column, writeFontProperties(font->elementFont()));
+ addQtFlagsInitializer(item, properties, QLatin1String("textAlignment"), column);
+ addQtEnumInitializer(item, properties, QLatin1String("checkState"), column);
+ addStringInitializer(item, properties, QLatin1String("text"), column);
+ addStringInitializer(item, properties, QLatin1String("toolTip"), column, QLatin1String(toolTipDefineC));
+ addStringInitializer(item, properties, QLatin1String("whatsThis"), column, QLatin1String(whatsThisDefineC));
+ addStringInitializer(item, properties, QLatin1String("statusTip"), column, QLatin1String(statusTipDefineC));
+}
+
+void WriteInitialization::initializeListWidget(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+ const QString className = w->attributeClass();
+
+ const QList<DomItem*> items = w->elementItem();
+
+ if (items.isEmpty())
+ return;
+
+ QString tempName = disableSorting(w, varName);
+ // items
+ // TODO: the generated code should be data-driven to reduce its size
+ for (int i = 0; i < items.size(); ++i) {
+ const DomItem *domItem = items.at(i);
+
+ const DomPropertyMap properties = propertyMap(domItem->elementProperty());
+
+ Item item(QLatin1String("QListWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
+ addQtFlagsInitializer(&item, properties, QLatin1String("flags"));
+ addCommonInitializers(&item, properties);
+
+ item.writeSetupUi(varName);
+ item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(i) + QLatin1Char(')'));
+ }
+ enableSorting(w, varName, tempName);
+}
+
+void WriteInitialization::initializeTreeWidget(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+
+ // columns
+ Item item(QLatin1String("QTreeWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
+
+ const QList<DomColumn*> columns = w->elementColumn();
+ for (int i = 0; i < columns.size(); ++i) {
+ const DomColumn *column = columns.at(i);
+
+ const DomPropertyMap properties = propertyMap(column->elementProperty());
+ addCommonInitializers(&item, properties, i);
+ }
+ const QString itemName = item.writeSetupUi(QString(), Item::DontConstruct);
+ item.writeRetranslateUi(varName + QLatin1String("->headerItem()"));
+ if (!itemName.isNull())
+ m_output << m_indent << varName << "->setHeaderItem(" << itemName << ");\n";
+
+ if (w->elementItem().size() == 0)
+ return;
+
+ QString tempName = disableSorting(w, varName);
+
+ QList<Item *> items = initializeTreeWidgetItems(w->elementItem());
+ for (int i = 0; i < items.count(); i++) {
+ Item *itm = items[i];
+ itm->writeSetupUi(varName);
+ itm->writeRetranslateUi(varName + QLatin1String("->topLevelItem(") + QString::number(i) + QLatin1Char(')'));
+ delete itm;
+ }
+
+ enableSorting(w, varName, tempName);
+}
+
+/*!
+ Create and write out initializers for tree widget items.
+ This function makes sure that only needed items are fetched (subject to preprocessor
+ conditionals), that each item is fetched from its parent widget/item exactly once
+ and that no temporary variables are created for items that are needed only once. As
+ fetches are built top-down from the root, but determining how often and under which
+ conditions an item is needed needs to be done bottom-up, the whole process makes
+ two passes, storing the intermediate result in a recursive StringInitializerListMap.
+*/
+QList<WriteInitialization::Item *> WriteInitialization::initializeTreeWidgetItems(const QList<DomItem *> &domItems)
+{
+ // items
+ QList<Item *> items;
+
+ for (int i = 0; i < domItems.size(); ++i) {
+ const DomItem *domItem = domItems.at(i);
+
+ Item *item = new Item(QLatin1String("QTreeWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
+ items << item;
+
+ QHash<QString, DomProperty *> map;
+
+ int col = -1;
+ const DomPropertyList properties = domItem->elementProperty();
+ for (int j = 0; j < properties.size(); ++j) {
+ DomProperty *p = properties.at(j);
+ if (p->attributeName() == QLatin1String("text")) {
+ if (!map.isEmpty()) {
+ addCommonInitializers(item, map, col);
+ map.clear();
+ }
+ col++;
+ }
+ map.insert(p->attributeName(), p);
+ }
+ addCommonInitializers(item, map, col);
+ // AbstractFromBuilder saves flags last, so they always end up in the last column's map.
+ addQtFlagsInitializer(item, map, QLatin1String("flags"));
+
+ QList<Item *> subItems = initializeTreeWidgetItems(domItem->elementItem());
+ foreach (Item *subItem, subItems)
+ item->addChild(subItem);
+ }
+ return items;
+}
+
+void WriteInitialization::initializeTableWidget(DomWidget *w)
+{
+ const QString varName = m_driver->findOrInsertWidget(w);
+
+ // columns
+ const QList<DomColumn *> columns = w->elementColumn();
+
+ if (columns.size() != 0) {
+ m_output << m_indent << "if (" << varName << "->columnCount() < " << columns.size() << ")\n"
+ << m_dindent << varName << "->setColumnCount(" << columns.size() << ");\n";
+ }
+
+ for (int i = 0; i < columns.size(); ++i) {
+ const DomColumn *column = columns.at(i);
+ if (!column->elementProperty().isEmpty()) {
+ const DomPropertyMap properties = propertyMap(column->elementProperty());
+
+ Item item(QLatin1String("QTableWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
+ addCommonInitializers(&item, properties);
+
+ QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
+ item.writeRetranslateUi(varName + QLatin1String("->horizontalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
+ m_output << m_indent << varName << "->setHorizontalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n";
+ }
+ }
+
+ // rows
+ const QList<DomRow *> rows = w->elementRow();
+
+ if (rows.size() != 0) {
+ m_output << m_indent << "if (" << varName << "->rowCount() < " << rows.size() << ")\n"
+ << m_dindent << varName << "->setRowCount(" << rows.size() << ");\n";
+ }
+
+ for (int i = 0; i < rows.size(); ++i) {
+ const DomRow *row = rows.at(i);
+ if (!row->elementProperty().isEmpty()) {
+ const DomPropertyMap properties = propertyMap(row->elementProperty());
+
+ Item item(QLatin1String("QTableWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
+ addCommonInitializers(&item, properties);
+
+ QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
+ item.writeRetranslateUi(varName + QLatin1String("->verticalHeaderItem(") + QString::number(i) + QLatin1Char(')'));
+ m_output << m_indent << varName << "->setVerticalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n";
+ }
+ }
+
+ // items
+ QString tempName = disableSorting(w, varName);
+
+ const QList<DomItem *> items = w->elementItem();
+
+ for (int i = 0; i < items.size(); ++i) {
+ const DomItem *cell = items.at(i);
+ if (cell->hasAttributeRow() && cell->hasAttributeColumn() && !cell->elementProperty().isEmpty()) {
+ const int r = cell->attributeRow();
+ const int c = cell->attributeColumn();
+ const DomPropertyMap properties = propertyMap(cell->elementProperty());
+
+ Item item(QLatin1String("QTableWidgetItem"), m_indent, m_output, m_refreshOut, m_driver);
+ addQtFlagsInitializer(&item, properties, QLatin1String("flags"));
+ addCommonInitializers(&item, properties);
+
+ QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable);
+ item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(r) + QLatin1String(", ") + QString::number(c) + QLatin1Char(')'));
+ m_output << m_indent << varName << "->setItem(" << QString::number(r) << ", " << QString::number(c) << ", " << itemName << ");\n";
+ }
+ }
+ enableSorting(w, varName, tempName);
+}
+
+QString WriteInitialization::trCall(const QString &str, const QString &commentHint) const
+{
+ if (str.isEmpty())
+ return QLatin1String("QString()");
+
+ QString result;
+ const QString comment = commentHint.isEmpty() ? QString(QLatin1Char('0')) : fixString(commentHint, m_dindent);
+
+ if (m_option.translateFunction.isEmpty()) {
+ result = QLatin1String("QApplication::translate(\"");
+ result += m_generatedClass;
+ result += QLatin1Char('"');
+ result += QLatin1String(", ");
+ } else {
+ result = m_option.translateFunction;
+ result += QLatin1Char('(');
+ }
+
+ result += fixString(str, m_dindent);
+ result += QLatin1String(", ");
+ result += comment;
+
+ if (m_option.translateFunction.isEmpty()) {
+ result += QLatin1String(", ");
+ result += QLatin1String("QApplication::UnicodeUTF8");
+ }
+
+ result += QLatin1Char(')');
+ return result;
+}
+
+void WriteInitialization::initializeQ3SqlDataTable(DomWidget *w)
+{
+ const DomPropertyMap properties = propertyMap(w->elementProperty());
+
+ const DomProperty *frameworkCode = properties.value(QLatin1String("frameworkCode"), 0);
+ if (frameworkCode && toBool(frameworkCode->elementBool()) == false)
+ return;
+
+ QString connection;
+ QString table;
+ QString field;
+
+ const DomProperty *db = properties.value(QLatin1String("database"), 0);
+ if (db && db->elementStringList()) {
+ const QStringList info = db->elementStringList()->elementString();
+ connection = info.size() > 0 ? info.at(0) : QString();
+ table = info.size() > 1 ? info.at(1) : QString();
+ field = info.size() > 2 ? info.at(2) : QString();
+ }
+
+ if (table.isEmpty() || connection.isEmpty()) {
+ fprintf(stderr, "%s: Warning: Invalid database connection\n", qPrintable(m_option.messagePrefix()));
+ return;
+ }
+
+ const QString varName = m_driver->findOrInsertWidget(w);
+
+ m_output << m_indent << "if (!" << varName << "->sqlCursor()) {\n";
+
+ m_output << m_dindent << varName << "->setSqlCursor(";
+
+ if (connection == QLatin1String("(default)")) {
+ m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << "), false, true);\n";
+ } else {
+ m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << ", true, " << connection << "Connection" << "), false, true);\n";
+ }
+ m_output << m_dindent << varName << "->refresh(Q3DataTable::RefreshAll);\n";
+ m_output << m_indent << "}\n";
+}
+
+void WriteInitialization::initializeQ3SqlDataBrowser(DomWidget *w)
+{
+ const DomPropertyMap properties = propertyMap(w->elementProperty());
+
+ const DomProperty *frameworkCode = properties.value(QLatin1String("frameworkCode"), 0);
+ if (frameworkCode && toBool(frameworkCode->elementBool()) == false)
+ return;
+
+ QString connection;
+ QString table;
+ QString field;
+
+ const DomProperty *db = properties.value(QLatin1String("database"), 0);
+ if (db && db->elementStringList()) {
+ const QStringList info = db->elementStringList()->elementString();
+ connection = info.size() > 0 ? info.at(0) : QString();
+ table = info.size() > 1 ? info.at(1) : QString();
+ field = info.size() > 2 ? info.at(2) : QString();
+ }
+
+ if (table.isEmpty() || connection.isEmpty()) {
+ fprintf(stderr, "%s: Warning: Invalid database connection\n", qPrintable(m_option.messagePrefix()));
+ return;
+ }
+
+ const QString varName = m_driver->findOrInsertWidget(w);
+
+ m_output << m_indent << "if (!" << varName << "->sqlCursor()) {\n";
+
+ m_output << m_dindent << varName << "->setSqlCursor(";
+
+ if (connection == QLatin1String("(default)")) {
+ m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << "), true);\n";
+ } else {
+ m_output << "new Q3SqlCursor(" << fixString(table, m_dindent) << ", true, " << connection << "Connection" << "), false, true);\n";
+ }
+ m_output << m_dindent << varName << "->refresh();\n";
+ m_output << m_indent << "}\n";
+}
+
+void WriteInitialization::initializeMenu(DomWidget *w, const QString &/*parentWidget*/)
+{
+ const QString menuName = m_driver->findOrInsertWidget(w);
+ const QString menuAction = menuName + QLatin1String("Action");
+
+ const DomAction *action = m_driver->actionByName(menuAction);
+ if (action && action->hasAttributeMenu()) {
+ m_output << m_indent << menuAction << " = " << menuName << "->menuAction();\n";
+ }
+}
+
+QString WriteInitialization::trCall(DomString *str, const QString &defaultString) const
+{
+ QString value = defaultString;
+ QString comment;
+ if (str) {
+ value = toString(str);
+ comment = str->attributeComment();
+ }
+ return trCall(value, comment);
+}
+
+QString WriteInitialization::noTrCall(DomString *str, const QString &defaultString) const
+{
+ QString value = defaultString;
+ if (!str && defaultString.isEmpty())
+ return QString();
+ if (str)
+ value = str->text();
+ QString ret = QLatin1String("QString::fromUtf8(");
+ ret += fixString(value, m_dindent);
+ ret += QLatin1Char(')');
+ return ret;
+}
+
+QString WriteInitialization::autoTrCall(DomString *str, const QString &defaultString) const
+{
+ if ((!str && !defaultString.isEmpty()) || needsTranslation(str))
+ return trCall(str, defaultString);
+ return noTrCall(str, defaultString);
+}
+
+QTextStream &WriteInitialization::autoTrOutput(DomString *str, const QString &defaultString)
+{
+ if ((!str && !defaultString.isEmpty()) || needsTranslation(str))
+ return m_refreshOut;
+ return m_output;
+}
+
+bool WriteInitialization::isValidObject(const QString &name) const
+{
+ return m_registeredWidgets.contains(name)
+ || m_registeredActions.contains(name);
+}
+
+QString WriteInitialization::findDeclaration(const QString &name)
+{
+ const QString normalized = Driver::normalizedName(name);
+
+ if (DomWidget *widget = m_driver->widgetByName(normalized))
+ return m_driver->findOrInsertWidget(widget);
+ if (DomAction *action = m_driver->actionByName(normalized))
+ return m_driver->findOrInsertAction(action);
+ if (const DomButtonGroup *group = m_driver->findButtonGroup(normalized))
+ return m_driver->findOrInsertButtonGroup(group);
+ return QString();
+}
+
+void WriteInitialization::acceptConnection(DomConnection *connection)
+{
+ const QString sender = findDeclaration(connection->elementSender());
+ const QString receiver = findDeclaration(connection->elementReceiver());
+
+ if (sender.isEmpty() || receiver.isEmpty())
+ return;
+
+ m_output << m_indent << "QObject::connect("
+ << sender
+ << ", "
+ << "SIGNAL("<<connection->elementSignal()<<')'
+ << ", "
+ << receiver
+ << ", "
+ << "SLOT("<<connection->elementSlot()<<')'
+ << ");\n";
+}
+
+DomImage *WriteInitialization::findImage(const QString &name) const
+{
+ return m_registeredImages.value(name);
+}
+
+DomWidget *WriteInitialization::findWidget(const QLatin1String &widgetClass)
+{
+ for (int i = m_widgetChain.count() - 1; i >= 0; --i) {
+ DomWidget *widget = m_widgetChain.at(i);
+
+ if (widget && m_uic->customWidgetsInfo()->extends(widget->attributeClass(), widgetClass))
+ return widget;
+ }
+
+ return 0;
+}
+
+void WriteInitialization::acceptImage(DomImage *image)
+{
+ if (!image->hasAttributeName())
+ return;
+
+ m_registeredImages.insert(image->attributeName(), image);
+}
+
+void WriteInitialization::acceptWidgetScripts(const DomScripts &widgetScripts, DomWidget *node, const DomWidgets &childWidgets)
+{
+ // Add the per-class custom scripts to the per-widget ones.
+ DomScripts scripts(widgetScripts);
+
+ if (DomScript *customWidgetScript = m_uic->customWidgetsInfo()->customWidgetScript(node->attributeClass()))
+ scripts.push_front(customWidgetScript);
+
+ if (scripts.empty())
+ return;
+
+ // concatenate script snippets
+ QString script;
+ foreach (const DomScript *domScript, scripts) {
+ const QString snippet = domScript->text();
+ if (!snippet.isEmpty()) {
+ script += snippet.trimmed();
+ script += QLatin1Char('\n');
+ }
+ }
+ if (script.isEmpty())
+ return;
+
+ // Build the list of children and insert call
+ m_output << m_indent << "childWidgets.clear();\n";
+ if (!childWidgets.empty()) {
+ m_output << m_indent << "childWidgets";
+ foreach (DomWidget *child, childWidgets) {
+ m_output << " << " << m_driver->findOrInsertWidget(child);
+ }
+ m_output << ";\n";
+ }
+ m_output << m_indent << "scriptContext.run(QString::fromUtf8("
+ << fixString(script, m_dindent) << "), "
+ << m_driver->findOrInsertWidget(node) << ", childWidgets);\n";
+}
+
+
+static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QString> &directives)
+{
+ if (directives.isEmpty())
+ return;
+
+ QMap<QString, bool> map; // bool is dummy. The idea is to sort that (always generate in the same order) by putting a set into a map
+ foreach (const QString &str, directives)
+ map.insert(str, true);
+
+ if (map.size() == 1) {
+ outputStream << "#ifndef " << map.constBegin().key() << endl;
+ return;
+ }
+
+ outputStream << "#if";
+ bool doOr = false;
+ foreach (const QString &str, map.keys()) {
+ if (doOr)
+ outputStream << " ||";
+ outputStream << " !defined(" << str << ')';
+ doOr = true;
+ }
+ outputStream << endl;
+}
+
+static void generateMultiDirectiveEnd(QTextStream &outputStream, const QSet<QString> &directives)
+{
+ if (directives.isEmpty())
+ return;
+
+ outputStream << "#endif" << endl;
+}
+
+WriteInitialization::Item::Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver)
+ :
+ m_parent(0),
+ m_itemClassName(itemClassName),
+ m_indent(indent),
+ m_setupUiStream(setupUiStream),
+ m_retranslateUiStream(retranslateUiStream),
+ m_driver(driver)
+{
+
+}
+
+WriteInitialization::Item::~Item()
+{
+ foreach (Item *child, m_children)
+ delete child;
+}
+
+QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::EmptyItemPolicy emptyItemPolicy)
+{
+ if (emptyItemPolicy == Item::DontConstruct && m_setupUiData.policy == ItemData::DontGenerate)
+ return QString();
+
+ bool generateMultiDirective = false;
+ if (emptyItemPolicy == Item::ConstructItemOnly && m_children.size() == 0) {
+ if (m_setupUiData.policy == ItemData::DontGenerate) {
+ m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
+ return QString();
+ } else if (m_setupUiData.policy == ItemData::GenerateWithMultiDirective) {
+ generateMultiDirective = true;
+ }
+ }
+
+ if (generateMultiDirective)
+ generateMultiDirectiveBegin(m_setupUiStream, m_setupUiData.directives);
+
+ const QString uniqueName = m_driver->unique(QLatin1String("__") + m_itemClassName.toLower());
+ m_setupUiStream << m_indent << m_itemClassName << " *" << uniqueName << " = new " << m_itemClassName << '(' << parent << ");\n";
+
+ if (generateMultiDirective) {
+ m_setupUiStream << "#else\n";
+ m_setupUiStream << m_indent << "new " << m_itemClassName << '(' << parent << ");\n";
+ generateMultiDirectiveEnd(m_setupUiStream, m_setupUiData.directives);
+ }
+
+ QMultiMap<QString, QString>::ConstIterator it = m_setupUiData.setters.constBegin();
+ while (it != m_setupUiData.setters.constEnd()) {
+ openIfndef(m_setupUiStream, it.key());
+ m_setupUiStream << m_indent << uniqueName << it.value() << endl;
+ closeIfndef(m_setupUiStream, it.key());
+ ++it;
+ }
+ foreach (Item *child, m_children)
+ child->writeSetupUi(uniqueName);
+ return uniqueName;
+}
+
+void WriteInitialization::Item::writeRetranslateUi(const QString &parentPath)
+{
+ if (m_retranslateUiData.policy == ItemData::DontGenerate)
+ return;
+
+ if (m_retranslateUiData.policy == ItemData::GenerateWithMultiDirective)
+ generateMultiDirectiveBegin(m_retranslateUiStream, m_retranslateUiData.directives);
+
+ const QString uniqueName = m_driver->unique(QLatin1String("___") + m_itemClassName.toLower());
+ m_retranslateUiStream << m_indent << m_itemClassName << " *" << uniqueName << " = " << parentPath << ";\n";
+
+ if (m_retranslateUiData.policy == ItemData::GenerateWithMultiDirective)
+ generateMultiDirectiveEnd(m_retranslateUiStream, m_retranslateUiData.directives);
+
+ QString oldDirective;
+ QMultiMap<QString, QString>::ConstIterator it = m_retranslateUiData.setters.constBegin();
+ while (it != m_retranslateUiData.setters.constEnd()) {
+ const QString newDirective = it.key();
+ if (oldDirective != newDirective) {
+ closeIfndef(m_retranslateUiStream, oldDirective);
+ openIfndef(m_retranslateUiStream, newDirective);
+ oldDirective = newDirective;
+ }
+ m_retranslateUiStream << m_indent << uniqueName << it.value() << endl;
+ ++it;
+ }
+ closeIfndef(m_retranslateUiStream, oldDirective);
+
+ for (int i = 0; i < m_children.size(); i++)
+ m_children[i]->writeRetranslateUi(uniqueName + QLatin1String("->child(") + QString::number(i) + QLatin1Char(')'));
+}
+
+void WriteInitialization::Item::addSetter(const QString &setter, const QString &directive, bool translatable)
+{
+ const ItemData::TemporaryVariableGeneratorPolicy newPolicy = directive.isNull() ? ItemData::Generate : ItemData::GenerateWithMultiDirective;
+ if (translatable) {
+ m_retranslateUiData.setters.insert(directive, setter);
+ if (ItemData::GenerateWithMultiDirective == newPolicy)
+ m_retranslateUiData.directives << directive;
+ if (m_retranslateUiData.policy < newPolicy)
+ m_retranslateUiData.policy = newPolicy;
+ } else {
+ m_setupUiData.setters.insert(directive, setter);
+ if (ItemData::GenerateWithMultiDirective == newPolicy)
+ m_setupUiData.directives << directive;
+ if (m_setupUiData.policy < newPolicy)
+ m_setupUiData.policy = newPolicy;
+ }
+}
+
+void WriteInitialization::Item::addChild(Item *child)
+{
+ m_children << child;
+ child->m_parent = this;
+
+ Item *c = child;
+ Item *p = this;
+ while (p) {
+ p->m_setupUiData.directives |= c->m_setupUiData.directives;
+ p->m_retranslateUiData.directives |= c->m_retranslateUiData.directives;
+ if (p->m_setupUiData.policy < c->m_setupUiData.policy)
+ p->m_setupUiData.policy = c->m_setupUiData.policy;
+ if (p->m_retranslateUiData.policy < c->m_retranslateUiData.policy)
+ p->m_retranslateUiData.policy = c->m_retranslateUiData.policy;
+ c = p;
+ p = p->m_parent;
+ }
+}
+
+
+} // namespace CPP
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/cpp/cppwriteinitialization.h b/src/tools/uic/cpp/cppwriteinitialization.h
new file mode 100644
index 0000000000..302fbe4bc5
--- /dev/null
+++ b/src/tools/uic/cpp/cppwriteinitialization.h
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPWRITEINITIALIZATION_H
+#define CPPWRITEINITIALIZATION_H
+
+#include "treewalker.h"
+#include <QtCore/QPair>
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QMap>
+#include <QtCore/QStack>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+class Driver;
+class Uic;
+class DomBrush;
+class DomFont;
+class DomResourceIcon;
+class DomSizePolicy;
+struct Option;
+
+namespace CPP {
+ // Handle for a flat DOM font to get comparison functionality required for maps
+ class FontHandle {
+ public:
+ FontHandle(const DomFont *domFont);
+ int compare(const FontHandle &) const;
+ private:
+ const DomFont *m_domFont;
+#if defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
+ friend uint qHash(const FontHandle &);
+#endif
+ };
+ inline bool operator ==(const FontHandle &f1, const FontHandle &f2) { return f1.compare(f2) == 0; }
+ inline bool operator <(const FontHandle &f1, const FontHandle &f2) { return f1.compare(f2) < 0; }
+
+ // Handle for a flat DOM icon to get comparison functionality required for maps
+ class IconHandle {
+ public:
+ IconHandle(const DomResourceIcon *domIcon);
+ int compare(const IconHandle &) const;
+ private:
+ const DomResourceIcon *m_domIcon;
+#if defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
+ friend uint qHash(const IconHandle &);
+#endif
+ };
+ inline bool operator ==(const IconHandle &i1, const IconHandle &i2) { return i1.compare(i2) == 0; }
+ inline bool operator <(const IconHandle &i1, const IconHandle &i2) { return i1.compare(i2) < 0; }
+
+ // Handle for a flat DOM size policy to get comparison functionality required for maps
+ class SizePolicyHandle {
+ public:
+ SizePolicyHandle(const DomSizePolicy *domSizePolicy);
+ int compare(const SizePolicyHandle &) const;
+ private:
+ const DomSizePolicy *m_domSizePolicy;
+#if defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
+ friend uint qHash(const SizePolicyHandle &);
+#endif
+ };
+ inline bool operator ==(const SizePolicyHandle &f1, const SizePolicyHandle &f2) { return f1.compare(f2) == 0; }
+#if !(defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3))
+ inline bool operator <(const SizePolicyHandle &f1, const SizePolicyHandle &f2) { return f1.compare(f2) < 0; }
+#endif
+
+
+
+struct WriteInitialization : public TreeWalker
+{
+ typedef QList<DomProperty*> DomPropertyList;
+ typedef QHash<QString, DomProperty*> DomPropertyMap;
+
+ WriteInitialization(Uic *uic, bool activateScripts);
+
+//
+// widgets
+//
+ void acceptUI(DomUI *node);
+ void acceptWidget(DomWidget *node);
+ void acceptWidgetScripts(const DomScripts &, DomWidget *node, const DomWidgets &childWidgets);
+
+ void acceptLayout(DomLayout *node);
+ void acceptSpacer(DomSpacer *node);
+ void acceptLayoutItem(DomLayoutItem *node);
+
+//
+// actions
+//
+ void acceptActionGroup(DomActionGroup *node);
+ void acceptAction(DomAction *node);
+ void acceptActionRef(DomActionRef *node);
+
+//
+// tab stops
+//
+ void acceptTabStops(DomTabStops *tabStops);
+
+//
+// custom widgets
+//
+ void acceptCustomWidgets(DomCustomWidgets *node);
+ void acceptCustomWidget(DomCustomWidget *node);
+
+//
+// layout defaults/functions
+//
+ void acceptLayoutDefault(DomLayoutDefault *node) { m_LayoutDefaultHandler.acceptLayoutDefault(node); }
+ void acceptLayoutFunction(DomLayoutFunction *node) { m_LayoutDefaultHandler.acceptLayoutFunction(node); }
+
+//
+// signal/slot connections
+//
+ void acceptConnection(DomConnection *connection);
+
+//
+// images
+//
+ void acceptImage(DomImage *image);
+
+ enum {
+ Use43UiFile = 0,
+ TopLevelMargin,
+ ChildMargin,
+ SubLayoutMargin
+ };
+
+private:
+ static QString domColor2QString(const DomColor *c);
+
+ QString iconCall(const DomProperty *prop);
+ QString pixCall(const DomProperty *prop) const;
+ QString pixCall(const QString &type, const QString &text) const;
+ QString trCall(const QString &str, const QString &comment = QString()) const;
+ QString trCall(DomString *str, const QString &defaultString = QString()) const;
+ QString noTrCall(DomString *str, const QString &defaultString = QString()) const;
+ QString autoTrCall(DomString *str, const QString &defaultString = QString()) const;
+ QTextStream &autoTrOutput(DomString *str, const QString &defaultString = QString());
+ // Apply a comma-separated list of values using a function "setSomething(int idx, value)"
+ void writePropertyList(const QString &varName, const QString &setFunction, const QString &value, const QString &defaultValue);
+
+ enum { WritePropertyIgnoreMargin = 1, WritePropertyIgnoreSpacing = 2, WritePropertyIgnoreObjectName = 4 };
+ void writeProperties(const QString &varName, const QString &className, const DomPropertyList &lst, unsigned flags = 0);
+ void writeColorGroup(DomColorGroup *colorGroup, const QString &group, const QString &paletteName);
+ void writeBrush(const DomBrush *brush, const QString &brushName);
+
+//
+// special initialization
+//
+ class Item {
+ public:
+ Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver);
+ ~Item();
+ enum EmptyItemPolicy {
+ DontConstruct,
+ ConstructItemOnly,
+ ConstructItemAndVariable
+ };
+ QString writeSetupUi(const QString &parent, EmptyItemPolicy emptyItemPolicy = ConstructItemOnly);
+ void writeRetranslateUi(const QString &parentPath);
+ void addSetter(const QString &setter, const QString &directive = QString(), bool translatable = false); // don't call it if you already added *this as a child of another Item
+ void addChild(Item *child); // all setters should already been added
+ int setupUiCount() const { return m_setupUiData.setters.count(); }
+ int retranslateUiCount() const { return m_retranslateUiData.setters.count(); }
+ private:
+ struct ItemData {
+ ItemData() : policy(DontGenerate) {}
+ QMultiMap<QString, QString> setters; // directive to setter
+ QSet<QString> directives;
+ enum TemporaryVariableGeneratorPolicy { // policies with priority, number describes the priority
+ DontGenerate = 1,
+ GenerateWithMultiDirective = 2,
+ Generate = 3
+ } policy;
+ };
+ ItemData m_setupUiData;
+ ItemData m_retranslateUiData;
+ QList<Item *> m_children;
+ Item *m_parent;
+
+ const QString m_itemClassName;
+ const QString m_indent;
+ QTextStream &m_setupUiStream;
+ QTextStream &m_retranslateUiStream;
+ Driver *m_driver;
+ };
+
+ void addInitializer(Item *item,
+ const QString &name, int column, const QString &value, const QString &directive = QString(), bool translatable = false) const;
+ void addQtFlagsInitializer(Item *item, const DomPropertyMap &properties,
+ const QString &name, int column = -1) const;
+ void addQtEnumInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column = -1) const;
+ void addBrushInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column = -1);
+ void addStringInitializer(Item *item,
+ const DomPropertyMap &properties, const QString &name, int column = -1, const QString &directive = QString()) const;
+ void addCommonInitializers(Item *item,
+ const DomPropertyMap &properties, int column = -1);
+
+ void initializeMenu(DomWidget *w, const QString &parentWidget);
+ void initializeComboBox(DomWidget *w);
+ void initializeComboBox3(DomWidget *w);
+ void initializeListWidget(DomWidget *w);
+ void initializeTreeWidget(DomWidget *w);
+ QList<Item *> initializeTreeWidgetItems(const QList<DomItem *> &domItems);
+ void initializeTableWidget(DomWidget *w);
+
+ QString disableSorting(DomWidget *w, const QString &varName);
+ void enableSorting(DomWidget *w, const QString &varName, const QString &tempName);
+
+//
+// special initialization for the Q3 support classes
+//
+ void initializeQ3ListBox(DomWidget *w);
+ void initializeQ3IconView(DomWidget *w);
+ void initializeQ3ListView(DomWidget *w);
+ void initializeQ3ListViewItems(const QString &className, const QString &varName, const QList<DomItem*> &items);
+ void initializeQ3Table(DomWidget *w);
+ void initializeQ3TableItems(const QString &className, const QString &varName, const QList<DomItem*> &items);
+
+//
+// Sql
+//
+ void initializeQ3SqlDataTable(DomWidget *w);
+ void initializeQ3SqlDataBrowser(DomWidget *w);
+
+ QString findDeclaration(const QString &name);
+ DomWidget *findWidget(const QLatin1String &widgetClass);
+ DomImage *findImage(const QString &name) const;
+
+ bool isValidObject(const QString &name) const;
+
+private:
+ QString writeFontProperties(const DomFont *f);
+ QString writeIconProperties(const DomResourceIcon *i);
+ QString writeSizePolicy(const DomSizePolicy *sp);
+ QString writeBrushInitialization(const DomBrush *brush);
+ void addButtonGroup(const DomWidget *node, const QString &varName);
+ void addWizardPage(const QString &pageVarName, const DomWidget *page, const QString &parentWidget);
+
+ const Uic *m_uic;
+ Driver *m_driver;
+ QTextStream &m_output;
+ const Option &m_option;
+ QString m_indent;
+ QString m_dindent;
+ bool m_stdsetdef;
+
+ struct Buddy
+ {
+ Buddy(const QString &oN, const QString &b)
+ : objName(oN), buddy(b) {}
+ QString objName;
+ QString buddy;
+ };
+
+ QStack<DomWidget*> m_widgetChain;
+ QStack<DomLayout*> m_layoutChain;
+ QStack<DomActionGroup*> m_actionGroupChain;
+ QList<Buddy> m_buddies;
+
+ QSet<QString> m_buttonGroups;
+ QHash<QString, DomWidget*> m_registeredWidgets;
+ QHash<QString, DomImage*> m_registeredImages;
+ QHash<QString, DomAction*> m_registeredActions;
+ typedef QHash<uint, QString> ColorBrushHash;
+ ColorBrushHash m_colorBrushHash;
+ // Map from font properties to font variable name for reuse
+ // Map from size policy to variable for reuse
+#if defined(Q_OS_MAC) && defined(Q_CC_GNU) && (__GNUC__ == 3 && __GNUC_MINOR__ == 3)
+ typedef QHash<FontHandle, QString> FontPropertiesNameMap;
+ typedef QHash<IconHandle, QString> IconPropertiesNameMap;
+ typedef QHash<SizePolicyHandle, QString> SizePolicyNameMap;
+#else
+ typedef QMap<FontHandle, QString> FontPropertiesNameMap;
+ typedef QMap<IconHandle, QString> IconPropertiesNameMap;
+ typedef QMap<SizePolicyHandle, QString> SizePolicyNameMap;
+#endif
+ FontPropertiesNameMap m_fontPropertiesNameMap;
+ IconPropertiesNameMap m_iconPropertiesNameMap;
+ SizePolicyNameMap m_sizePolicyNameMap;
+
+ class LayoutDefaultHandler {
+ public:
+ LayoutDefaultHandler();
+ void acceptLayoutDefault(DomLayoutDefault *node);
+ void acceptLayoutFunction(DomLayoutFunction *node);
+
+ // Write out the layout margin and spacing properties applying the defaults.
+ void writeProperties(const QString &indent, const QString &varName,
+ const DomPropertyMap &pm, int marginType,
+ bool suppressMarginDefault, QTextStream &str) const;
+ private:
+ void writeProperty(int p, const QString &indent, const QString &objectName, const DomPropertyMap &pm,
+ const QString &propertyName, const QString &setter, int defaultStyleValue,
+ bool suppressDefault, QTextStream &str) const;
+
+ enum Properties { Margin, Spacing, NumProperties };
+ enum StateFlags { HasDefaultValue = 1, HasDefaultFunction = 2};
+ unsigned m_state[NumProperties];
+ int m_defaultValues[NumProperties];
+ QString m_functions[NumProperties];
+ };
+
+ // layout defaults
+ LayoutDefaultHandler m_LayoutDefaultHandler;
+ int m_layoutMarginType;
+
+ QString m_generatedClass;
+ QString m_mainFormVarName;
+ bool m_mainFormUsedInRetranslateUi;
+
+ QString m_delayedInitialization;
+ QTextStream m_delayedOut;
+
+ QString m_refreshInitialization;
+ QTextStream m_refreshOut;
+
+ QString m_delayedActionInitialization;
+ QTextStream m_actionOut;
+ const bool m_activateScripts;
+
+ bool m_layoutWidget;
+ bool m_firstThemeIcon;
+};
+
+} // namespace CPP
+
+QT_END_NAMESPACE
+
+#endif // CPPWRITEINITIALIZATION_H
diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp
new file mode 100644
index 0000000000..320995eadd
--- /dev/null
+++ b/src/tools/uic/customwidgetsinfo.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "customwidgetsinfo.h"
+#include "driver.h"
+#include "ui4.h"
+#include "utils.h"
+
+QT_BEGIN_NAMESPACE
+
+CustomWidgetsInfo::CustomWidgetsInfo()
+{
+}
+
+void CustomWidgetsInfo::acceptUI(DomUI *node)
+{
+ m_customWidgets.clear();
+
+ if (node->elementCustomWidgets())
+ acceptCustomWidgets(node->elementCustomWidgets());
+}
+
+void CustomWidgetsInfo::acceptCustomWidgets(DomCustomWidgets *node)
+{
+ TreeWalker::acceptCustomWidgets(node);
+}
+
+void CustomWidgetsInfo::acceptCustomWidget(DomCustomWidget *node)
+{
+ if (node->elementClass().isEmpty())
+ return;
+
+ m_customWidgets.insert(node->elementClass(), node);
+}
+
+bool CustomWidgetsInfo::extends(const QString &classNameIn, const QLatin1String &baseClassName) const
+{
+ if (classNameIn == baseClassName)
+ return true;
+
+ QString className = classNameIn;
+ while (const DomCustomWidget *c = customWidget(className)) {
+ const QString extends = c->elementExtends();
+ if (className == extends) // Faulty legacy custom widget entries exist.
+ return false;
+ if (extends == baseClassName)
+ return true;
+ className = extends;
+ }
+ return false;
+}
+
+bool CustomWidgetsInfo::isCustomWidgetContainer(const QString &className) const
+{
+ if (const DomCustomWidget *dcw = m_customWidgets.value(className, 0))
+ if (dcw->hasElementContainer())
+ return dcw->elementContainer() != 0;
+ return false;
+}
+
+QString CustomWidgetsInfo::realClassName(const QString &className) const
+{
+ if (className == QLatin1String("Line"))
+ return QLatin1String("QFrame");
+
+ return className;
+}
+
+DomScript *CustomWidgetsInfo::customWidgetScript(const QString &name) const
+{
+ if (m_customWidgets.empty())
+ return 0;
+
+ const NameCustomWidgetMap::const_iterator it = m_customWidgets.constFind(name);
+ if (it == m_customWidgets.constEnd())
+ return 0;
+
+ return it.value()->elementScript();
+}
+
+QString CustomWidgetsInfo::customWidgetAddPageMethod(const QString &name) const
+{
+ if (DomCustomWidget *dcw = m_customWidgets.value(name, 0))
+ return dcw->elementAddPageMethod();
+ return QString();
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h
new file mode 100644
index 0000000000..198e92cfac
--- /dev/null
+++ b/src/tools/uic/customwidgetsinfo.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CUSTOMWIDGETSINFO_H
+#define CUSTOMWIDGETSINFO_H
+
+#include "treewalker.h"
+#include <QtCore/QStringList>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class Driver;
+class DomScript;
+
+class CustomWidgetsInfo : public TreeWalker
+{
+public:
+ CustomWidgetsInfo();
+
+ void acceptUI(DomUI *node);
+
+ void acceptCustomWidgets(DomCustomWidgets *node);
+ void acceptCustomWidget(DomCustomWidget *node);
+
+ inline QStringList customWidgets() const
+ { return m_customWidgets.keys(); }
+
+ inline bool hasCustomWidget(const QString &name) const
+ { return m_customWidgets.contains(name); }
+
+ inline DomCustomWidget *customWidget(const QString &name) const
+ { return m_customWidgets.value(name); }
+
+ DomScript *customWidgetScript(const QString &name) const;
+
+ QString customWidgetAddPageMethod(const QString &name) const;
+
+ QString realClassName(const QString &className) const;
+
+ bool extends(const QString &className, const QLatin1String &baseClassName) const;
+
+ bool isCustomWidgetContainer(const QString &className) const;
+
+private:
+ typedef QMap<QString, DomCustomWidget*> NameCustomWidgetMap;
+ NameCustomWidgetMap m_customWidgets;
+ bool m_scriptsActivated;
+};
+
+QT_END_NAMESPACE
+
+#endif // CUSTOMWIDGETSINFO_H
diff --git a/src/tools/uic/databaseinfo.cpp b/src/tools/uic/databaseinfo.cpp
new file mode 100644
index 0000000000..c4fa88b585
--- /dev/null
+++ b/src/tools/uic/databaseinfo.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "databaseinfo.h"
+#include "driver.h"
+#include "ui4.h"
+#include "utils.h"
+
+QT_BEGIN_NAMESPACE
+
+DatabaseInfo::DatabaseInfo(Driver *drv)
+ : driver(drv)
+{
+}
+
+void DatabaseInfo::acceptUI(DomUI *node)
+{
+ m_connections.clear();
+ m_cursors.clear();
+ m_fields.clear();
+
+ TreeWalker::acceptUI(node);
+
+ m_connections = unique(m_connections);
+}
+
+void DatabaseInfo::acceptWidget(DomWidget *node)
+{
+ QHash<QString, DomProperty*> properties = propertyMap(node->elementProperty());
+
+ DomProperty *frameworkCode = properties.value(QLatin1String("frameworkCode"), 0);
+ if (frameworkCode && toBool(frameworkCode->elementBool()) == false)
+ return;
+
+ DomProperty *db = properties.value(QLatin1String("database"), 0);
+ if (db && db->elementStringList()) {
+ QStringList info = db->elementStringList()->elementString();
+
+ QString connection = info.size() > 0 ? info.at(0) : QString();
+ if (connection.isEmpty())
+ return;
+ m_connections.append(connection);
+
+ QString table = info.size() > 1 ? info.at(1) : QString();
+ if (table.isEmpty())
+ return;
+ m_cursors[connection].append(table);
+
+ QString field = info.size() > 2 ? info.at(2) : QString();
+ if (field.isEmpty())
+ return;
+ m_fields[connection].append(field);
+ }
+
+ TreeWalker::acceptWidget(node);
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/databaseinfo.h b/src/tools/uic/databaseinfo.h
new file mode 100644
index 0000000000..b52c92826f
--- /dev/null
+++ b/src/tools/uic/databaseinfo.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DATABASEINFO_H
+#define DATABASEINFO_H
+
+#include "treewalker.h"
+#include <QtCore/QStringList>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class Driver;
+
+class DatabaseInfo : public TreeWalker
+{
+public:
+ DatabaseInfo(Driver *driver);
+
+ void acceptUI(DomUI *node);
+ void acceptWidget(DomWidget *node);
+
+ inline QStringList connections() const
+ { return m_connections; }
+
+ inline QStringList cursors(const QString &connection) const
+ { return m_cursors.value(connection); }
+
+ inline QStringList fields(const QString &connection) const
+ { return m_fields.value(connection); }
+
+private:
+ Driver *driver;
+ QStringList m_connections;
+ QMap<QString, QStringList> m_cursors;
+ QMap<QString, QStringList> m_fields;
+};
+
+QT_END_NAMESPACE
+
+#endif // DATABASEINFO_H
diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp
new file mode 100644
index 0000000000..e5365886a1
--- /dev/null
+++ b/src/tools/uic/driver.cpp
@@ -0,0 +1,381 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "driver.h"
+#include "uic.h"
+#include "ui4.h"
+
+#include <QtCore/QRegExp>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+Driver::Driver()
+ : m_stdout(stdout, QFile::WriteOnly | QFile::Text)
+{
+ m_output = &m_stdout;
+}
+
+Driver::~Driver()
+{
+}
+
+QString Driver::findOrInsertWidget(DomWidget *ui_widget)
+{
+ if (!m_widgets.contains(ui_widget))
+ m_widgets.insert(ui_widget, unique(ui_widget->attributeName(), ui_widget->attributeClass()));
+
+ return m_widgets.value(ui_widget);
+}
+
+QString Driver::findOrInsertSpacer(DomSpacer *ui_spacer)
+{
+ if (!m_spacers.contains(ui_spacer)) {
+ const QString name = ui_spacer->hasAttributeName() ? ui_spacer->attributeName() : QString();
+ m_spacers.insert(ui_spacer, unique(name, QLatin1String("QSpacerItem")));
+ }
+
+ return m_spacers.value(ui_spacer);
+}
+
+QString Driver::findOrInsertLayout(DomLayout *ui_layout)
+{
+ if (!m_layouts.contains(ui_layout)) {
+ const QString name = ui_layout->hasAttributeName() ? ui_layout->attributeName() : QString();
+ m_layouts.insert(ui_layout, unique(name, ui_layout->attributeClass()));
+ }
+
+ return m_layouts.value(ui_layout);
+}
+
+QString Driver::findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem)
+{
+ switch (ui_layoutItem->kind()) {
+ case DomLayoutItem::Widget:
+ return findOrInsertWidget(ui_layoutItem->elementWidget());
+ case DomLayoutItem::Spacer:
+ return findOrInsertSpacer(ui_layoutItem->elementSpacer());
+ case DomLayoutItem::Layout:
+ return findOrInsertLayout(ui_layoutItem->elementLayout());
+ case DomLayoutItem::Unknown:
+ break;
+ }
+
+ Q_ASSERT( 0 );
+
+ return QString();
+}
+
+QString Driver::findOrInsertActionGroup(DomActionGroup *ui_group)
+{
+ if (!m_actionGroups.contains(ui_group))
+ m_actionGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QActionGroup")));
+
+ return m_actionGroups.value(ui_group);
+}
+
+QString Driver::findOrInsertAction(DomAction *ui_action)
+{
+ if (!m_actions.contains(ui_action))
+ m_actions.insert(ui_action, unique(ui_action->attributeName(), QLatin1String("QAction")));
+
+ return m_actions.value(ui_action);
+}
+
+QString Driver::findOrInsertButtonGroup(const DomButtonGroup *ui_group)
+{
+ ButtonGroupNameHash::iterator it = m_buttonGroups.find(ui_group);
+ if (it == m_buttonGroups.end())
+ it = m_buttonGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QButtonGroup")));
+ return it.value();
+}
+
+// Find a group by its non-uniqified name
+const DomButtonGroup *Driver::findButtonGroup(const QString &attributeName) const
+{
+ const ButtonGroupNameHash::const_iterator cend = m_buttonGroups.constEnd();
+ for (ButtonGroupNameHash::const_iterator it = m_buttonGroups.constBegin(); it != cend; ++it)
+ if (it.key()->attributeName() == attributeName)
+ return it.key();
+ return 0;
+}
+
+
+QString Driver::findOrInsertName(const QString &name)
+{
+ return unique(name);
+}
+
+QString Driver::normalizedName(const QString &name)
+{
+ QString result = name;
+ QChar *data = result.data();
+ for (int i = name.size(); --i >= 0; ++data) {
+ if (!data->isLetterOrNumber())
+ *data = QLatin1Char('_');
+ }
+ return result;
+}
+
+QString Driver::unique(const QString &instanceName, const QString &className)
+{
+ QString name;
+ bool alreadyUsed = false;
+
+ if (instanceName.size()) {
+ int id = 1;
+ name = instanceName;
+ name = normalizedName(name);
+ QString base = name;
+
+ while (m_nameRepository.contains(name)) {
+ alreadyUsed = true;
+ name = base + QString::number(id++);
+ }
+ } else if (className.size()) {
+ name = unique(qtify(className));
+ } else {
+ name = unique(QLatin1String("var"));
+ }
+
+ if (alreadyUsed && className.size()) {
+ fprintf(stderr, "%s: Warning: The name '%s' (%s) is already in use, defaulting to '%s'.\n",
+ qPrintable(m_option.messagePrefix()),
+ qPrintable(instanceName), qPrintable(className),
+ qPrintable(name));
+ }
+
+ m_nameRepository.insert(name, true);
+ return name;
+}
+
+QString Driver::qtify(const QString &name)
+{
+ QString qname = name;
+
+ if (qname.at(0) == QLatin1Char('Q') || qname.at(0) == QLatin1Char('K'))
+ qname = qname.mid(1);
+
+ int i=0;
+ while (i < qname.length()) {
+ if (qname.at(i).toLower() != qname.at(i))
+ qname[i] = qname.at(i).toLower();
+ else
+ break;
+
+ ++i;
+ }
+
+ return qname;
+}
+
+static bool isAnsiCCharacter(const QChar& c)
+{
+ return (c.toUpper() >= QLatin1Char('A') && c.toUpper() <= QLatin1Char('Z'))
+ || c.isDigit() || c == QLatin1Char('_');
+}
+
+QString Driver::headerFileName() const
+{
+ QString name = m_option.outputFile;
+
+ if (name.isEmpty()) {
+ name = QLatin1String("ui_"); // ### use ui_ as prefix.
+ name.append(m_option.inputFile);
+ }
+
+ return headerFileName(name);
+}
+
+QString Driver::headerFileName(const QString &fileName)
+{
+ if (fileName.isEmpty())
+ return headerFileName(QLatin1String("noname"));
+
+ QFileInfo info(fileName);
+ QString baseName = info.baseName();
+ // Transform into a valid C++ identifier
+ if (!baseName.isEmpty() && baseName.at(0).isDigit())
+ baseName.prepend(QLatin1Char('_'));
+ for (int i = 0; i < baseName.size(); ++i) {
+ QChar c = baseName.at(i);
+ if (!isAnsiCCharacter(c)) {
+ // Replace character by its unicode value
+ QString hex = QString::number(c.unicode(), 16);
+ baseName.replace(i, 1, QLatin1Char('_') + hex + QLatin1Char('_'));
+ i += hex.size() + 1;
+ }
+ }
+ return baseName.toUpper() + QLatin1String("_H");
+}
+
+bool Driver::printDependencies(const QString &fileName)
+{
+ Q_ASSERT(m_option.dependencies == true);
+
+ m_option.inputFile = fileName;
+
+ Uic tool(this);
+ return tool.printDependencies();
+}
+
+bool Driver::uic(const QString &fileName, DomUI *ui, QTextStream *out)
+{
+ m_option.inputFile = fileName;
+
+ QTextStream *oldOutput = m_output;
+
+ m_output = out != 0 ? out : &m_stdout;
+
+ Uic tool(this);
+ bool rtn = false;
+#ifdef QT_UIC_CPP_GENERATOR
+ rtn = tool.write(ui);
+#else
+ Q_UNUSED(ui);
+ fprintf(stderr, "uic: option to generate cpp code not compiled in [%s:%d]\n",
+ __FILE__, __LINE__);
+#endif
+
+ m_output = oldOutput;
+
+ return rtn;
+}
+
+bool Driver::uic(const QString &fileName, QTextStream *out)
+{
+ QFile f;
+ if (fileName.isEmpty())
+ f.open(stdin, QIODevice::ReadOnly);
+ else {
+ f.setFileName(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ return false;
+ }
+
+ m_option.inputFile = fileName;
+
+ QTextStream *oldOutput = m_output;
+ bool deleteOutput = false;
+
+ if (out) {
+ m_output = out;
+ } else {
+#ifdef Q_WS_WIN
+ // As one might also redirect the output to a file on win,
+ // we should not create the textstream with QFile::Text flag.
+ // The redirected file is opened in TextMode and this will
+ // result in broken line endings as writing will replace \n again.
+ m_output = new QTextStream(stdout, QIODevice::WriteOnly);
+#else
+ m_output = new QTextStream(stdout, QIODevice::WriteOnly | QFile::Text);
+#endif
+ deleteOutput = true;
+ }
+
+ Uic tool(this);
+ bool rtn = tool.write(&f);
+ f.close();
+
+ if (deleteOutput)
+ delete m_output;
+
+ m_output = oldOutput;
+
+ return rtn;
+}
+
+void Driver::reset()
+{
+ Q_ASSERT( m_output == 0 );
+
+ m_option = Option();
+ m_output = 0;
+ m_problems.clear();
+
+ QStringList m_problems;
+
+ m_widgets.clear();
+ m_spacers.clear();
+ m_layouts.clear();
+ m_actionGroups.clear();
+ m_actions.clear();
+ m_nameRepository.clear();
+ m_pixmaps.clear();
+}
+
+void Driver::insertPixmap(const QString &pixmap)
+{
+ m_pixmaps.insert(pixmap, true);
+}
+
+bool Driver::containsPixmap(const QString &pixmap) const
+{
+ return m_pixmaps.contains(pixmap);
+}
+
+DomWidget *Driver::widgetByName(const QString &name) const
+{
+ return m_widgets.key(name);
+}
+
+DomSpacer *Driver::spacerByName(const QString &name) const
+{
+ return m_spacers.key(name);
+}
+
+DomLayout *Driver::layoutByName(const QString &name) const
+{
+ return m_layouts.key(name);
+}
+
+DomActionGroup *Driver::actionGroupByName(const QString &name) const
+{
+ return m_actionGroups.key(name);
+}
+
+DomAction *Driver::actionByName(const QString &name) const
+{
+ return m_actions.key(name);
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h
new file mode 100644
index 0000000000..f152343328
--- /dev/null
+++ b/src/tools/uic/driver.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+#include "option.h"
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class DomUI;
+class DomWidget;
+class DomSpacer;
+class DomLayout;
+class DomLayoutItem;
+class DomActionGroup;
+class DomAction;
+class DomButtonGroup;
+
+class Driver
+{
+public:
+ Driver();
+ virtual ~Driver();
+
+ // tools
+ bool printDependencies(const QString &fileName);
+ bool uic(const QString &fileName, QTextStream *output = 0);
+ bool uic(const QString &fileName, DomUI *ui, QTextStream *output = 0);
+
+ // configuration
+ inline QTextStream &output() const { return *m_output; }
+ inline Option &option() { return m_option; }
+
+ // initialization
+ void reset();
+
+ // error
+ inline QStringList problems() { return m_problems; }
+ inline void addProblem(const QString &problem) { m_problems.append(problem); }
+
+ // utils
+ static QString headerFileName(const QString &fileName);
+ QString headerFileName() const;
+
+ static QString normalizedName(const QString &name);
+ static QString qtify(const QString &name);
+ QString unique(const QString &instanceName=QString(),
+ const QString &className=QString());
+
+ // symbol table
+ QString findOrInsertWidget(DomWidget *ui_widget);
+ QString findOrInsertSpacer(DomSpacer *ui_spacer);
+ QString findOrInsertLayout(DomLayout *ui_layout);
+ QString findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem);
+ QString findOrInsertName(const QString &name);
+ QString findOrInsertActionGroup(DomActionGroup *ui_group);
+ QString findOrInsertAction(DomAction *ui_action);
+ QString findOrInsertButtonGroup(const DomButtonGroup *ui_group);
+ // Find a group by its non-uniqified name
+ const DomButtonGroup *findButtonGroup(const QString &attributeName) const;
+
+ inline bool hasName(const QString &name) const
+ { return m_nameRepository.contains(name); }
+
+ DomWidget *widgetByName(const QString &name) const;
+ DomSpacer *spacerByName(const QString &name) const;
+ DomLayout *layoutByName(const QString &name) const;
+ DomActionGroup *actionGroupByName(const QString &name) const;
+ DomAction *actionByName(const QString &name) const;
+
+ // pixmap
+ void insertPixmap(const QString &pixmap);
+ bool containsPixmap(const QString &pixmap) const;
+
+private:
+ Option m_option;
+ QTextStream m_stdout;
+ QTextStream *m_output;
+
+ QStringList m_problems;
+
+ // symbol tables
+ QHash<DomWidget*, QString> m_widgets;
+ QHash<DomSpacer*, QString> m_spacers;
+ QHash<DomLayout*, QString> m_layouts;
+ QHash<DomActionGroup*, QString> m_actionGroups;
+ typedef QHash<const DomButtonGroup*, QString> ButtonGroupNameHash;
+ ButtonGroupNameHash m_buttonGroups;
+ QHash<DomAction*, QString> m_actions;
+ QHash<QString, bool> m_nameRepository;
+ QHash<QString, bool> m_pixmaps;
+};
+
+QT_END_NAMESPACE
+
+#endif // DRIVER_H
diff --git a/src/tools/uic/globaldefs.h b/src/tools/uic/globaldefs.h
new file mode 100644
index 0000000000..9ab758b731
--- /dev/null
+++ b/src/tools/uic/globaldefs.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLOBALDEFS_H
+#define GLOBALDEFS_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+enum { BOXLAYOUT_DEFAULT_MARGIN = 11 };
+enum { BOXLAYOUT_DEFAULT_SPACING = 6 };
+
+QT_END_NAMESPACE
+
+#endif // GLOBALDEFS_H
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
new file mode 100644
index 0000000000..f8d4c40433
--- /dev/null
+++ b/src/tools/uic/main.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "uic.h"
+#include "option.h"
+#include "driver.h"
+#include "../../corelib/global/qconfig.cpp"
+#include <QtCore/QFile>
+#include <QtCore/QDir>
+#include <QtCore/QTextStream>
+#include <QtCore/QTextCodec>
+
+QT_BEGIN_NAMESPACE
+
+static const char *error = 0;
+
+void showHelp(const char *appName)
+{
+ fprintf(stderr, "Qt User Interface Compiler version %s\n", QT_VERSION_STR);
+ if (error)
+ fprintf(stderr, "%s: %s\n", appName, error);
+
+ fprintf(stderr, "Usage: %s [options] <uifile>\n\n"
+ " -h, -help display this help and exit\n"
+ " -v, -version display version\n"
+ " -d, -dependencies display the dependencies\n"
+ " -o <file> place the output into <file>\n"
+ " -tr <func> use func() for i18n\n"
+ " -p, -no-protection disable header protection\n"
+ " -n, -no-implicit-includes disable generation of #include-directives\n"
+ " for forms generated by uic3\n"
+ " -g <name> change generator\n"
+ "\n", appName);
+}
+
+int runUic(int argc, char *argv[])
+{
+ Driver driver;
+
+ const char *fileName = 0;
+
+ int arg = 1;
+ while (arg < argc) {
+ QString opt = QString::fromLocal8Bit(argv[arg]);
+ if (opt == QLatin1String("-h") || opt == QLatin1String("-help")) {
+ showHelp(argv[0]);
+ return 0;
+ } else if (opt == QLatin1String("-d") || opt == QLatin1String("-dependencies")) {
+ driver.option().dependencies = true;
+ } else if (opt == QLatin1String("-v") || opt == QLatin1String("-version")) {
+ fprintf(stderr, "Qt User Interface Compiler version %s\n", QT_VERSION_STR);
+ return 0;
+ } else if (opt == QLatin1String("-o") || opt == QLatin1String("-output")) {
+ ++arg;
+ if (!argv[arg]) {
+ showHelp(argv[0]);
+ return 1;
+ }
+ driver.option().outputFile = QFile::decodeName(argv[arg]);
+ } else if (opt == QLatin1String("-p") || opt == QLatin1String("-no-protection")) {
+ driver.option().headerProtection = false;
+ } else if (opt == QLatin1String("-n") || opt == QLatin1String("-no-implicit-includes")) {
+ driver.option().implicitIncludes = false;
+ } else if (opt == QLatin1String("-postfix")) {
+ ++arg;
+ if (!argv[arg]) {
+ showHelp(argv[0]);
+ return 1;
+ }
+ driver.option().postfix = QLatin1String(argv[arg]);
+ } else if (opt == QLatin1String("-3")) {
+ ++arg;
+ if (!argv[arg]) {
+ showHelp(argv[0]);
+ return 1;
+ }
+ driver.option().uic3 = QFile::decodeName(argv[arg]);
+ } else if (opt == QLatin1String("-tr") || opt == QLatin1String("-translate")) {
+ ++arg;
+ if (!argv[arg]) {
+ showHelp(argv[0]);
+ return 1;
+ }
+ driver.option().translateFunction = QLatin1String(argv[arg]);
+ } else if (opt == QLatin1String("-g") || opt == QLatin1String("-generator")) {
+ ++arg;
+ if (!argv[arg]) {
+ showHelp(argv[0]);
+ return 1;
+ }
+ QString name = QString::fromLocal8Bit(argv[arg]).toLower ();
+ driver.option().generator = (name == QLatin1String ("java")) ? Option::JavaGenerator : Option::CppGenerator;
+ } else if (!fileName) {
+ fileName = argv[arg];
+ } else {
+ showHelp(argv[0]);
+ return 1;
+ }
+
+ ++arg;
+ }
+
+ QString inputFile;
+ if (fileName)
+ inputFile = QString::fromLocal8Bit(fileName);
+ else
+ driver.option().headerProtection = false;
+
+ if (driver.option().dependencies) {
+ return !driver.printDependencies(inputFile);
+ }
+
+ QTextStream *out = 0;
+ QFile f;
+ if (driver.option().outputFile.size()) {
+ f.setFileName(driver.option().outputFile);
+ if (!f.open(QIODevice::WriteOnly | QFile::Text)) {
+ fprintf(stderr, "Could not create output file\n");
+ return 1;
+ }
+ out = new QTextStream(&f);
+ out->setCodec(QTextCodec::codecForName("UTF-8"));
+ }
+
+ bool rtn = driver.uic(inputFile, out);
+ delete out;
+
+ if (!rtn) {
+ if (driver.option().outputFile.size()) {
+ f.close();
+ f.remove();
+ }
+ fprintf(stderr, "File '%s' is not valid\n", inputFile.isEmpty() ? "<stdin>" : inputFile.toLocal8Bit().constData());
+ }
+
+ return !rtn;
+}
+
+QT_END_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ return QT_PREPEND_NAMESPACE(runUic)(argc, argv);
+}
diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h
new file mode 100644
index 0000000000..976b531c4b
--- /dev/null
+++ b/src/tools/uic/option.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPTION_H
+#define OPTION_H
+
+#include <QtCore/QString>
+#include <QtCore/QDir>
+
+QT_BEGIN_NAMESPACE
+
+struct Option
+{
+ enum Generator
+ {
+ CppGenerator,
+ JavaGenerator
+ };
+
+ unsigned int headerProtection : 1;
+ unsigned int copyrightHeader : 1;
+ unsigned int generateImplemetation : 1;
+ unsigned int generateNamespace : 1;
+ unsigned int autoConnection : 1;
+ unsigned int dependencies : 1;
+ unsigned int extractImages : 1;
+ unsigned int limitXPM_LineLength : 1;
+ unsigned int implicitIncludes: 1;
+ Generator generator;
+
+ QString inputFile;
+ QString outputFile;
+ QString qrcOutputFile;
+ QString indent;
+ QString prefix;
+ QString postfix;
+ QString translateFunction;
+ QString uic3;
+#ifdef QT_UIC_JAVA_GENERATOR
+ QString javaPackage;
+ QString javaOutputDirectory;
+#endif
+
+ Option()
+ : headerProtection(1),
+ copyrightHeader(1),
+ generateImplemetation(0),
+ generateNamespace(1),
+ autoConnection(1),
+ dependencies(0),
+ extractImages(0),
+ limitXPM_LineLength(0),
+ implicitIncludes(1),
+ generator(CppGenerator),
+ prefix(QLatin1String("Ui_"))
+ { indent.fill(QLatin1Char(' '), 4); }
+
+ QString messagePrefix() const
+ {
+ return inputFile.isEmpty() ?
+ QString(QLatin1String("stdin")) :
+ QDir::toNativeSeparators(inputFile);
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // OPTION_H
diff --git a/src/tools/uic/treewalker.cpp b/src/tools/uic/treewalker.cpp
new file mode 100644
index 0000000000..ed72284d0c
--- /dev/null
+++ b/src/tools/uic/treewalker.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "treewalker.h"
+#include "ui4.h"
+
+QT_BEGIN_NAMESPACE
+
+void TreeWalker::acceptUI(DomUI *ui)
+{
+ acceptWidget(ui->elementWidget());
+ if (const DomButtonGroups *domButtonGroups = ui->elementButtonGroups())
+ acceptButtonGroups(domButtonGroups);
+
+ acceptTabStops(ui->elementTabStops());
+
+ if (ui->elementImages())
+ acceptImages(ui->elementImages());
+}
+
+void TreeWalker::acceptLayoutDefault(DomLayoutDefault *layoutDefault)
+{
+ Q_UNUSED(layoutDefault);
+}
+
+void TreeWalker::acceptLayoutFunction(DomLayoutFunction *layoutFunction)
+{
+ Q_UNUSED(layoutFunction);
+}
+
+void TreeWalker::acceptTabStops(DomTabStops *tabStops)
+{
+ Q_UNUSED(tabStops);
+}
+
+void TreeWalker::acceptLayout(DomLayout *layout)
+{
+ for (int i=0; i<layout->elementProperty().size(); ++i)
+ acceptProperty(layout->elementProperty().at(i));
+
+ for (int i=0; i<layout->elementItem().size(); ++i)
+ acceptLayoutItem(layout->elementItem().at(i));
+}
+
+void TreeWalker::acceptLayoutItem(DomLayoutItem *layoutItem)
+{
+ switch (layoutItem->kind()) {
+ case DomLayoutItem::Widget:
+ acceptWidget(layoutItem->elementWidget());
+ return;
+ case DomLayoutItem::Layout:
+ acceptLayout(layoutItem->elementLayout());
+ return;
+ case DomLayoutItem::Spacer:
+ acceptSpacer(layoutItem->elementSpacer());
+ return;
+ case DomLayoutItem::Unknown:
+ break;
+ }
+
+ Q_ASSERT( 0 );
+}
+
+void TreeWalker::acceptWidget(DomWidget *widget)
+{
+ for (int i=0; i<widget->elementAction().size(); ++i)
+ acceptAction(widget->elementAction().at(i));
+
+ for (int i=0; i<widget->elementActionGroup().size(); ++i)
+ acceptActionGroup(widget->elementActionGroup().at(i));
+
+ for (int i=0; i<widget->elementAddAction().size(); ++i)
+ acceptActionRef(widget->elementAddAction().at(i));
+
+ for (int i=0; i<widget->elementProperty().size(); ++i)
+ acceptProperty(widget->elementProperty().at(i));
+
+
+
+ // recurse down
+ DomWidgets childWidgets;
+ for (int i=0; i<widget->elementWidget().size(); ++i) {
+ DomWidget *child = widget->elementWidget().at(i);
+ childWidgets += child;
+ acceptWidget(child);
+ }
+
+ if (!widget->elementLayout().isEmpty())
+ acceptLayout(widget->elementLayout().at(0));
+
+ const DomScripts scripts(widget->elementScript());
+ acceptWidgetScripts(scripts, widget, childWidgets);
+}
+
+void TreeWalker::acceptSpacer(DomSpacer *spacer)
+{
+ for (int i=0; i<spacer->elementProperty().size(); ++i)
+ acceptProperty(spacer->elementProperty().at(i));
+}
+
+void TreeWalker::acceptColor(DomColor *color)
+{
+ Q_UNUSED(color);
+}
+
+void TreeWalker::acceptColorGroup(DomColorGroup *colorGroup)
+{
+ Q_UNUSED(colorGroup);
+}
+
+void TreeWalker::acceptPalette(DomPalette *palette)
+{
+ acceptColorGroup(palette->elementActive());
+ acceptColorGroup(palette->elementInactive());
+ acceptColorGroup(palette->elementDisabled());
+}
+
+void TreeWalker::acceptFont(DomFont *font)
+{
+ Q_UNUSED(font);
+}
+
+void TreeWalker::acceptPoint(DomPoint *point)
+{
+ Q_UNUSED(point);
+}
+
+void TreeWalker::acceptRect(DomRect *rect)
+{
+ Q_UNUSED(rect);
+}
+
+void TreeWalker::acceptSizePolicy(DomSizePolicy *sizePolicy)
+{
+ Q_UNUSED(sizePolicy);
+}
+
+void TreeWalker::acceptSize(DomSize *size)
+{
+ Q_UNUSED(size);
+}
+
+void TreeWalker::acceptDate(DomDate *date)
+{
+ Q_UNUSED(date);
+}
+
+void TreeWalker::acceptTime(DomTime *time)
+{
+ Q_UNUSED(time);
+}
+
+void TreeWalker::acceptDateTime(DomDateTime *dateTime)
+{
+ Q_UNUSED(dateTime);
+}
+
+void TreeWalker::acceptProperty(DomProperty *property)
+{
+ switch (property->kind()) {
+ case DomProperty::Bool:
+ case DomProperty::Color:
+ case DomProperty::Cstring:
+ case DomProperty::Cursor:
+ case DomProperty::CursorShape:
+ case DomProperty::Enum:
+ case DomProperty::Font:
+ case DomProperty::Pixmap:
+ case DomProperty::IconSet:
+ case DomProperty::Palette:
+ case DomProperty::Point:
+ case DomProperty::PointF:
+ case DomProperty::Rect:
+ case DomProperty::RectF:
+ case DomProperty::Set:
+ case DomProperty::Locale:
+ case DomProperty::SizePolicy:
+ case DomProperty::Size:
+ case DomProperty::SizeF:
+ case DomProperty::String:
+ case DomProperty::Number:
+ case DomProperty::LongLong:
+ case DomProperty::Char:
+ case DomProperty::Date:
+ case DomProperty::Time:
+ case DomProperty::DateTime:
+ case DomProperty::Url:
+ case DomProperty::Unknown:
+ case DomProperty::StringList:
+ case DomProperty::Float:
+ case DomProperty::Double:
+ case DomProperty::UInt:
+ case DomProperty::ULongLong:
+ case DomProperty::Brush:
+ break;
+ }
+}
+
+void TreeWalker::acceptCustomWidgets(DomCustomWidgets *customWidgets)
+{
+ for (int i=0; i<customWidgets->elementCustomWidget().size(); ++i)
+ acceptCustomWidget(customWidgets->elementCustomWidget().at(i));
+}
+
+void TreeWalker::acceptCustomWidget(DomCustomWidget *customWidget)
+{
+ Q_UNUSED(customWidget);
+}
+
+void TreeWalker::acceptAction(DomAction *action)
+{
+ Q_UNUSED(action);
+}
+
+void TreeWalker::acceptActionGroup(DomActionGroup *actionGroup)
+{
+ for (int i=0; i<actionGroup->elementAction().size(); ++i)
+ acceptAction(actionGroup->elementAction().at(i));
+
+ for (int i=0; i<actionGroup->elementActionGroup().size(); ++i)
+ acceptActionGroup(actionGroup->elementActionGroup().at(i));
+}
+
+void TreeWalker::acceptActionRef(DomActionRef *actionRef)
+{
+ Q_UNUSED(actionRef);
+}
+
+void TreeWalker::acceptImages(DomImages *images)
+{
+ for (int i=0; i<images->elementImage().size(); ++i)
+ acceptImage(images->elementImage().at(i));
+}
+
+void TreeWalker::acceptImage(DomImage *image)
+{
+ Q_UNUSED(image);
+}
+
+void TreeWalker::acceptIncludes(DomIncludes *includes)
+{
+ for (int i=0; i<includes->elementInclude().size(); ++i)
+ acceptInclude(includes->elementInclude().at(i));
+}
+
+void TreeWalker::acceptInclude(DomInclude *incl)
+{
+ Q_UNUSED(incl);
+}
+
+void TreeWalker::acceptConnections(DomConnections *connections)
+{
+ for (int i=0; i<connections->elementConnection().size(); ++i)
+ acceptConnection(connections->elementConnection().at(i));
+}
+
+void TreeWalker::acceptConnection(DomConnection *connection)
+{
+ acceptConnectionHints(connection->elementHints());
+}
+
+void TreeWalker::acceptConnectionHints(DomConnectionHints *connectionHints)
+{
+ for (int i=0; i<connectionHints->elementHint().size(); ++i)
+ acceptConnectionHint(connectionHints->elementHint().at(i));
+}
+
+void TreeWalker::acceptConnectionHint(DomConnectionHint *connectionHint)
+{
+ Q_UNUSED(connectionHint);
+}
+
+void TreeWalker::acceptWidgetScripts(const DomScripts &, DomWidget *, const DomWidgets &)
+{
+}
+
+void TreeWalker::acceptButtonGroups(const DomButtonGroups *domButtonGroups)
+{
+ typedef QList<DomButtonGroup*> DomButtonGroupList;
+ const DomButtonGroupList domGroups = domButtonGroups->elementButtonGroup();
+ const DomButtonGroupList::const_iterator cend = domGroups.constEnd();
+ for (DomButtonGroupList::const_iterator it = domGroups.constBegin(); it != cend; ++it)
+ acceptButtonGroup(*it);
+}
+
+void TreeWalker::acceptButtonGroup(const DomButtonGroup *)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/treewalker.h b/src/tools/uic/treewalker.h
new file mode 100644
index 0000000000..a4e5d6e6be
--- /dev/null
+++ b/src/tools/uic/treewalker.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TREEWALKER_H
+#define TREEWALKER_H
+
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class DomUI;
+class DomLayoutDefault;
+class DomLayoutFunction;
+class DomTabStops;
+class DomLayout;
+class DomLayoutItem;
+class DomWidget;
+class DomSpacer;
+class DomColor;
+class DomColorGroup;
+class DomPalette;
+class DomFont;
+class DomPoint;
+class DomRect;
+class DomSizePolicy;
+class DomSize;
+class DomDate;
+class DomTime;
+class DomDateTime;
+class DomProperty;
+class DomCustomWidgets;
+class DomCustomWidget;
+class DomAction;
+class DomActionGroup;
+class DomActionRef;
+class DomImages;
+class DomImage;
+class DomItem;
+class DomIncludes;
+class DomInclude;
+class DomString;
+class DomResourcePixmap;
+class DomResources;
+class DomResource;
+class DomConnections;
+class DomConnection;
+class DomConnectionHints;
+class DomConnectionHint;
+class DomScript;
+class DomButtonGroups;
+class DomButtonGroup;
+
+struct TreeWalker
+{
+ inline virtual ~TreeWalker() {}
+
+ virtual void acceptUI(DomUI *ui);
+ virtual void acceptLayoutDefault(DomLayoutDefault *layoutDefault);
+ virtual void acceptLayoutFunction(DomLayoutFunction *layoutFunction);
+ virtual void acceptTabStops(DomTabStops *tabStops);
+ virtual void acceptCustomWidgets(DomCustomWidgets *customWidgets);
+ virtual void acceptCustomWidget(DomCustomWidget *customWidget);
+ virtual void acceptLayout(DomLayout *layout);
+ virtual void acceptLayoutItem(DomLayoutItem *layoutItem);
+ virtual void acceptWidget(DomWidget *widget);
+ virtual void acceptSpacer(DomSpacer *spacer);
+ virtual void acceptColor(DomColor *color);
+ virtual void acceptColorGroup(DomColorGroup *colorGroup);
+ virtual void acceptPalette(DomPalette *palette);
+ virtual void acceptFont(DomFont *font);
+ virtual void acceptPoint(DomPoint *point);
+ virtual void acceptRect(DomRect *rect);
+ virtual void acceptSizePolicy(DomSizePolicy *sizePolicy);
+ virtual void acceptSize(DomSize *size);
+ virtual void acceptDate(DomDate *date);
+ virtual void acceptTime(DomTime *time);
+ virtual void acceptDateTime(DomDateTime *dateTime);
+ virtual void acceptProperty(DomProperty *property);
+ typedef QList<DomScript *> DomScripts;
+ typedef QList<DomWidget *> DomWidgets;
+ virtual void acceptWidgetScripts(const DomScripts &, DomWidget *node, const DomWidgets &childWidgets);
+ virtual void acceptImages(DomImages *images);
+ virtual void acceptImage(DomImage *image);
+ virtual void acceptIncludes(DomIncludes *includes);
+ virtual void acceptInclude(DomInclude *incl);
+ virtual void acceptAction(DomAction *action);
+ virtual void acceptActionGroup(DomActionGroup *actionGroup);
+ virtual void acceptActionRef(DomActionRef *actionRef);
+ virtual void acceptConnections(DomConnections *connections);
+ virtual void acceptConnection(DomConnection *connection);
+ virtual void acceptConnectionHints(DomConnectionHints *connectionHints);
+ virtual void acceptConnectionHint(DomConnectionHint *connectionHint);
+ virtual void acceptButtonGroups(const DomButtonGroups *buttonGroups);
+ virtual void acceptButtonGroup(const DomButtonGroup *buttonGroup);
+};
+
+QT_END_NAMESPACE
+
+#endif // TREEWALKER_H
diff --git a/src/tools/uic/ui4.cpp b/src/tools/uic/ui4.cpp
new file mode 100644
index 0000000000..94d931b87c
--- /dev/null
+++ b/src/tools/uic/ui4.cpp
@@ -0,0 +1,11154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "ui4.h"
+
+#ifdef QUILOADER_QDOM_READ
+#include <QtXml/QDomElement>
+#endif
+
+QT_BEGIN_NAMESPACE
+#ifdef QFORMINTERNAL_NAMESPACE
+using namespace QFormInternal;
+#endif
+
+/*******************************************************************************
+** Implementations
+*/
+
+void DomUI::clear(bool clear_all)
+{
+ delete m_widget;
+ delete m_layoutDefault;
+ delete m_layoutFunction;
+ delete m_customWidgets;
+ delete m_tabStops;
+ delete m_images;
+ delete m_includes;
+ delete m_resources;
+ delete m_connections;
+ delete m_designerdata;
+ delete m_slots;
+ delete m_buttonGroups;
+
+ if (clear_all) {
+ m_text.clear();
+ m_has_attr_version = false;
+ m_has_attr_language = false;
+ m_has_attr_displayname = false;
+ m_has_attr_stdsetdef = false;
+ m_attr_stdsetdef = 0;
+ m_has_attr_stdSetDef = false;
+ m_attr_stdSetDef = 0;
+ }
+
+ m_children = 0;
+ m_widget = 0;
+ m_layoutDefault = 0;
+ m_layoutFunction = 0;
+ m_customWidgets = 0;
+ m_tabStops = 0;
+ m_images = 0;
+ m_includes = 0;
+ m_resources = 0;
+ m_connections = 0;
+ m_designerdata = 0;
+ m_slots = 0;
+ m_buttonGroups = 0;
+}
+
+DomUI::DomUI()
+{
+ m_children = 0;
+ m_has_attr_version = false;
+ m_has_attr_language = false;
+ m_has_attr_displayname = false;
+ m_has_attr_stdsetdef = false;
+ m_attr_stdsetdef = 0;
+ m_has_attr_stdSetDef = false;
+ m_attr_stdSetDef = 0;
+ m_widget = 0;
+ m_layoutDefault = 0;
+ m_layoutFunction = 0;
+ m_customWidgets = 0;
+ m_tabStops = 0;
+ m_images = 0;
+ m_includes = 0;
+ m_resources = 0;
+ m_connections = 0;
+ m_designerdata = 0;
+ m_slots = 0;
+ m_buttonGroups = 0;
+}
+
+DomUI::~DomUI()
+{
+ delete m_widget;
+ delete m_layoutDefault;
+ delete m_layoutFunction;
+ delete m_customWidgets;
+ delete m_tabStops;
+ delete m_images;
+ delete m_includes;
+ delete m_resources;
+ delete m_connections;
+ delete m_designerdata;
+ delete m_slots;
+ delete m_buttonGroups;
+}
+
+void DomUI::read(QXmlStreamReader &reader)
+{
+
+ foreach (const QXmlStreamAttribute &attribute, reader.attributes()) {
+ QStringRef name = attribute.name();
+ if (name == QLatin1String("version")) {
+ setAttributeVersion(attribute.value().toString());
+ continue;
+ }
+ if (name == QLatin1String("language")) {
+ setAttributeLanguage(attribute.value().toString());
+ continue;
+ }
+ if (name == QLatin1String("displayname")) {
+ setAttributeDisplayname(attribute.value().toString());
+ continue;
+ }
+ if (name == QLatin1String("stdsetdef")) {
+ setAttributeStdsetdef(attribute.value().toString().toInt());
+ continue;
+ }
+ if (name == QLatin1String("stdSetDef")) {
+ setAttributeStdSetDef(attribute.value().toString().toInt());
+ continue;
+ }
+ reader.raiseError(QLatin1String("Unexpected attribute ") + name.toString());
+ }
+
+ for (bool finished = false; !finished && !reader.hasError();) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement : {
+ const QString tag = reader.name().toString().toLower();
+ if (tag == QLatin1String("author")) {
+ setElementAuthor(reader.readElementText());
+ continue;
+ }
+ if (tag == QLatin1String("comment")) {
+ setElementComment(reader.readElementText());
+ continue;
+ }
+ if (tag == QLatin1String("exportmacro")) {
+ setElementExportMacro(reader.readElementText());
+ continue;
+ }
+ if (tag == QLatin1String("class")) {
+ setElementClass(reader.readElementText());
+ continue;
+ }
+ if (tag == QLatin1String("widget")) {
+ DomWidget *v = new DomWidget();
+ v->read(reader);
+ setElementWidget(v);
+ continue;
+ }
+ if (tag == QLatin1String("layoutdefault")) {
+ DomLayoutDefault *v = new DomLayoutDefault();
+ v->read(reader);
+ setElementLayoutDefault(v);
+ continue;
+ }
+ if (tag == QLatin1String("layoutfunction")) {
+ DomLayoutFunction *v = new DomLayoutFunction();
+ v->read(reader);
+ setElementLayoutFunction(v);
+ continue;
+ }
+ if (tag == QLatin1String("pixmapfunction")) {
+ setElementPixmapFunction(reader.readElementText());
+ continue;
+ }
+ if (tag == QLatin1String("customwidgets")) {
+ DomCustomWidgets *v = new DomCustomWidgets();
+ v->read(reader);
+ setElementCustomWidgets(v);
+ continue;
+ }
+ if (tag == QLatin1String("tabstops")) {
+ DomTabStops *v = new DomTabStops();
+ v->read(reader);
+ setElementTabStops(v);
+ continue;
+ }
+ if (tag == QLatin1String("images")) {
+ DomImages *v = new DomImages();
+ v->read(reader);
+ setElementImages(v);
+ continue;
+ }
+ if (tag == QLatin1String("includes")) {
+ DomIncludes *v = new DomIncludes();
+ v->read(reader);
+ setElementIncludes(v);
+ continue;
+ }
+ if (tag == QLatin1String("resources")) {
+ DomResources *v = new DomResources();
+ v->read(reader);
+ setElementResources(v);
+ continue;
+ }
+ if (tag == QLatin1String("connections")) {
+ DomConnections *v = new DomConnections();
+ v->read(reader);
+ setElementConnections(v);
+ continue;
+ }
+ if (tag == QLatin1String("designerdata")) {
+ DomDesignerData *v = new DomDesignerData();
+ v->read(reader);
+ setElementDesignerdata(v);
+ continue;
+ }
+ if (tag == QLatin1String("slots")) {
+ DomSlots *v = new DomSlots();
+ v->read(reader);
+ setElementSlots(v);
+ continue;
+ }
+ if (tag == QLatin1String("buttongroups")) {
+ DomButtonGroups *v = new DomButtonGroups();
+ v->read(reader);
+ setElementButtonGroups(v);
+ continue;
+ }
+ reader.raiseError(QLatin1String("Unexpected element ") + tag);
+ }
+ break;
+ case QXmlStreamReader::EndElement :
+ finished = true;
+ break;
+ case QXmlStreamReader::Characters :
+ if (!reader.isWhitespace())
+ m_text.append(reader.text().toString());
+ break;
+ default :
+ break;
+ }
+ }
+}
+
+#ifdef QUILOADER_QDOM_READ
+void DomUI::read(const QDomElement &node)
+{
+ if (node.hasAttribute(QLatin1String("version")))
+ setAttributeVersion(node.attribute(QLatin1String("version")));
+ if (node.hasAttribute(QLatin1String("language")))
+ setAttributeLanguage(node.attribute(QLatin1String("language")));
+ if (node.hasAttribute(QLatin1String("displayname")))
+ setAttributeDisplayname(node.attribute(QLatin1String("displayname")));
+ if (node.hasAttribute(QLatin1String("stdsetdef")))
+ setAttributeStdsetdef(node.attribute(QLatin1String("stdsetdef")).toInt());
+ if (node.hasAttribute(QLatin1String("stdSetDef")))
+ setAttri