summaryrefslogtreecommitdiffstats
path: root/src/tools/uic3/domtool.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:18:55 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:18:55 (GMT)
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /src/tools/uic3/domtool.cpp
downloadQt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz
Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2
Long live Qt 4.5!
Diffstat (limited to 'src/tools/uic3/domtool.cpp')
-rw-r--r--src/tools/uic3/domtool.cpp587
1 files changed, 587 insertions, 0 deletions
diff --git a/src/tools/uic3/domtool.cpp b/src/tools/uic3/domtool.cpp
new file mode 100644
index 0000000..ce2e2f6
--- /dev/null
+++ b/src/tools/uic3/domtool.cpp
@@ -0,0 +1,587 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "domtool.h"
+
+#include <QSizePolicy>
+#include <QColor>
+#include <QCursor>
+#include <QDateTime>
+#include <QRect>
+#include <QSize>
+#include <QFont>
+#include <QDomElement>
+#include <QByteArray>
+#include <QtDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ \class DomTool
+ \brief The DomTool class provides static functions for Qt Designer
+ and uic.
+
+ A collection of static functions used by Resource (part of the
+ designer) and Uic.
+
+*/
+
+/*
+ Returns the contents of property \a name of object \a e as
+ a variant or the variant passed as \a defValue if the property does
+ not exist. The \a comment is passed on to the elementToVariant()
+ function.
+
+ \sa hasProperty()
+*/
+QVariant DomTool::readProperty(const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment)
+{
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("property")) {
+ if (n.attribute(QLatin1String("name")) != name)
+ continue;
+ return elementToVariant(n.firstChild().toElement(), defValue, comment);
+ }
+ }
+ return defValue;
+}
+
+
+/*
+ \overload
+ */
+QVariant DomTool::readProperty(const QDomElement& e, const QString& name, const QVariant& defValue)
+{
+ QString comment;
+ return readProperty(e, name, defValue, comment);
+}
+
+/*
+ Returns whether object \a e defines property \a name or not.
+
+ \sa readProperty()
+ */
+bool DomTool::hasProperty(const QDomElement& e, const QString& name)
+{
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("property")) {
+ if (n.attribute(QLatin1String("name")) != name)
+ continue;
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ Returns a list of the names of the properties of the given \a type
+ found in the element \a e.
+*/
+QStringList DomTool::propertiesOfType(const QDomElement& e, const QString& type)
+{
+ QStringList result;
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("property")) {
+ QDomElement n2 = n.firstChild().toElement();
+ if (n2.tagName() == type)
+ result += n.attribute(QLatin1String("name"));
+ }
+ }
+ return result;
+}
+
+
+/*
+ \overload
+*/
+QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValue)
+{
+ QString dummy;
+ return elementToVariant(e, defValue, dummy);
+}
+
+/*
+ Interprets element \a e as a variant and returns the result of the
+ interpretation, extracting the data as a text element is the \a
+ comment matches the tag name. If the interpretation fails the \a
+ defValue is returned instead.
+ */
+QVariant DomTool::elementToVariant(const QDomElement& e, const QVariant& defValue, QString &comment)
+{
+ Q_UNUSED(defValue);
+
+ QVariant v;
+ Variant var;
+
+ if (e.tagName() == QLatin1String("rect")) {
+ QDomElement n3 = e.firstChild().toElement();
+ int x = 0, y = 0, w = 0, h = 0;
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("x"))
+ x = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("y"))
+ y = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("width"))
+ w = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("height"))
+ h = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ var.createRect(x, y, w, h);
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("point")) {
+ QDomElement n3 = e.firstChild().toElement();
+ int x = 0, y = 0;
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("x"))
+ x = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("y"))
+ y = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ var.createPoint(x,y);
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("size")) {
+ QDomElement n3 = e.firstChild().toElement();
+ int w = 0, h = 0;
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("width"))
+ w = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("height"))
+ h = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ var.createSize(w, h);
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("color")) {
+ var.color = readColor(e);
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("font")) {
+ QDomElement n3 = e.firstChild().toElement();
+ Font f;
+ f.init();
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("family"))
+ f.family = qstrdup(n3.firstChild().toText().data().toLatin1());
+ else if (n3.tagName() == QLatin1String("pointsize"))
+ f.pointsize = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("bold"))
+ f.bold = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("italic"))
+ f.italic = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("underline"))
+ f.underline = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("strikeout"))
+ f.strikeout = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ var.font = f;
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("string")) {
+ v = QVariant(e.firstChild().toText().data());
+ QDomElement n = e;
+ n = n.nextSibling().toElement();
+ if (n.tagName() == QLatin1String("comment"))
+ comment = n.firstChild().toText().data();
+ } else if (e.tagName() == QLatin1String("cstring")) {
+ v = QVariant(e.firstChild().toText().data().toAscii());
+ } else if (e.tagName() == QLatin1String("number")) {
+ bool ok = true;
+ v = QVariant(e.firstChild().toText().data().toInt(&ok));
+ if (!ok)
+ v = QVariant(e.firstChild().toText().data().toDouble());
+ } else if (e.tagName() == QLatin1String("bool")) {
+ QString t = e.firstChild().toText().data();
+ v = QVariant(t == QLatin1String("true") || t == QLatin1String("1"));
+ } else if (e.tagName() == QLatin1String("pixmap")) {
+ v = QVariant(e.firstChild().toText().data());
+ } else if (e.tagName() == QLatin1String("iconset")) {
+ v = QVariant(e.firstChild().toText().data());
+ } else if (e.tagName() == QLatin1String("image")) {
+ v = QVariant(e.firstChild().toText().data());
+ } else if (e.tagName() == QLatin1String("enum")) {
+ v = QVariant(e.firstChild().toText().data());
+ } else if (e.tagName() == QLatin1String("set")) {
+ v = QVariant(e.firstChild().toText().data());
+ } else if (e.tagName() == QLatin1String("sizepolicy")) {
+ QDomElement n3 = e.firstChild().toElement();
+ var.createSizePolicy();
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("hsizetype"))
+ var.sizePolicy.hsizetype = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("vsizetype"))
+ var.sizePolicy.vsizetype = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("horstretch"))
+ var.sizePolicy.horstretch = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("verstretch"))
+ var.sizePolicy.verstretch = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("cursor")) {
+ var.createCursor(e.firstChild().toText().data().toInt());
+ qVariantSetValue(v, var);
+ } else if (e.tagName() == QLatin1String("stringlist")) {
+ QStringList lst;
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement())
+ lst << n.firstChild().toText().data();
+ v = QVariant(lst);
+ } else if (e.tagName() == QLatin1String("date")) {
+ QDomElement n3 = e.firstChild().toElement();
+ int y, m, d;
+ y = m = d = 0;
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("year"))
+ y = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("month"))
+ m = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("day"))
+ d = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ v = QVariant(QDate(y, m, d));
+ } else if (e.tagName() == QLatin1String("time")) {
+ QDomElement n3 = e.firstChild().toElement();
+ int h, m, s;
+ h = m = s = 0;
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("hour"))
+ h = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("minute"))
+ m = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("second"))
+ s = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ v = QVariant(QTime(h, m, s));
+ } else if (e.tagName() == QLatin1String("datetime")) {
+ QDomElement n3 = e.firstChild().toElement();
+ int h, mi, s, y, mo, d ;
+ h = mi = s = y = mo = d = 0;
+ while (!n3.isNull()) {
+ if (n3.tagName() == QLatin1String("hour"))
+ h = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("minute"))
+ mi = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("second"))
+ s = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("year"))
+ y = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("month"))
+ mo = n3.firstChild().toText().data().toInt();
+ else if (n3.tagName() == QLatin1String("day"))
+ d = n3.firstChild().toText().data().toInt();
+ n3 = n3.nextSibling().toElement();
+ }
+ v = QVariant(QDateTime(QDate(y, mo, d), QTime(h, mi, s)));
+ }
+
+ return v;
+}
+
+
+/* Returns the color which is returned in the dom element \a e.
+ */
+
+Color DomTool::readColor(const QDomElement &e)
+{
+ QDomElement n = e.firstChild().toElement();
+ int r= 0, g = 0, b = 0;
+ while (!n.isNull()) {
+ if (n.tagName() == QLatin1String("red"))
+ r = n.firstChild().toText().data().toInt();
+ else if (n.tagName() == QLatin1String("green"))
+ g = n.firstChild().toText().data().toInt();
+ else if (n.tagName() == QLatin1String("blue"))
+ b = n.firstChild().toText().data().toInt();
+ n = n.nextSibling().toElement();
+ }
+
+ Color c;
+ c.init(r, g, b);
+ return c;
+}
+
+/*
+ Returns the contents of attribute \a name of object \a e as
+ a variant or the variant passed as \a defValue if the attribute does
+ not exist. The \a comment is passed to the elementToVariant()
+ function.
+
+ \sa hasAttribute()
+ */
+QVariant DomTool::readAttribute(const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment)
+{
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("attribute")) {
+ if (n.attribute(QLatin1String("name")) != name)
+ continue;
+ return elementToVariant(n.firstChild().toElement(), defValue, comment);
+ }
+ }
+ return defValue;
+}
+
+/*
+ \overload
+*/
+QVariant DomTool::readAttribute(const QDomElement& e, const QString& name, const QVariant& defValue)
+{
+ QString comment;
+ return readAttribute(e, name, defValue, comment);
+}
+
+/*
+ Returns whether object \a e defines attribute \a name or not.
+
+ \sa readAttribute()
+ */
+bool DomTool::hasAttribute(const QDomElement& e, const QString& name)
+{
+ QDomElement n;
+ for (n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement()) {
+ if (n.tagName() == QLatin1String("attribute")) {
+ if (n.attribute(QLatin1String("name")) != name)
+ continue;
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool toBool(const QString& s)
+{
+ return s == QLatin1String("true") || s.toInt() != 0;
+}
+
+static double versionToDouble(QString version)
+{
+ version = version.trimmed();
+
+ if (version.isEmpty())
+ return 0.0;
+
+ bool decpt = false;
+ QString num_str;
+ for (int i = 0; i < version.size(); ++i) {
+ char c = version.at(i).toAscii();
+ if ((c < '0' || c > '9') && c != '.')
+ break;
+ if (c == '.') {
+ if (decpt)
+ break;
+ decpt = true;
+ }
+ num_str.append(QLatin1Char(c));
+ }
+
+ return num_str.toDouble();
+}
+
+/*
+ \internal
+
+ Convert Qt 2.x format to Qt 3.x format if necessary.
+*/
+void DomTool::fixDocument(QDomDocument& doc)
+{
+ QDomElement e;
+ QDomNode n;
+ QDomNodeList nl;
+ int i = 0;
+
+ e = doc.firstChild().toElement();
+ if (e.tagName() != QLatin1String("UI"))
+ return;
+
+ // rename classes and properties
+ double version = versionToDouble(e.attribute(QLatin1String("version")));
+
+ nl = e.childNodes();
+ fixAttributes(nl, version);
+
+ // 3.x don't do anything more
+ if (version >= 3.0)
+ return;
+
+ // in versions smaller than 3.0 we need to change more
+
+ e.setAttribute(QLatin1String("version"), 3.0);
+ e.setAttribute(QLatin1String("stdsetdef"), 1);
+ nl = e.elementsByTagName(QLatin1String("property"));
+ for (i = 0; i < (int) nl.length(); i++) {
+ e = nl.item(i).toElement();
+ QString name;
+ QDomElement n2 = e.firstChild().toElement();
+ if (n2.tagName() == QLatin1String("name")) {
+ name = n2.firstChild().toText().data();
+ if (name == QLatin1String("resizeable"))
+ e.setAttribute(QLatin1String("name"), QLatin1String("resizable"));
+ else
+ e.setAttribute(QLatin1String("name"), name);
+ e.removeChild(n2);
+ }
+ bool stdset = toBool(e.attribute(QLatin1String("stdset")));
+ if (stdset || name == QLatin1String("toolTip") || name == QLatin1String("whatsThis") ||
+ name == QLatin1String("buddy") ||
+ e.parentNode().toElement().tagName() == QLatin1String("item") ||
+ e.parentNode().toElement().tagName() == QLatin1String("spacer") ||
+ e.parentNode().toElement().tagName() == QLatin1String("column")
+ )
+ e.removeAttribute(QLatin1String("stdset"));
+ else
+ e.setAttribute(QLatin1String("stdset"), 0);
+ }
+
+ nl = doc.elementsByTagName(QLatin1String("attribute"));
+ for (i = 0; i < (int) nl.length(); i++) {
+ e = nl.item(i).toElement();
+ QString name;
+ QDomElement n2 = e.firstChild().toElement();
+ if (n2.tagName() == QLatin1String("name")) {
+ name = n2.firstChild().toText().data();
+ e.setAttribute(QLatin1String("name"), name);
+ e.removeChild(n2);
+ }
+ }
+
+ nl = doc.elementsByTagName(QLatin1String("image"));
+ for (i = 0; i < (int) nl.length(); i++) {
+ e = nl.item(i).toElement();
+ QString name;
+ QDomElement n2 = e.firstChild().toElement();
+ if (n2.tagName() == QLatin1String("name")) {
+ name = n2.firstChild().toText().data();
+ e.setAttribute(QLatin1String("name"), name);
+ e.removeChild(n2);
+ }
+ }
+
+ nl = doc.elementsByTagName(QLatin1String("widget"));
+ for (i = 0; i < (int) nl.length(); i++) {
+ e = nl.item(i).toElement();
+ QString name;
+ QDomElement n2 = e.firstChild().toElement();
+ if (n2.tagName() == QLatin1String("class")) {
+ name = n2.firstChild().toText().data();
+ e.setAttribute(QLatin1String("class"), name);
+ e.removeChild(n2);
+ }
+ }
+
+}
+
+struct widgetName {
+ widgetName(double v, QString b, QString a)
+ : version(v), before(b), after(a) {}
+ double version;
+ QString before;
+ QString after;
+};
+
+struct propertyName : public widgetName {
+ propertyName(double v, QString b, QString a, QString c = QString())
+ : widgetName(v, b, a), clss(c) {}
+ QString clss;
+};
+
+const int widgs = 1;
+widgetName widgetTable[1] = {
+ widgetName(3.3, QLatin1String("before"), QLatin1String("after")),
+};
+
+const int props = 1;
+propertyName propertyTable[1] = {
+ propertyName(3.0, QLatin1String("resizeable"), QLatin1String("resizable")), // we need to fix a spelling error in 3.0
+};
+
+/*
+ \internal
+*/
+void DomTool::fixAttributes(QDomNodeList &nodes, double version)
+{
+ QDomNode n;
+ QDomNodeList nl;
+ for (int i = 0; i < (int) nodes.count(); ++i) {
+ n = nodes.item(i);
+ fixAttribute(n, version);
+ nl = n.childNodes();
+ fixAttributes(nl, version);
+ }
+}
+
+/*
+ \internal
+*/
+void DomTool::fixAttribute(QDomNode &node, double version)
+{
+ QString tagName = node.toElement().tagName();
+ if (tagName == QLatin1String("widget")) {
+ QString clss = node.toElement().attribute(QLatin1String("class"));
+ for (int i = 0; i < widgs; ++i)
+ if ((version < widgetTable[i].version)
+ && (clss == widgetTable[i].before)) {
+ node.toElement().setAttribute(QLatin1String("class"), propertyTable[i].after);
+ return;
+ }
+ return;
+ }
+ if (tagName == QLatin1String("property")) {
+ QDomElement e = node.parentNode().toElement();
+ QString clss = e.attribute(QLatin1String("class"));
+ QString name = node.toElement().attribute(QLatin1String("name"), QLatin1String(""));
+ for (int i = 0; i < props; ++i)
+ if ((version < propertyTable[i].version)
+ && (clss == propertyTable[i].clss)
+ && (propertyTable[i].before.isNull()
+ || name == propertyTable[i].before)) {
+ node.toElement().setAttribute(QLatin1String("name"), propertyTable[i].after);
+ return;
+ }
+ }
+}
+
+QT_END_NAMESPACE