summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormae <qt-info@nokia.com>2009-04-21 08:54:39 (GMT)
committerRoberto Raggi <roberto.raggi@nokia.com>2009-04-24 08:05:47 (GMT)
commit40377ef5ff137d3501c62eb26be786a09027f598 (patch)
treef6fc3f8b0ccd73bd43aa32a6648054023c7fa2d2
parenta0f45c904517016319338fb6eda53165f46f0f77 (diff)
downloadQt-40377ef5ff137d3501c62eb26be786a09027f598.zip
Qt-40377ef5ff137d3501c62eb26be786a09027f598.tar.gz
Qt-40377ef5ff137d3501c62eb26be786a09027f598.tar.bz2
imported qmlconv utility for convenience
-rw-r--r--tools/qmlconv/qmlconv.cpp386
-rw-r--r--tools/qmlconv/qmlconv.pro10
-rw-r--r--tools/tools.pro2
3 files changed, 397 insertions, 1 deletions
diff --git a/tools/qmlconv/qmlconv.cpp b/tools/qmlconv/qmlconv.cpp
new file mode 100644
index 0000000..a3a3f79
--- /dev/null
+++ b/tools/qmlconv/qmlconv.cpp
@@ -0,0 +1,386 @@
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QStack>
+#include <QtCore/QStringList>
+#include <QtCore/QDebug>
+
+
+
+
+class Reader
+{
+ QString outString;
+ QTextStream out;
+ QXmlStreamReader xml;
+ int depth;
+ bool supressIndent;
+
+ QStringList knownListProperties;
+ inline QString depthString() {if (supressIndent) { supressIndent = false; return QString(); }
+ return QString(depth*4, QLatin1Char(' '));}
+
+public:
+ Reader(QIODevice *in)
+ :xml(in) {
+
+ knownListProperties << "states" << "transitions" << "children" << "resources"
+ << "transform" << "notes";
+ depth = 0;
+ supressIndent = false;
+
+ out.setString(&outString);
+
+ loop();
+
+ out.flush();
+ QTextStream print(stdout);
+ print << outString;
+ }
+
+ void comment()
+ {
+ if (xml.isComment()) {
+ out << depthString() << "// "
+ << xml.text().toString().trimmed().replace(QRegExp("\n\\s*"),"\n"+depthString()+"// ")
+ << endl;
+ }
+ }
+
+ void emptyLoop() {
+ while (!xml.atEnd()) {
+ xml.readNext();
+ comment();
+ if (xml.tokenType() == QXmlStreamReader::EndElement)
+ return;
+ }
+ }
+
+ void loop()
+ {
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.tokenType() == QXmlStreamReader::EndElement)
+ return;
+ else if (xml.tokenType() == QXmlStreamReader::StartElement)
+ startElement();
+ comment();
+ }
+ }
+
+ void startElement() {
+ if (xml.name() == "properties")
+ startDeclareProperties();
+ else if (xml.name() == "signals")
+ startDeclareSignals();
+ else if (knownListProperties.contains(xml.name().toString()))
+ startList();
+ else if (xml.name() == "SetProperties")
+ startSetProperties();
+ else if (xml.name() == "SetProperty")
+ startSetProperty();
+ else if (xml.name() == "ParentChange")
+ startParentChange();
+ else if (xml.name() == "Connection")
+ startConnection();
+ else if (xml.name() == "Script")
+ startScript();
+ else if (xml.name().at(0).isLower() && xml.attributes().isEmpty())
+ startObjectProperty();
+ else
+ startItem();
+ }
+
+ static void possiblyRemoveBraces(QString *s) {
+ if (s->startsWith('{') && s->endsWith('}'))
+ *s = s->mid(1, s->length() - 2);
+ }
+
+ static bool isNumber(const QString &s) {
+ bool ok = true;
+ s.toFloat(&ok);
+ return ok;
+ }
+
+ static bool isSignalHandler(const QString &s) {
+ return s.size() > 3
+ && s.startsWith("on")
+ && s.at(2).isUpper();
+ }
+
+ static bool isEnum(const QString &property, const QString &value) {
+ return !value.contains(' ') && (property == "vAlign" || property == "hAlign"
+ || property == "style");
+ }
+
+ static bool isIdentifier(const QString &s) {
+ if (s.isEmpty())
+ return false;
+ if (!s.at(1).isLetter())
+ return false;
+ for (int i = 1; i < s.size(); ++i) {
+ QChar c = s.at(i);
+ if (c.isLetterOrNumber()
+ || c == QLatin1Char('_')
+ || c == QLatin1Char('-'))
+ continue;
+ return false;
+ }
+ return true;
+ }
+
+
+ void setProperty(const QString &property, const QString &value, bool newline = true) {
+ QString v = value.trimmed();
+ if (v.startsWith('{')) {
+ possiblyRemoveBraces(&v);
+ } else if (v == "true"
+ || v == "false"
+ || isNumber(v)
+ || property == "id"
+ || isEnum(property, value)
+ ) {
+ ;
+ } else if (isSignalHandler(property)) {
+ // if not a function name, create an anonymous function
+ if (!isIdentifier(v)) {
+ v.prepend("function(){ ");
+ v.append(" }");
+ }
+ } else
+
+ // if (property == "text" || property == "name" || value.contains(' ')
+ // || value.contains("/") || value.startsWith('#')
+ // || property == "filename" || property == "source" || property == "src"
+ // || property == "title" || property == "movieTitle" || property == "movieDescription"
+ // || property == "properties" || property == "fromState" || property == "toState"
+ // )
+ {
+ v.prepend('\"');
+ v.append('\"');
+ }
+ if (!newline)
+ out << property << ": " << v;
+ else
+ out << depthString() << property << ": " << v << endl;
+ }
+
+
+ typedef QPair<QString,QString> StringPair;
+ QList<StringPair> propertyChangeSet;
+ void startItem(bool inList = false) {
+
+ QString name = xml.name().toString();
+
+ out << depthString() << name << " {" << endl;
+ ++depth;
+
+ if (name == "State")
+ propertyChangeSet.clear();
+
+ foreach (QXmlStreamAttribute attribute, xml.attributes()) {
+ setProperty(attribute.name().toString(), attribute.value().toString());
+ }
+
+ loop();
+
+ if (name == "State" && !propertyChangeSet.isEmpty()) {
+ out << depthString() << "propertyChangeSet: PropertyChangeSet" << " {" << endl;
+ ++depth;
+ foreach(StringPair pair, propertyChangeSet)
+ setProperty(pair.first, pair.second);
+ --depth;
+ out << depthString() << "}" << endl;
+ propertyChangeSet.clear();
+ }
+
+ --depth;
+ out << depthString() << "}";
+ if (!inList)
+ out << endl;
+ }
+
+ void startObjectProperty() {
+
+ QString name = xml.name().toString();
+ bool hasElements = false;
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.tokenType() == QXmlStreamReader::EndElement)
+ break;
+ if (xml.tokenType() == QXmlStreamReader::StartElement) {
+ hasElements = true;
+ out << depthString() << name << ": ";
+ supressIndent = true;
+ startElement();
+ } else if (!hasElements && xml.tokenType() == QXmlStreamReader::Characters) {
+ if (!xml.text().toString().trimmed().isEmpty()) {
+ setProperty(name, xml.text().toString());
+ }
+ }
+ comment();
+ }
+ }
+
+ void startDeclareProperty() {
+ out << depthString() << "public property ";
+ QString name = xml.attributes().value("name").toString();
+
+ if (xml.attributes().hasAttribute("value"))
+ setProperty(name, xml.attributes().value("value").toString(), false);
+ else out << name;
+
+ QMap<QString, QString> attributes;
+ foreach (QXmlStreamAttribute attribute, xml.attributes()) {
+ if (attribute.name() == "name" || attribute.name() == "value")
+ continue;
+ attributes.insert(attribute.name().toString(), attribute.value().toString());
+ }
+ if (attributes.isEmpty()) {
+ out << endl;
+ } else {
+ out << " {" << endl;
+ ++depth;
+ foreach (QString key, attributes.keys())
+ setProperty(key, attributes.value(key));
+ --depth;
+ out << depthString() << "}" << endl;
+ }
+ emptyLoop();
+ }
+
+ void startDeclareProperties() {
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.tokenType() == QXmlStreamReader::EndElement)
+ return;
+ if (xml.tokenType() == QXmlStreamReader::StartElement) {
+ if (xml.name() == "Property")
+ startDeclareProperty();
+ }
+ comment();
+ }
+ }
+
+ void startDeclareSignal() {
+ out << depthString() << "public signal " << xml.attributes().value("name").toString() << endl;
+ emptyLoop();
+ }
+
+ void startDeclareSignals() {
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.tokenType() == QXmlStreamReader::EndElement)
+ return;
+ if (xml.tokenType() == QXmlStreamReader::StartElement) {
+ if (xml.name() == "Signal")
+ startDeclareSignal();
+ }
+ comment();
+ }
+ }
+
+
+ void startSetProperties() {
+ QString target = xml.attributes().value("target").toString();
+ possiblyRemoveBraces(&target);
+ foreach (QXmlStreamAttribute attribute, xml.attributes()) {
+ if (attribute.name() == "target")
+ continue;
+ propertyChangeSet += StringPair(target + "." + attribute.name().toString(), attribute.value().toString());
+ }
+ emptyLoop();
+ }
+
+ void startSetProperty() {
+ QString target = xml.attributes().value("target").toString();
+ possiblyRemoveBraces(&target);
+ propertyChangeSet += StringPair(target + "." + xml.attributes().value("property").toString(),
+ xml.attributes().value("value").toString());
+
+ emptyLoop();
+ }
+
+ void startParentChange() {
+ QString target = xml.attributes().value("target").toString();
+ possiblyRemoveBraces(&target);
+ propertyChangeSet += StringPair(target + ".parent", xml.attributes().value("parent").toString());
+ emptyLoop();
+ }
+
+ void startConnection() {
+ QString sender = xml.attributes().value("sender").toString();
+ possiblyRemoveBraces(&sender);
+ out << depthString() << "Connection {" << endl;
+ ++depth;
+ out << depthString() << "signal: " << sender + "." + xml.attributes().value("signal").toString() << endl;
+ out << depthString() << "onSignal: function(){ " << xml.attributes().value("script").toString() << " }" << endl;
+ --depth;
+ out << depthString() << "}" << endl;
+ emptyLoop();
+ }
+
+ void startScript() {
+ if (xml.attributes().hasAttribute(QLatin1String("src"))) {
+ QString import;
+ QTextStream ts(&import);
+ ts << "import \"";
+ ts << xml.attributes().value(QLatin1String("src")).toString();
+ ts << "\"" << endl;
+ ts.flush();
+ outString.prepend(import);
+ }
+ QString text = xml.readElementText();
+ if (!text.trimmed().isEmpty()) {
+ out << text << endl;
+ }
+ if (xml.tokenType() != QXmlStreamReader::EndElement)
+ emptyLoop();
+ }
+
+ void startList()
+ {
+ out << depthString() << xml.name().toString() << ": [" << endl;
+ ++depth;
+ bool needComma = false;
+
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.tokenType() == QXmlStreamReader::EndElement)
+ break;
+ if (xml.tokenType() == QXmlStreamReader::StartElement) {
+ if (needComma)
+ out << "," << endl;
+ startItem(true);
+ needComma = true;
+ }
+ comment();
+ }
+
+ out << endl;
+ --depth;
+ out << depthString() << "]" << endl;
+ }
+
+};
+
+
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ if (argc != 2) {
+ qWarning() << "Usage: qmlconf filename";
+ exit(1);
+ }
+
+ QFile file(argv[1]);
+ if (file.open(QIODevice::ReadOnly)) {
+ Reader r(&file);
+ }
+
+
+ file.close();
+ return 0;
+}
diff --git a/tools/qmlconv/qmlconv.pro b/tools/qmlconv/qmlconv.pro
new file mode 100644
index 0000000..839d0ff
--- /dev/null
+++ b/tools/qmlconv/qmlconv.pro
@@ -0,0 +1,10 @@
+DESTDIR = ../../bin
+QT -= gui
+# Input
+SOURCES += qmlconv.cpp
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+CONFIG += console
+
diff --git a/tools/tools.pro b/tools/tools.pro
index da4ff67..12da18c 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -24,7 +24,7 @@ mac {
SUBDIRS += kmap2qmap
-contains(QT_CONFIG, declarative):SUBDIRS += duiviewer
+contains(QT_CONFIG, declarative):SUBDIRS += duiviewer qmlconv
contains(QT_CONFIG, dbus):SUBDIRS += qdbus
!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns
embedded: SUBDIRS += makeqpf