173
143
QString BarDescriptorDocument::xmlSource() const
175
BarDescriptorEditor *editor = qobject_cast<BarDescriptorEditor*>(m_editorWidget->editor());
176
QTC_ASSERT(editor, return QString());
178
if (editor->activePage() == BarDescriptorEditor::Source) {
179
return m_editorWidget->xmlSource();
182
doc.appendChild(doc.createProcessingInstruction(QLatin1String("xml"), QLatin1String("version='1.0' encoding='") + QLatin1String(codec()->name()) + QLatin1String("' standalone='no'")));
185
QDomElement rootElem = doc.createElement(QLatin1String("qnx"));
186
rootElem.setAttribute(QLatin1String("xmlns"), QLatin1String("http://www.qnx.com/schemas/application/1.0"));
188
QMap<int, BarDescriptorDocumentAbstractNodeHandler*> nodeHandlerMap;
189
foreach (BarDescriptorDocumentAbstractNodeHandler *nodeHandler, m_nodeHandlers)
190
nodeHandlerMap.insertMulti(nodeHandler->order(), nodeHandler);
192
QList<BarDescriptorDocumentAbstractNodeHandler*> nodeHandlers = nodeHandlerMap.values();
193
foreach (BarDescriptorDocumentAbstractNodeHandler *nodeHandler, nodeHandlers)
194
rootElem.appendChild(nodeHandler->toNode(doc));
196
doc.appendChild(rootElem);
198
return doc.toString(4);
202
bool BarDescriptorDocument::loadContent(const QString &xmlSource, QString *errorMessage, int *errorLine)
205
bool result = doc.setContent(xmlSource, errorMessage, errorLine);
209
QDomElement docElem = doc.documentElement();
210
if (docElem.tagName() != QLatin1String("qnx"))
213
m_editorWidget->clear();
215
removeUnknownNodeHandlers();
216
foreach (BarDescriptorDocumentAbstractNodeHandler *nodeHandler, m_nodeHandlers)
217
nodeHandler->clear();
219
QDomNode node = docElem.firstChildElement();
220
while (!node.isNull()) {
221
BarDescriptorDocumentAbstractNodeHandler *nodeHandler = nodeHandlerForDomNode(node);
223
nodeHandler = new BarDescriptorDocumentUnknownNodeHandler(m_editorWidget);
224
registerNodeHandler(nodeHandler);
227
if (!nodeHandler->handle(node))
230
node = node.nextSibling();
233
m_editorWidget->setXmlSource(xmlSource);
238
void BarDescriptorDocument::registerNodeHandler(BarDescriptorDocumentAbstractNodeHandler *nodeHandler)
240
m_nodeHandlers << nodeHandler;
243
BarDescriptorDocumentAbstractNodeHandler *BarDescriptorDocument::nodeHandlerForDomNode(const QDomNode &node)
245
foreach (BarDescriptorDocumentAbstractNodeHandler *handler, m_nodeHandlers) {
246
if (handler->canHandle(node) && !dynamic_cast<BarDescriptorDocumentUnknownNodeHandler*>(handler))
253
void BarDescriptorDocument::removeUnknownNodeHandlers()
255
for (int i = m_nodeHandlers.size() - 1; i >= 0; --i) {
256
BarDescriptorDocumentUnknownNodeHandler *nodeHandler = dynamic_cast<BarDescriptorDocumentUnknownNodeHandler*>(m_nodeHandlers[i]);
258
m_nodeHandlers.removeAt(i);
145
const int indent = 4;
146
return m_barDocument.toString(indent);
149
bool BarDescriptorDocument::loadContent(const QString &xmlCode, bool setDirty, QString *errorMessage, int *errorLine)
151
if (xmlCode == xmlSource())
154
bool result = m_barDocument.setContent(xmlCode, errorMessage, errorLine);
159
emit Core::IDocument::changed();
163
QVariant BarDescriptorDocument::value(BarDescriptorDocument::Tag tag) const
165
const QString tagName = QString::fromLatin1(metaObject()->enumerator(metaObject()->enumeratorOffset()).valueToKey(tag));
176
return stringValue(tagName);
178
return childStringListValue(tagName, QLatin1String("image")).value(0);
180
return childStringListValue(tagName, QLatin1String("image"));
183
var.setValue(assets());
189
return childStringListValue(QLatin1String("initialWindow"), tagName).value(0);
191
return childStringListValue(QLatin1String("initialWindow"), tagName).value(0) == QLatin1String("true");
194
return stringListValue(tagName);
197
var.setValue(environment());
204
void BarDescriptorDocument::setValue(BarDescriptorDocument::Tag tag, const QVariant &value)
206
const QMetaEnum tagEnum = metaObject()->enumerator(metaObject()->enumeratorOffset());
207
const QString tagName = QString::fromLatin1(tagEnum.valueToKey(tag));
216
setStringValue(tagName, value.toString());
220
setChildStringListValue(tagName, QLatin1String("image"), value.toStringList());
223
setAssets(value.value<BarDescriptorAssetList>());
228
setChildStringListValue(QLatin1String("initialWindow"), tagName, value.toStringList());
231
setChildStringListValue(QLatin1String("initialWindow"), tagName, QStringList() << (value.toBool() ? QLatin1String("true") : QLatin1String("false")));
235
setStringListValue(tagName, value.toStringList());
238
setEnvironment(value.value<QList<Utils::EnvironmentItem> >());
242
// Unset <publisher> when setting <author> as only one should be used
243
setStringValue(QString::fromLatin1(tagEnum.valueToKey(author)), value.toString());
244
setStringValue(QString::fromLatin1(tagEnum.valueToKey(publisher)), QLatin1String(""));
249
emit changed(tag, value);
250
emit Core::IDocument::changed();
253
QString BarDescriptorDocument::stringValue(const QString &tagName) const
255
QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
256
if (nodes.isEmpty() || nodes.size() > 1)
259
QDomNode node = nodes.item(0);
260
QDomText textNode = node.firstChild().toText();
261
if (textNode.isNull())
264
return textNode.data();
267
void BarDescriptorDocument::setStringValue(const QString &tagName, const QString &value)
269
QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
271
if (nodes.size() > 1)
274
QDomNode existingNode = nodes.item(0);
275
if (existingNode.isNull() && value.isEmpty())
278
if (!existingNode.isNull() && value.isEmpty()) {
279
m_barDocument.documentElement().removeChild(existingNode);
280
} else if (existingNode.isNull()) {
281
QDomElement newNode = m_barDocument.createElement(tagName);
282
newNode.appendChild(m_barDocument.createTextNode(value));
283
m_barDocument.documentElement().appendChild(newNode);
285
QDomText textNode = existingNode.firstChild().toText();
286
if (textNode.isNull())
288
textNode.setData(value);
292
QStringList BarDescriptorDocument::childStringListValue(const QString &tagName, const QString &childTagName) const
294
QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
295
if (nodes.isEmpty() || nodes.size() > 1)
296
return QStringList();
298
QDomNode parentNode = nodes.item(0);
299
QDomElement childElm = parentNode.firstChildElement(childTagName);
300
if (childElm.isNull())
301
return QStringList();
304
while (!childElm.isNull()) {
305
QDomText textNode = childElm.firstChild().toText();
306
if (textNode.isNull())
307
return QStringList();
309
result.append(textNode.data());
311
childElm = childElm.nextSiblingElement(childTagName);
317
void BarDescriptorDocument::setChildStringListValue(const QString &tagName, const QString &childTagName, const QStringList &stringList)
319
QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
321
if (nodes.size() > 1)
324
QDomNode existingNode = nodes.item(0);
326
if (existingNode.isNull()) {
327
QDomElement newParentNode = m_barDocument.createElement(tagName);
329
foreach (const QString &value, stringList) {
330
QDomElement newChildNode = m_barDocument.createElement(childTagName);
331
QDomText newTextNode = m_barDocument.createTextNode(value);
332
newChildNode.appendChild(newTextNode);
333
newParentNode.appendChild(newChildNode);
335
m_barDocument.documentElement().appendChild(newParentNode);
337
QStringList values = stringList;
338
QDomElement childElm = existingNode.firstChildElement(childTagName);
339
if (!childElm.isNull()) {
340
// Loop through existing elements, remove the existing nodes
341
// that no longer are in "values", and remove from "values"
342
// the existing nodes that don't need re-creation
343
while (!childElm.isNull()) {
344
QDomText textNode = childElm.firstChild().toText();
345
if (textNode.isNull())
348
QDomElement toRemove;
349
if (!values.contains(textNode.data()))
352
values.removeAll(textNode.data());
354
childElm = childElm.nextSiblingElement(childTagName);
356
if (!toRemove.isNull())
357
existingNode.removeChild(toRemove);
361
// Add the new elements
362
int newElementCount = 0;
363
foreach (const QString &value, values) {
366
QDomElement newChildNode = m_barDocument.createElement(childTagName);
367
newChildNode.appendChild(m_barDocument.createTextNode(value));
368
existingNode.appendChild(newChildNode);
372
if (newElementCount == 0)
373
m_barDocument.documentElement().removeChild(existingNode);
377
QStringList BarDescriptorDocument::stringListValue(const QString &tagName) const
381
QDomElement childElm = m_barDocument.documentElement().firstChildElement(tagName);
382
while (!childElm.isNull()) {
383
QDomText textNode = childElm.firstChild().toText();
384
if (textNode.isNull())
387
result.append(textNode.data());
389
childElm = childElm.nextSiblingElement(tagName);
395
void BarDescriptorDocument::setStringListValue(const QString &tagName, const QStringList &stringList)
397
QStringList values = stringList;
398
QDomElement childElm = m_barDocument.documentElement().firstChildElement(tagName);
399
if (!childElm.isNull()) {
400
// Loop through existing elements, remove the existing nodes
401
// that no longer are in "values", and remove from "values"
402
// the existing nodes that don't need re-creation
403
while (!childElm.isNull()) {
404
QDomText textNode = childElm.firstChild().toText();
405
if (textNode.isNull())
408
QDomElement toRemove;
409
if (!values.contains(textNode.data()))
412
values.removeAll(textNode.data());
414
childElm = childElm.nextSiblingElement(tagName);
416
if (!toRemove.isNull())
417
m_barDocument.documentElement().removeChild(toRemove);
421
// Add the new elements
422
foreach (const QString &value, values) {
425
QDomElement newChildNode = m_barDocument.createElement(tagName);
426
newChildNode.appendChild(m_barDocument.createTextNode(value));
427
m_barDocument.documentElement().appendChild(newChildNode);
431
BarDescriptorAssetList BarDescriptorDocument::assets() const
433
BarDescriptorAssetList result;
434
QDomNodeList nodes = m_barDocument.elementsByTagName(QLatin1String("asset"));
438
for (int i = 0; i < nodes.size(); ++i) {
439
QDomElement assetElm = nodes.item(i).toElement();
440
if (assetElm.isNull())
443
QDomText textNode = assetElm.firstChild().toText();
444
if (textNode.isNull())
447
QString path = assetElm.attribute(QLatin1String("path"));
448
QString entry = assetElm.attribute(QLatin1String("entry"));
449
QString dest = textNode.data();
451
BarDescriptorAsset asset;
453
asset.destination = dest;
454
asset.entry = entry == QLatin1String("true");
455
result.append(asset);
461
void BarDescriptorDocument::setAssets(const BarDescriptorAssetList &assets)
463
QDomNodeList nodes = m_barDocument.elementsByTagName(QLatin1String("asset"));
465
BarDescriptorAssetList newAssets = assets;
466
QList<QDomNode> toRemove;
468
for (int i = 0; i < nodes.size(); ++i) {
469
QDomElement assetElm = nodes.at(i).toElement();
470
if (assetElm.isNull())
473
QDomText textNode = assetElm.firstChild().toText();
474
if (textNode.isNull())
477
QString source = assetElm.attribute(QLatin1String("path"));
479
foreach (const BarDescriptorAsset &asset, newAssets) {
480
if (asset.source == source) {
483
assetElm.setAttribute(QLatin1String("type"), QLatin1String("Qnx/Elf"));
484
assetElm.setAttribute(QLatin1String("entry"), QLatin1String("true"));
486
assetElm.removeAttribute(QLatin1String("type"));
487
assetElm.removeAttribute(QLatin1String("entry"));
489
textNode.setData(asset.destination);
491
newAssets.removeAll(asset);
497
toRemove.append(assetElm);
500
foreach (const QDomNode &node, toRemove)
501
m_barDocument.documentElement().removeChild(node);
503
foreach (const BarDescriptorAsset &asset, newAssets) {
504
QDomElement assetElm = m_barDocument.createElement(QLatin1String("asset"));
505
assetElm.setAttribute(QLatin1String("path"), asset.source);
507
assetElm.setAttribute(QLatin1String("type"), QLatin1String("Qnx/Elf"));
508
assetElm.setAttribute(QLatin1String("entry"), QLatin1String("true"));
510
assetElm.appendChild(m_barDocument.createTextNode(asset.destination));
511
m_barDocument.documentElement().appendChild(assetElm);
515
QList<Utils::EnvironmentItem> BarDescriptorDocument::environment() const
517
QList<Utils::EnvironmentItem> result;
519
QDomElement envElm = m_barDocument.documentElement().firstChildElement(QLatin1String("env"));
520
while (!envElm.isNull()) {
521
QString var = envElm.attribute(QLatin1String("var"));
522
QString value = envElm.attribute(QLatin1String("value"));
524
Utils::EnvironmentItem item(var, value);
527
envElm = envElm.nextSiblingElement(QLatin1String("env"));
532
void BarDescriptorDocument::setEnvironment(const QList<Utils::EnvironmentItem> &environment)
534
QDomNodeList envNodes = m_barDocument.elementsByTagName(QLatin1String("env"));
536
QList<Utils::EnvironmentItem> newEnvironment = environment;
537
QList<QDomElement> toRemove;
538
for (int i = 0; i < envNodes.size(); ++i) {
539
QDomElement elm = envNodes.at(i).toElement();
543
QString var = elm.attribute(QLatin1String("var"));
545
foreach (const Utils::EnvironmentItem item, newEnvironment) {
546
if (item.name == var) {
548
elm.setAttribute(QLatin1String("value"), item.value);
549
newEnvironment.removeAll(item);
555
toRemove.append(elm);
558
foreach (const QDomNode &node, toRemove)
559
m_barDocument.documentElement().removeChild(node);
561
foreach (const Utils::EnvironmentItem item, newEnvironment) {
562
QDomElement elm = m_barDocument.createElement(QLatin1String("env"));
563
elm.setAttribute(QLatin1String("var"), item.name);
564
elm.setAttribute(QLatin1String("value"), item.value);
565
m_barDocument.documentElement().appendChild(elm);
569
void BarDescriptorDocument::emitAllChanged()
571
QMetaEnum tags = metaObject()->enumerator(metaObject()->enumeratorOffset());
572
for (int i = 0; i < tags.keyCount(); ++i) {
573
Tag tag = static_cast<Tag>(tags.value(i));
574
emit changed(tag, value(tag));
578
QString BarDescriptorDocument::bannerComment() const
580
QDomNode nd = m_barDocument.firstChild();
581
QDomProcessingInstruction pi = nd.toProcessingInstruction();
583
nd = pi.nextSibling();
585
return nd.toComment().data();
588
void BarDescriptorDocument::setBannerComment(const QString &commentText)
590
QDomNode nd = m_barDocument.firstChild();
591
QDomProcessingInstruction pi = nd.toProcessingInstruction();
593
nd = pi.nextSibling();
595
bool oldDirty = m_dirty;
596
QDomComment cnd = nd.toComment();
598
if (!commentText.isEmpty()) {
599
cnd = m_barDocument.createComment(commentText);
600
m_barDocument.insertBefore(cnd, nd);
604
if (commentText.isEmpty()) {
605
m_barDocument.removeChild(cnd);
608
if (cnd.data() != commentText) {
609
cnd.setData(commentText);
614
if (m_dirty != oldDirty)
615
emit Core::IDocument::changed();
618
int BarDescriptorDocument::tagForElement(const QDomElement &element)
620
QMetaEnum tags = metaObject()->enumerator(metaObject()->enumeratorOffset());
621
QDomElement el = element;
622
while (!el.isNull()) {
623
const int n = tags.keyToValue(el.tagName().toLatin1().constData());
626
el = el.parentNode().toElement();
631
bool BarDescriptorDocument::expandPlaceHolder_helper(const QDomElement &el,
632
const QString &placeholderKey,
633
const QString &placeholderText,
634
QSet<BarDescriptorDocument::Tag> &changedTags)
636
// replace attributes
637
bool elementChanged = false;
638
QDomNamedNodeMap attrs = el.attributes();
639
for (int i = 0; i < attrs.count(); ++i) {
640
QDomAttr attr = attrs.item(i).toAttr();
641
if (!attr.isNull()) {
642
QString s = attr.value();
643
s.replace(placeholderKey, placeholderText);
644
if (s != attr.value()) {
646
elementChanged = true;
651
bool documentChanged = false;
653
for (QDomNode nd = el.firstChild(); !nd.isNull(); nd = nd.nextSibling()) {
654
QDomText txtnd = nd.toText();
655
if (!txtnd.isNull()) {
656
QString s = txtnd.data();
657
s.replace(placeholderKey, placeholderText);
658
if (s != txtnd.data()) {
660
elementChanged = true;
663
QDomElement child = nd.toElement();
664
if (!child.isNull()) {
665
bool hit = expandPlaceHolder_helper(child, placeholderKey, placeholderText, changedTags);
666
documentChanged = documentChanged || hit;
669
if (elementChanged) {
670
int n = tagForElement(el);
672
changedTags << static_cast<Tag>(n);
674
documentChanged = documentChanged || elementChanged;
675
return documentChanged;
678
void BarDescriptorDocument::expandPlaceHolders(const QHash<QString, QString> &placeholdersKeyVals)
680
QSet<Tag> changedTags;
681
QHashIterator<QString, QString> it(placeholdersKeyVals);
682
bool docChanged = false;
683
while (it.hasNext()) {
685
bool expanded = expandPlaceHolder_helper(m_barDocument.documentElement(),
686
it.key(), it.value(), changedTags);
687
docChanged = docChanged || expanded;
689
m_dirty = m_dirty || docChanged;
690
foreach (Tag tag, changedTags)
691
emit changed(tag, value(tag));
693
emit Core::IDocument::changed();