forked from qt-creator/qt-creator
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>
This commit is contained in:
committed by
Fanda Vacek
parent
e24b5c17d6
commit
b254313c68
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -54,6 +54,9 @@ public:
|
||||
private slots:
|
||||
void testBarDescriptorDocumentSetValue_data();
|
||||
void testBarDescriptorDocumentSetValue();
|
||||
|
||||
void testBarDescriptorDocumentSetBannerComment_data();
|
||||
void testBarDescriptorDocumentSetBannerComment();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user