summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantisek Vacek <fvacek@blackberry.com>2014-02-05 08:49:29 +0100
committerFanda Vacek <fvacek@blackberry.com>2014-02-05 11:39:48 +0100
commitb254313c686d07057acba243198100e49159e6e5 (patch)
tree4b34e9e0897f944fd3b60a4e80c1a1ecda2981d6
parente24b5c17d6ea598e27dbb8e0e2a1d6ac88b3501d (diff)
downloadqt-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>
-rw-r--r--src/plugins/qnx/bardescriptordocument.cpp120
-rw-r--r--src/plugins/qnx/bardescriptordocument.h11
-rw-r--r--src/plugins/qnx/blackberrycreatepackagestep.cpp92
-rw-r--r--src/plugins/qnx/qnxplugin.cpp61
-rw-r--r--src/plugins/qnx/qnxplugin.h3
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
};