diff options
author | Frantisek Vacek <fvacek@blackberry.com> | 2014-02-05 08:49:29 +0100 |
---|---|---|
committer | Fanda Vacek <fvacek@blackberry.com> | 2014-02-05 11:39:48 +0100 |
commit | b254313c686d07057acba243198100e49159e6e5 (patch) | |
tree | 4b34e9e0897f944fd3b60a4e80c1a1ecda2981d6 /src/plugins/qnx | |
parent | e24b5c17d6ea598e27dbb8e0e2a1d6ac88b3501d (diff) | |
download | qt-creator-b254313c686d07057acba243198100e49159e6e5.tar.gz |
QNX: Use BarDescriptorDocument API to prepare bar-descriptor for deployment
Patch is refactoring create package step to use new BarDescriptorDocument
class when bar-descriptor.xml is prepared for deployment.
BarDescriptorDocument API is extended to allow this.
Change-Id: If00fba3310c5acf1cc8feefe0cf919aa2a05637e
Reviewed-by: Tobias Nätterlund <tobias.naetterlund@kdab.com>
Reviewed-by: Mehdi Fekari <mfekari@blackberry.com>
Reviewed-by: Nicolas Arnaud-Cormos <nicolas@kdab.com>
Diffstat (limited to 'src/plugins/qnx')
-rw-r--r-- | src/plugins/qnx/bardescriptordocument.cpp | 120 | ||||
-rw-r--r-- | src/plugins/qnx/bardescriptordocument.h | 11 | ||||
-rw-r--r-- | src/plugins/qnx/blackberrycreatepackagestep.cpp | 92 | ||||
-rw-r--r-- | src/plugins/qnx/qnxplugin.cpp | 61 | ||||
-rw-r--r-- | src/plugins/qnx/qnxplugin.h | 3 |
5 files changed, 242 insertions, 45 deletions
diff --git a/src/plugins/qnx/bardescriptordocument.cpp b/src/plugins/qnx/bardescriptordocument.cpp index b07c92daee..92b80f06f8 100644 --- a/src/plugins/qnx/bardescriptordocument.cpp +++ b/src/plugins/qnx/bardescriptordocument.cpp @@ -40,6 +40,7 @@ #include <QFileInfo> #include <QMetaEnum> #include <QTextCodec> +#include <QSet> using namespace Qnx; using namespace Qnx::Internal; @@ -573,3 +574,122 @@ void BarDescriptorDocument::emitAllChanged() emit changed(tag, value(tag)); } } + +QString BarDescriptorDocument::bannerComment() const +{ + QDomNode nd = m_barDocument.firstChild(); + QDomProcessingInstruction pi = nd.toProcessingInstruction(); + if (!pi.isNull()) + nd = pi.nextSibling(); + + return nd.toComment().data(); +} + +void BarDescriptorDocument::setBannerComment(const QString &commentText) +{ + QDomNode nd = m_barDocument.firstChild(); + QDomProcessingInstruction pi = nd.toProcessingInstruction(); + if (!pi.isNull()) + nd = pi.nextSibling(); + + bool oldDirty = m_dirty; + QDomComment cnd = nd.toComment(); + if (cnd.isNull()) { + if (!commentText.isEmpty()) { + cnd = m_barDocument.createComment(commentText); + m_barDocument.insertBefore(cnd, nd); + m_dirty = true; + } + } else { + if (commentText.isEmpty()) { + m_barDocument.removeChild(cnd); + m_dirty = true; + } else { + if (cnd.data() != commentText) { + cnd.setData(commentText); + m_dirty = true; + } + } + } + if (m_dirty != oldDirty) + emit Core::IDocument::changed(); +} + +int BarDescriptorDocument::tagForElement(const QDomElement &element) +{ + QMetaEnum tags = metaObject()->enumerator(metaObject()->enumeratorOffset()); + QDomElement el = element; + while (!el.isNull()) { + bool ok; + int n = tags.keyToValue(el.tagName().toLatin1().constData(), &ok); + if (ok) + return n; + el = el.parentNode().toElement(); + } + return -1; +} + +bool BarDescriptorDocument::expandPlaceHolder_helper(const QDomElement &el, + const QString &placeholderKey, + const QString &placeholderText, + QSet<BarDescriptorDocument::Tag> &changedTags) +{ + // replace attributes + bool elementChanged = false; + QDomNamedNodeMap attrs = el.attributes(); + for (int i = 0; i < attrs.count(); ++i) { + QDomAttr attr = attrs.item(i).toAttr(); + if (!attr.isNull()) { + QString s = attr.value(); + s.replace(placeholderKey, placeholderText); + if (s != attr.value()) { + attr.setValue(s); + elementChanged = true; + } + } + } + + bool documentChanged = false; + // replace text + for (QDomNode nd = el.firstChild(); !nd.isNull(); nd = nd.nextSibling()) { + QDomText txtnd = nd.toText(); + if (!txtnd.isNull()) { + QString s = txtnd.data(); + s.replace(placeholderKey, placeholderText); + if (s != txtnd.data()) { + txtnd.setData(s); + elementChanged = true; + } + } + QDomElement child = nd.toElement(); + if (!child.isNull()) { + bool hit = expandPlaceHolder_helper(child, placeholderKey, placeholderText, changedTags); + documentChanged = documentChanged || hit; + } + } + if (elementChanged) { + int n = tagForElement(el); + if (n >= 0) + changedTags << static_cast<Tag>(n); + } + documentChanged = documentChanged || elementChanged; + return documentChanged; +} + +void BarDescriptorDocument::expandPlaceHolders(const QHash<QString, QString> &placeholdersKeyVals) +{ + QSet<Tag> changedTags; + QHashIterator<QString, QString> it(placeholdersKeyVals); + bool docChanged = false; + while (it.hasNext()) { + it.next(); + bool expanded = expandPlaceHolder_helper(m_barDocument.documentElement(), + it.key(), it.value(), changedTags); + docChanged = docChanged || expanded; + } + m_dirty = m_dirty || docChanged; + foreach (Tag tag, changedTags) + emit changed(tag, value(tag)); + if (docChanged) + emit Core::IDocument::changed(); +} diff --git a/src/plugins/qnx/bardescriptordocument.h b/src/plugins/qnx/bardescriptordocument.h index 05c135f777..87a745bdda 100644 --- a/src/plugins/qnx/bardescriptordocument.h +++ b/src/plugins/qnx/bardescriptordocument.h @@ -105,12 +105,16 @@ public: QVariant value(Tag tag) const; + void expandPlaceHolders(const QHash<QString, QString> &placeholdersKeyVals); + + QString bannerComment() const; + void setBannerComment(const QString &commentText); + signals: void changed(BarDescriptorDocument::Tag tag, const QVariant &value); public slots: void setValue(BarDescriptorDocument::Tag tag, const QVariant &value); - private: QString stringValue(const QString &tagName) const; void setStringValue(const QString &tagName, const QString &value); @@ -127,6 +131,11 @@ private: QList<Utils::EnvironmentItem> environment() const; void setEnvironment(const QList<Utils::EnvironmentItem> &environment); + int tagForElement(const QDomElement &element); + bool expandPlaceHolder_helper(const QDomElement &el, const QString &placeholderKey, + const QString &placeholderText, + QSet<BarDescriptorDocument::Tag> &changedTags); + void emitAllChanged(); bool m_dirty; diff --git a/src/plugins/qnx/blackberrycreatepackagestep.cpp b/src/plugins/qnx/blackberrycreatepackagestep.cpp index 1679435442..440388556d 100644 --- a/src/plugins/qnx/blackberrycreatepackagestep.cpp +++ b/src/plugins/qnx/blackberrycreatepackagestep.cpp @@ -39,6 +39,7 @@ #include "blackberrydeviceconfiguration.h" #include "blackberrydeployinformation.h" #include "blackberrysigningpasswordsdialog.h" +#include "bardescriptordocument.h" #include <debugger/debuggerrunconfigurationaspect.h> #include <projectexplorer/projectexplorerconstants.h> @@ -50,24 +51,12 @@ #include <qtsupport/qtkitinformation.h> #include <utils/qtcassert.h> -#include <QFile> - using namespace Qnx; using namespace Qnx::Internal; namespace { const char PACKAGER_CMD[] = "blackberry-nativepackager"; -const char QT_INSTALL_LIBS[] = "QT_INSTALL_LIBS"; -const char QT_INSTALL_LIBS_VAR[] = "%QT_INSTALL_LIBS%"; -const char QT_INSTALL_PLUGINS[] = "QT_INSTALL_PLUGINS"; -const char QT_INSTALL_PLUGINS_VAR[] = "%QT_INSTALL_PLUGINS%"; -const char QT_INSTALL_IMPORTS[] = "QT_INSTALL_IMPORTS"; -const char QT_INSTALL_IMPORTS_VAR[] = "%QT_INSTALL_IMPORTS%"; -const char QT_INSTALL_QML[] = "QT_INSTALL_QML"; -const char QT_INSTALL_QML_VAR[] = "%QT_INSTALL_QML%"; -const char SRC_DIR_VAR[] = "%SRC_DIR%"; - const char PACKAGE_MODE_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.PackageMode"; const char CSK_PASSWORD_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.CskPassword"; const char KEYSTORE_PASSWORD_KEY[] = "Qt4ProjectManager.BlackBerryCreatePackageStep.KeystorePassword"; @@ -253,6 +242,13 @@ void BlackBerryCreatePackageStep::setSavePasswords(bool savePasswords) m_savePasswords = savePasswords; } +static void addQtInfoPlaceHolderToHash(QHash<QString, QString> &hash, + const BlackBerryQtVersion *qtVersion, const char *key) +{ + hash[QLatin1Char('%') + QString::fromLatin1(key) + QLatin1Char('%')] = + qtVersion->versionInfo().value(QLatin1String(key)); +} + bool BlackBerryCreatePackageStep::prepareAppDescriptorFile(const QString &appDescriptorPath, const QString &preparedFilePath) { BlackBerryQtVersion *qtVersion = dynamic_cast<BlackBerryQtVersion *>(QtSupport::QtKitInformation::qtVersion(target()->kit())); @@ -261,54 +257,62 @@ bool BlackBerryCreatePackageStep::prepareAppDescriptorFile(const QString &appDes return false; } - QFile file(appDescriptorPath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - raiseError(tr("Could not open '%1' for reading").arg(appDescriptorPath)); + BarDescriptorDocument doc; + QString errorString; + if (!doc.open(&errorString, appDescriptorPath)) { + raiseError(tr("Error opening application descriptor file '%1' - %2") + .arg(QDir::toNativeSeparators(appDescriptorPath)) + .arg(errorString)); return false; } - - QFile preparedFile(preparedFilePath); - - QByteArray fileContent = file.readAll(); - // Add Warning text - const QString warningText = QString::fromLatin1("<!-- This file is autogenerated;" - " any changes will get overwritten if deploying with Qt Creator -->\n<qnx"); - fileContent.replace("<qnx", warningText.toLatin1()); + const QString warningText = QString::fromLatin1("This file is autogenerated," + " any changes will get overwritten if deploying with Qt Creator"); + doc.setBannerComment(warningText); // Replace Qt path placeholders - if (fileContent.contains(QT_INSTALL_LIBS_VAR)) - fileContent.replace(QT_INSTALL_LIBS_VAR, qtVersion->versionInfo().value(QLatin1String(QT_INSTALL_LIBS)).toLatin1()); - if (fileContent.contains(QT_INSTALL_PLUGINS_VAR)) - fileContent.replace(QT_INSTALL_PLUGINS_VAR, qtVersion->versionInfo().value(QLatin1String(QT_INSTALL_PLUGINS)).toLatin1()); - if (fileContent.contains(QT_INSTALL_IMPORTS_VAR)) - fileContent.replace(QT_INSTALL_IMPORTS_VAR, qtVersion->versionInfo().value(QLatin1String(QT_INSTALL_IMPORTS)).toLatin1()); - if (fileContent.contains(QT_INSTALL_QML_VAR)) - fileContent.replace(QT_INSTALL_QML_VAR, qtVersion->versionInfo().value(QLatin1String(QT_INSTALL_QML)).toLatin1()); - + QHash<QString, QString> placeHoldersHash; + addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_LIBS"); + addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_PLUGINS"); + addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_IMPORTS"); + addQtInfoPlaceHolderToHash(placeHoldersHash, qtVersion, "QT_INSTALL_QML"); //Replace Source path placeholder - if (fileContent.contains(SRC_DIR_VAR)) - fileContent.replace(SRC_DIR_VAR, QDir::toNativeSeparators(target()->project()->projectDirectory()).toLatin1()); + placeHoldersHash[QLatin1String("%SRC_DIR%")] = + QDir::toNativeSeparators(target()->project()->projectDirectory()); + doc.expandPlaceHolders(placeHoldersHash); + + QStringList commandLineArguments = doc.value(BarDescriptorDocument::arg).toStringList(); + QStringList extraCommandLineArguments; // Add parameter for QML debugging (if enabled) Debugger::DebuggerRunConfigurationAspect *aspect = target()->activeRunConfiguration()->extraAspect<Debugger::DebuggerRunConfigurationAspect>(); if (aspect->useQmlDebugger()) { - if (!fileContent.contains("-qmljsdebugger")) { - const QString argString = QString::fromLatin1("<arg>-qmljsdebugger=port:%1</arg>\n</qnx>") - .arg(aspect->qmlDebugServerPort()); - fileContent.replace("</qnx>", argString.toLatin1()); + bool qmljsdebuggerExists = false; + foreach (const QString &s, commandLineArguments) { + if (s.startsWith(QLatin1String("-qmljsdebugger="))) { + qmljsdebuggerExists = true; + break; + } + } + if (!qmljsdebuggerExists) { + extraCommandLineArguments << QString::fromLatin1("-qmljsdebugger=port:%1") + .arg(aspect->qmlDebugServerPort()); } } - if (!preparedFile.open(QIODevice::WriteOnly)) { - const QString buildDir = target()->activeBuildConfiguration()->buildDirectory().toUserOutput(); - raiseError(tr("Could not create prepared application descriptor file in '%1'").arg(buildDir)); - return false; + if (extraCommandLineArguments.count()) { + commandLineArguments << extraCommandLineArguments; + doc.setValue(BarDescriptorDocument::arg, commandLineArguments); } - preparedFile.write(fileContent); - preparedFile.close(); + doc.setFilePath(preparedFilePath); + if (!doc.save(&errorString)) { + raiseError(tr("Error saving prepared application descriptor file '%1' - %2") + .arg(QDir::toNativeSeparators(preparedFilePath)) + .arg(errorString)); + return false; + } return true; } diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp index 465086da8f..6fcf1b0bc6 100644 --- a/src/plugins/qnx/qnxplugin.cpp +++ b/src/plugins/qnx/qnxplugin.cpp @@ -331,6 +331,67 @@ void QNXPlugin::testBarDescriptorDocumentSetValue() QCOMPARE(doc.value(tag), value); } +void QNXPlugin::testBarDescriptorDocumentSetBannerComment_data() +{ + QTest::addColumn<QString>("comment"); + QTest::addColumn<QString>("baseXml"); + QTest::addColumn<QString>("xml"); + + QString procInstr = QString::fromLatin1("<?xml version='1.0' encoding='UTF-8' standalone='no'?>"); + QString comment = QString::fromLatin1("This file is autogenerated, any change will be ..."); + QString xmlComment = QString::fromLatin1("<!--%1-->").arg(comment); + QString oldXmlComment = QString::fromLatin1("<!-- Some old banner comment -->"); + QString docRoot = QString::fromLatin1("<qnx xmlns=\"http://www.qnx.com/schemas/application/1.0\"/>"); + QChar lf = QChar::fromLatin1('\n'); + + QTest::newRow("new-comment") + << comment + << QString(procInstr + lf + docRoot + lf) + << QString(procInstr + lf + xmlComment + lf + docRoot + lf); + + QTest::newRow("new-comment-noproc") + << comment + << QString(docRoot + lf) + << QString(xmlComment + lf + docRoot + lf); + + QTest::newRow("replace-comment") + << comment + << QString(procInstr + lf + oldXmlComment + lf + docRoot + lf) + << QString(procInstr + lf + xmlComment + lf + docRoot + lf); + + QTest::newRow("replace-comment-noproc") + << comment + << QString(oldXmlComment + lf + docRoot + lf) + << QString(xmlComment + lf + docRoot + lf); + + QTest::newRow("remove-comment") + << QString() + << QString(procInstr + lf + oldXmlComment + lf + docRoot + lf) + << QString(procInstr + lf + docRoot + lf); + + QTest::newRow("remove-comment-noproc") + << QString() + << QString(oldXmlComment + lf + docRoot + lf) + << QString(docRoot + lf); + +} + +void QNXPlugin::testBarDescriptorDocumentSetBannerComment() +{ + QFETCH(QString, comment); + QFETCH(QString, baseXml); + QFETCH(QString, xml); + + BarDescriptorDocument doc; + doc.loadContent(baseXml, false); + QCOMPARE(doc.xmlSource(), baseXml); + + doc.setBannerComment(comment); + QCOMPARE(doc.xmlSource(), xml); + QCOMPARE(doc.isModified(), true); + QCOMPARE(doc.bannerComment(), comment); +} + #endif Q_EXPORT_PLUGIN2(QNX, QNXPlugin) diff --git a/src/plugins/qnx/qnxplugin.h b/src/plugins/qnx/qnxplugin.h index 9286464c8c..3a9820b87b 100644 --- a/src/plugins/qnx/qnxplugin.h +++ b/src/plugins/qnx/qnxplugin.h @@ -54,6 +54,9 @@ public: private slots: void testBarDescriptorDocumentSetValue_data(); void testBarDescriptorDocumentSetValue(); + + void testBarDescriptorDocumentSetBannerComment_data(); + void testBarDescriptorDocumentSetBannerComment(); #endif }; |