summaryrefslogtreecommitdiffstats
path: root/src/tools/uic3/ui3reader.cpp
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
commit9afa05c6d2fd0a4f16814e3e7bc5cdca683e5324 (patch)
tree41423907a733fdbf6ce942a7e1929a6cfccca0f6 /src/tools/uic3/ui3reader.cpp
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/uic3/ui3reader.cpp')
-rw-r--r--src/tools/uic3/ui3reader.cpp631
1 files changed, 631 insertions, 0 deletions
diff --git a/src/tools/uic3/ui3reader.cpp b/src/tools/uic3/ui3reader.cpp
new file mode 100644
index 0000000..91406ed
--- /dev/null
+++ b/src/tools/uic3/ui3reader.cpp
@@ -0,0 +1,631 @@
+/****************************************************************************
+**
+** 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 "ui3reader.h"
+#include "parser.h"
+#include "domtool.h"
+#include "ui4.h"
+#include "widgetinfo.h"
+#include "globaldefs.h"
+#include "qt3to4.h"
+
+#include <QFile>
+#include <QDateTime>
+#include <QRegExp>
+#include <QXmlStreamWriter>
+#include <QtDebug>
+#include <stdio.h>
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+bool Ui3Reader::isMainWindow = false;
+
+static QString lineColDebug(int line, int col)
+{
+ if (line >= 0) {
+ const QString ret = QString::fromLatin1("Line: %1%2");
+ return ret.arg(line).arg(col >= 0 ? QString::fromLatin1(" Column: %1").arg(col) : QString());
+ }
+ return QString();
+}
+
+void Ui3Reader::errorInvalidProperty(const QString &propertyName, const QString &widgetName, const QString &widgetClass, int line, int col)
+{
+ fprintf(stderr, "uic3: property `%s' for widget `%s' of type `%s' is not supported. %s\n",
+ propertyName.toLatin1().constData(),
+ widgetName.toLatin1().constData(),
+ widgetClass.toLatin1().constData(),
+ lineColDebug(line, col).toLocal8Bit().constData());
+}
+
+void Ui3Reader::errorInvalidSignal(const QString &signal, const QString &widgetName, const QString &widgetClass, int line, int col)
+{
+ fprintf(stderr, "uic3: signal `%s' for widget `%s' of type `%s' is not supported; connection may fail. %s\n",
+ signal.toLatin1().constData(), widgetName.toLatin1().constData(),
+ widgetClass.toLatin1().constData(),
+ lineColDebug(line, col).toLocal8Bit().constData());
+}
+
+void Ui3Reader::errorInvalidSlot(const QString &slot, const QString &widgetName, const QString &widgetClass, int line, int col)
+{
+ fprintf(stderr, "uic3: slot `%s' for widget `%s' of type `%s' is not supported; connection may fail. %s\n",
+ slot.toLatin1().constData(),
+ widgetName.toLatin1().constData(),
+ widgetClass.toLatin1().constData(),
+ lineColDebug(line, col).toLocal8Bit().constData());
+}
+
+QString Ui3Reader::getComment(const QDomNode& n)
+{
+ QDomNode child = n.firstChild();
+ while (!child.isNull()) {
+ if (child.toElement().tagName() == QLatin1String("comment"))
+ return child.toElement().firstChild().toText().data();
+ child = child.nextSibling();
+ }
+ return QString();
+}
+
+QString Ui3Reader::mkBool(bool b)
+{
+ return b ? QLatin1String("true") : QLatin1String("false");
+}
+
+QString Ui3Reader::mkBool(const QString& s)
+{
+ return mkBool(s == QLatin1String("true") || s == QLatin1String("1"));
+}
+
+bool Ui3Reader::toBool(const QString& s)
+{
+ return s == QLatin1String("true") || s.toInt() != 0;
+}
+
+QString Ui3Reader::fixString(const QString &str, bool encode)
+{
+ QString s;
+ if (!encode) {
+ s = str;
+ s.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
+ s.replace(QLatin1Char('\"'), QLatin1String("\\\""));
+ s.remove(QLatin1Char('\r'));
+ s.replace(QLatin1Char('\n'), QLatin1String("\\n\"\n\""));
+ } else {
+ QByteArray utf8 = str.utf8();
+ const int l = utf8.length();
+ for (int i = 0; i < l; ++i)
+ s += QLatin1String("\\x") + QString::number((uchar)utf8[i], 16);
+ }
+
+ return QLatin1Char('\"') + s + QLatin1Char('\"');
+}
+
+QString Ui3Reader::trcall(const QString& sourceText, const QString& comment)
+{
+ if (sourceText.isEmpty() && comment.isEmpty())
+ return QLatin1String("QString()");
+
+ QString t = trmacro;
+ bool encode = false;
+ if (t.isNull()) {
+ t = QLatin1String("tr");
+ for (int i = 0; i < (int) sourceText.length(); i++) {
+ if (sourceText[i].unicode() >= 0x80) {
+ t = QLatin1String("trUtf8");
+ encode = true;
+ break;
+ }
+ }
+ }
+
+ if (comment.isEmpty()) {
+ return t + QLatin1Char('(') + fixString(sourceText, encode) + QLatin1Char(')');
+ } else {
+ return t + QLatin1Char('(')
+ + fixString(sourceText, encode)
+ + QLatin1String(", ")
+ + fixString(comment, encode) + QLatin1Char(')');
+ }
+}
+
+QString Ui3Reader::mkStdSet(const QString& prop)
+{
+ return QLatin1String("set") + prop[0].toUpper() + prop.mid(1);
+}
+
+void Ui3Reader::init()
+{
+ outputFileName.clear();
+ trmacro.clear();
+
+ fileName.clear();
+ writeFunctImpl = true;
+ defMargin = BOXLAYOUT_DEFAULT_MARGIN;
+ defSpacing = BOXLAYOUT_DEFAULT_SPACING;
+ externPixmaps = false;
+ indent = QLatin1String(" "); // default indent
+
+ item_used = cg_used = pal_used = 0;
+
+ layouts.clear();
+ layouts << QLatin1String("hbox") << QLatin1String("vbox") << QLatin1String("grid");
+ tags = layouts;
+ tags << QLatin1String("widget");
+
+ nameOfClass.clear();
+ namespaces.clear();
+ bareNameOfClass.clear();
+}
+
+QDomElement Ui3Reader::parse(const QDomDocument &doc)
+{
+ root = doc.firstChild().toElement();
+ widget = QDomElement();
+
+ pixmapLoaderFunction = getPixmapLoaderFunction(doc.firstChild().toElement());
+ nameOfClass = getFormClassName(doc.firstChild().toElement());
+
+ uiFileVersion = doc.firstChild().toElement().attribute(QLatin1String("version"));
+ stdsetdef = toBool(doc.firstChild().toElement().attribute(QLatin1String("stdsetdef")));
+
+ if (doc.firstChild().isNull() || doc.firstChild().firstChild().isNull())
+ return widget;
+
+ QDomElement e = doc.firstChild().firstChild().toElement();
+ while (!e.isNull()) {
+ if (e.tagName() == QLatin1String("widget")) {
+ widget = e;
+ } else if (e.tagName() == QLatin1String("pixmapinproject")) {
+ externPixmaps = true;
+ } else if (e.tagName() == QLatin1String("layoutdefaults")) {
+ defSpacing = e.attribute(QLatin1String("spacing"), defSpacing.toString());
+ defMargin = e.attribute(QLatin1String("margin"), defMargin.toString());
+ } else if (e.tagName() == QLatin1String("layoutfunctions")) {
+ defSpacing = e.attribute(QLatin1String("spacing"), defSpacing.toString());
+ bool ok;
+ defSpacing.toInt(&ok);
+ if (!ok) {
+ QString buf = defSpacing.toString();
+ defSpacing = buf.append(QLatin1String("()"));
+ }
+ defMargin = e.attribute(QLatin1String("margin"), defMargin.toString());
+ defMargin.toInt(&ok);
+ if (!ok) {
+ QString buf = defMargin.toString();
+ defMargin = buf.append(QLatin1String("()"));
+ }
+ }
+ e = e.nextSibling().toElement();
+ }
+
+ return widget;
+}
+
+Ui3Reader::Ui3Reader(QTextStream &outStream, unsigned options) :
+ m_options(options), out(outStream), trout(&languageChangeBody),
+ m_porting(new Porting), m_extractImages(false)
+{
+}
+
+Ui3Reader::~Ui3Reader()
+{
+ delete m_porting;
+}
+
+void Ui3Reader::generate(const QString &fn, const QString &outputFn,
+ QDomDocument doc, bool decl, bool subcl, const QString &trm,
+ const QString& subClass, const QString &convertedUiFile)
+{
+ init();
+
+ fileName = fn;
+ outputFileName = outputFn;
+ trmacro = trm;
+
+ QDomElement e = parse(doc);
+
+ if (nameOfClass.isEmpty())
+ nameOfClass = getObjectName(e);
+ namespaces = nameOfClass.split(QLatin1String("::"));
+ bareNameOfClass = namespaces.last();
+ namespaces.removeLast();
+
+ if (!convertedUiFile.isEmpty()) {
+ createWrapperDecl(e, convertedUiFile);
+ } else if (subcl) {
+ if (decl)
+ createSubDecl(e, subClass);
+ else
+ createSubImpl(e, subClass);
+ } else {
+ if (decl)
+ createFormDecl(e);
+ else
+ createFormImpl(e);
+ }
+
+}
+
+void Ui3Reader::generateUi4(const QString &fn, const QString &outputFn, QDomDocument doc)
+{
+ init();
+
+ fileName = fn;
+ outputFileName = outputFn;
+
+ DomUI *ui = generateUi4(parse(doc));
+ if (!ui)
+ return;
+
+ if (pixmapLoaderFunction.size())
+ ui->setElementPixmapFunction(pixmapLoaderFunction);
+
+ QXmlStreamWriter writer(out.device());
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(2);
+ writer.writeStartDocument();
+ ui->write(writer);
+ writer.writeEndDocument();
+
+ delete ui;
+}
+
+void Ui3Reader::setTrMacro(const QString &trmacro)
+{
+ this->trmacro = trmacro;
+}
+
+void Ui3Reader::setOutputFileName(const QString &fileName)
+{
+ outputFileName = fileName;
+}
+
+/*! Extracts a pixmap loader function from \a e
+ */
+QString Ui3Reader::getPixmapLoaderFunction(const QDomElement& e)
+{
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("pixmapfunction"))
+ return n.firstChild().toText().data();
+ }
+ return QString();
+}
+
+
+/*! Extracts the forms class name from \a e
+ */
+QString Ui3Reader::getFormClassName(const QDomElement& e)
+{
+ QDomElement n;
+ QString cn;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("class")) {
+ QString s = n.firstChild().toText().data();
+ int i;
+ while ((i = s.indexOf(QLatin1Char(' '))) != -1)
+ s[i] = QLatin1Char('_');
+ cn = s;
+ }
+ }
+ return cn;
+}
+
+/*! Extracts a class name from \a e.
+ */
+QString Ui3Reader::getClassName(const QDomElement& e)
+{
+ QString s = e.attribute(QLatin1String("class"));
+ if (s.isEmpty() && e.tagName() == QLatin1String("toolbar"))
+ s = QLatin1String(QLatin1String("QToolBar"));
+ else if (s.isEmpty() && e.tagName() == QLatin1String("menubar"))
+ s = QLatin1String("QMenuBar");
+
+ return fixClassName(s);
+}
+
+/*! Returns true if database framework code is generated, else false.
+*/
+
+bool Ui3Reader::isFrameworkCodeGenerated(const QDomElement& e)
+{
+ QDomElement n = getObjectProperty(e, QLatin1String("frameworkCode"));
+ if (n.attribute(QLatin1String("name")) == QLatin1String("frameworkCode") &&
+ !DomTool::elementToVariant(n.firstChild().toElement(), QVariant(true)).toBool())
+ return false;
+ return true;
+}
+
+/*! Extracts an object name from \a e. It's stored in the 'name'
+ property.
+ */
+QString Ui3Reader::getObjectName(const QDomElement& e)
+{
+ QDomElement n = getObjectProperty(e, QLatin1String("name"));
+ if (n.firstChild().toElement().tagName() == QLatin1String("cstring"))
+ return n.firstChild().toElement().firstChild().toText().data();
+ return QString();
+}
+
+/*! Extracts an layout name from \a e. It's stored in the 'name'
+ property of the preceding sibling (the first child of a QLayoutWidget).
+ */
+QString Ui3Reader::getLayoutName(const QDomElement& e)
+{
+ QDomElement p = e.parentNode().toElement();
+ QString name;
+
+ if (getClassName(p) != QLatin1String("QLayoutWidget"))
+ name = QLatin1String("Layout");
+
+ QDomElement n = getObjectProperty(p, QLatin1String("name"));
+ if (n.firstChild().toElement().tagName() == QLatin1String("cstring")) {
+ name.prepend(n.firstChild().toElement().firstChild().toText().data());
+ return name.split(QLatin1String("::")).last();
+ }
+ return e.tagName();
+}
+
+
+QString Ui3Reader::getDatabaseInfo(const QDomElement& e, const QString& tag)
+{
+ QDomElement n;
+ QDomElement n1;
+ int child = 0;
+ // database info is a stringlist stored in this order
+ if (tag == QLatin1String("connection"))
+ child = 0;
+ else if (tag == QLatin1String("table"))
+ child = 1;
+ else if (tag == QLatin1String("field"))
+ child = 2;
+ else
+ return QString();
+ n = getObjectProperty(e, QLatin1String("database"));
+ if (n.firstChild().toElement().tagName() == QLatin1String("stringlist")) {
+ // find correct stringlist entry
+ QDomElement n1 = n.firstChild().firstChild().toElement();
+ for (int i = 0; i < child && !n1.isNull(); ++i)
+ n1 = n1.nextSibling().toElement();
+ if (n1.isNull())
+ return QString();
+ return n1.firstChild().toText().data();
+ }
+ return QString();
+}
+
+static const char* const ColorRole[] = {
+ "Foreground", "Button", "Light", "Midlight", "Dark", "Mid",
+ "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow",
+ "Highlight", "HighlightedText", "Link", "LinkVisited", 0
+};
+
+
+/*!
+ Creates a colorgroup with name \a name from the color group \a cg
+ */
+void Ui3Reader::createColorGroupImpl(const QString& name, const QDomElement& e)
+{
+ int r = -1;
+ QDomElement n = e.firstChild().toElement();
+ QString color;
+
+ Color white;
+ white.init(255, 255, 255);
+
+ Color black;
+ black.init(0, 0, 0);
+
+ while (!n.isNull()) {
+ if (n.tagName() == QLatin1String("color")) {
+ r++;
+ Color col = DomTool::readColor(n);
+ color = QLatin1String("QColor(%1, %2, %3)");
+ color = color.arg(col.red).arg(col.green).arg(col.blue);
+ if (col == white)
+ color = QLatin1String("white");
+ else if (col == black)
+ color = QLatin1String("black");
+ if (n.nextSibling().toElement().tagName() != QLatin1String("pixmap")) {
+ out << indent << name << ".setColor(QColorGroup::" << ColorRole[r] << ", " << color << ");" << endl;
+ }
+ } else if (n.tagName() == QLatin1String("pixmap")) {
+ QString pixmap = n.firstChild().toText().data();
+ if (!pixmapLoaderFunction.isEmpty()) {
+ pixmap.prepend(pixmapLoaderFunction
+ + QLatin1Char('(')
+ + QLatin1String(externPixmaps ? "\"" : ""));
+
+ pixmap.append(QLatin1String(externPixmaps ? "\"" : "") + QLatin1Char(')'));
+ }
+ out << indent << name << ".setBrush(QColorGroup::"
+ << ColorRole[r] << ", QBrush(" << color << ", " << pixmap << "));" << endl;
+ }
+ n = n.nextSibling().toElement();
+ }
+}
+
+/*!
+ Auxiliary function to load a color group. The colorgroup must not
+ contain pixmaps.
+ */
+ColorGroup Ui3Reader::loadColorGroup(const QDomElement &e)
+{
+ ColorGroup cg;
+ int r = -1;
+ QDomElement n = e.firstChild().toElement();
+ Color col;
+ while (!n.isNull()) {
+ if (n.tagName() == QLatin1String("color")) {
+ r++;
+ col = DomTool::readColor(n);
+ cg.append(qMakePair(r, col));
+ }
+ n = n.nextSibling().toElement();
+ }
+ return cg;
+}
+
+/*! Returns true if the widget properties specify that it belongs to
+ the database \a connection and \a table.
+*/
+
+bool Ui3Reader::isWidgetInTable(const QDomElement& e, const QString& connection, const QString& table)
+{
+ QString conn = getDatabaseInfo(e, QLatin1String("connection"));
+ QString tab = getDatabaseInfo(e, QLatin1String("table"));
+ if (conn == connection && tab == table)
+ return true;
+ return false;
+}
+
+/*!
+ Registers all database connections, cursors and forms.
+*/
+
+void Ui3Reader::registerDatabases(const QDomElement& e)
+{
+ QDomElement n;
+ QDomNodeList nl;
+ int i;
+ nl = e.parentNode().toElement().elementsByTagName(QLatin1String("widget"));
+ for (i = 0; i < (int) nl.length(); ++i) {
+ n = nl.item(i).toElement();
+ QString conn = getDatabaseInfo(n, QLatin1String("connection"));
+ QString tab = getDatabaseInfo(n, QLatin1String("table"));
+ QString fld = getDatabaseInfo(n, QLatin1String("field"));
+ if (!conn.isNull()) {
+ dbConnections += conn;
+ if (!tab.isNull()) {
+ dbCursors[conn] += tab;
+ if (!fld.isNull())
+ dbForms[conn] += tab;
+ }
+ }
+ }
+}
+
+/*!
+ Registers an object with name \a name.
+
+ The returned name is a valid variable identifier, as similar to \a
+ name as possible and guaranteed to be unique within the form.
+
+ \sa registeredName(), isObjectRegistered()
+ */
+QString Ui3Reader::registerObject(const QString& name)
+{
+ if (objectNames.isEmpty()) {
+ // some temporary variables we need
+ objectNames += QLatin1String("img");
+ objectNames += QLatin1String("item");
+ objectNames += QLatin1String("cg");
+ objectNames += QLatin1String("pal");
+ }
+
+ QString result = name;
+ int i;
+ while ((i = result.indexOf(QLatin1Char(' '))) != -1 ) {
+ result[i] = QLatin1Char('_');
+ }
+
+ if (objectNames.contains(result)) {
+ int i = 2;
+ while (objectNames.contains(result + QLatin1Char('_') + QString::number(i)))
+ i++;
+ result += QLatin1Char('_');
+ result += QString::number(i);
+ }
+ objectNames += result;
+ objectMapper.insert(name, result);
+ return result;
+}
+
+/*!
+ Returns the registered name for the original name \a name
+ or \a name if \a name wasn't registered.
+
+ \sa registerObject(), isObjectRegistered()
+ */
+QString Ui3Reader::registeredName(const QString& name)
+{
+ if (!objectMapper.contains(name))
+ return name;
+ return objectMapper[name];
+}
+
+/*!
+ Returns whether the object \a name was registered yet or not.
+ */
+bool Ui3Reader::isObjectRegistered(const QString& name)
+{
+ return objectMapper.contains(name);
+}
+
+/*!
+ Unifies the entries in stringlist \a list. Should really be a QStringList feature.
+ */
+QStringList Ui3Reader::unique(const QStringList& list)
+{
+ if (list.isEmpty())
+ return list;
+
+ QStringList result;
+ for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ if (!result.contains(*it))
+ result += *it;
+ }
+ return result;
+}
+
+bool Ui3Reader::isLayout(const QString& name) const
+{
+ return layoutObjects.contains(name);
+}
+
+void Ui3Reader::setExtractImages(bool extract, const QString &qrcOutputFile)
+{
+ m_extractImages = extract;
+ m_qrcOutputFile = qrcOutputFile;
+}
+
+QT_END_NAMESPACE