~ubuntu-sdk-team/qtcreator-plugin-remotelinux/trunk

« back to all changes in this revision

Viewing changes to src/qnx/bardescriptordocument.cpp

  • Committer: CI bot
  • Author(s): Benjamin Zeller
  • Date: 2014-06-16 10:28:43 UTC
  • mfrom: (4.2.4 remotelinux)
  • Revision ID: ps-jenkins@lists.canonical.com-20140616102843-8juvmjvzwlzsboyw
Migrating to Qt5.3 and QtC 3.1 

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include "bardescriptordocument.h"
33
33
 
34
34
#include "qnxconstants.h"
35
 
#include "bardescriptoreditor.h"
36
 
#include "bardescriptoreditorwidget.h"
37
 
#include "bardescriptordocumentnodehandlers.h"
38
35
 
39
 
#include <coreplugin/editormanager/ieditor.h>
40
36
#include <coreplugin/editormanager/editormanager.h>
41
37
#include <utils/qtcassert.h>
42
38
 
43
 
#include <QFile>
 
39
#include <QDir>
44
40
#include <QFileInfo>
45
 
#include <QDir>
 
41
#include <QMetaEnum>
46
42
#include <QTextCodec>
 
43
#include <QSet>
47
44
 
48
45
using namespace Qnx;
49
46
using namespace Qnx::Internal;
50
47
 
51
 
BarDescriptorDocument::BarDescriptorDocument(BarDescriptorEditorWidget *editorWidget)
52
 
    : Core::TextDocument(editorWidget)
53
 
    , m_nodeHandlers(QList<BarDescriptorDocumentAbstractNodeHandler *>())
54
 
    , m_editorWidget(editorWidget)
 
48
BarDescriptorDocument::BarDescriptorDocument(QObject *parent)
 
49
    : Core::TextDocument(parent)
55
50
{
56
 
    // General
57
 
    registerNodeHandler(new BarDescriptorDocumentIdNodeHandler(m_editorWidget));
58
 
    registerNodeHandler(new BarDescriptorDocumentVersionNumberNodeHandler(m_editorWidget));
59
 
    registerNodeHandler(new BarDescriptorDocumentBuildIdNodeHandler(m_editorWidget));
60
 
    registerNodeHandler(new BarDescriptorDocumentAuthorNodeHandler(m_editorWidget));
61
 
    registerNodeHandler(new BarDescriptorDocumentAuthorIdNodeHandler(m_editorWidget));
62
 
 
63
 
    // Application
64
 
    registerNodeHandler(new BarDescriptorDocumentApplicationNameNodeHandler(m_editorWidget));
65
 
    registerNodeHandler(new BarDescriptorDocumentApplicationDescriptionNodeHandler(m_editorWidget));
66
 
    registerNodeHandler(new BarDescriptorDocumentApplicationIconNodeHandler(m_editorWidget));
67
 
    registerNodeHandler(new BarDescriptorDocumentSplashScreenNodeHandler(m_editorWidget));
68
 
    registerNodeHandler(new BarDescriptorDocumentInitialWindowNodeHandler(m_editorWidget));
69
 
    registerNodeHandler(new BarDescriptorDocumentArgNodeHandler(m_editorWidget));
70
 
    registerNodeHandler(new BarDescriptorDocumentActionNodeHandler(m_editorWidget));
71
 
    registerNodeHandler(new BarDescriptorDocumentEnvNodeHandler(m_editorWidget));
72
 
 
73
 
    // Assets
74
 
    registerNodeHandler(new BarDescriptorDocumentAssetNodeHandler(m_editorWidget));
75
 
 
76
51
    // blackberry-nativepackager requires the XML file to be in UTF-8 encoding,
77
52
    // force if possible
78
53
    if (QTextCodec *defaultUTF8 = QTextCodec::codecForName("UTF-8"))
83
58
 
84
59
BarDescriptorDocument::~BarDescriptorDocument()
85
60
{
86
 
    while (!m_nodeHandlers.isEmpty()) {
87
 
        BarDescriptorDocumentAbstractNodeHandler *nodeHandler = m_nodeHandlers.takeFirst();
88
 
        delete nodeHandler;
89
 
    }
90
61
}
91
62
 
92
63
bool BarDescriptorDocument::open(QString *errorString, const QString &fileName) {
95
66
        return false;
96
67
 
97
68
    setFilePath(fileName);
98
 
    m_editorWidget->setFilePath(fileName);
99
69
 
100
 
    bool result = loadContent(contents);
 
70
    const bool result = loadContent(contents, false);
101
71
 
102
72
    if (!result)
103
73
        *errorString = tr("%1 does not appear to be a valid application descriptor file").arg(QDir::toNativeSeparators(fileName));
110
80
    QTC_ASSERT(!autoSave, return false);
111
81
    QTC_ASSERT(fn.isEmpty(), return false);
112
82
 
113
 
    bool result = write(filePath(), xmlSource(), errorString);
 
83
    const bool result = write(filePath(), xmlSource(), errorString);
114
84
    if (!result)
115
85
        return false;
116
86
 
117
 
    m_editorWidget->setDirty(false);
118
 
    emit changed();
 
87
    m_dirty = false;
 
88
    emit Core::IDocument::changed();
119
89
    return true;
120
90
}
121
91
 
143
113
 
144
114
bool BarDescriptorDocument::isModified() const
145
115
{
146
 
    return m_editorWidget->isDirty();
 
116
    return m_dirty;
147
117
}
148
118
 
149
119
bool BarDescriptorDocument::isSaveAsAllowed() const
172
142
 
173
143
QString BarDescriptorDocument::xmlSource() const
174
144
{
175
 
    BarDescriptorEditor *editor = qobject_cast<BarDescriptorEditor*>(m_editorWidget->editor());
176
 
    QTC_ASSERT(editor, return QString());
177
 
 
178
 
    if (editor->activePage() == BarDescriptorEditor::Source) {
179
 
        return m_editorWidget->xmlSource();
180
 
    } else {
181
 
        QDomDocument doc;
182
 
        doc.appendChild(doc.createProcessingInstruction(QLatin1String("xml"), QLatin1String("version='1.0' encoding='") + QLatin1String(codec()->name()) + QLatin1String("' standalone='no'")));
183
 
 
184
 
        // QNX
185
 
        QDomElement rootElem = doc.createElement(QLatin1String("qnx"));
186
 
        rootElem.setAttribute(QLatin1String("xmlns"), QLatin1String("http://www.qnx.com/schemas/application/1.0"));
187
 
 
188
 
        QMap<int, BarDescriptorDocumentAbstractNodeHandler*> nodeHandlerMap;
189
 
        foreach (BarDescriptorDocumentAbstractNodeHandler *nodeHandler, m_nodeHandlers)
190
 
            nodeHandlerMap.insertMulti(nodeHandler->order(), nodeHandler);
191
 
 
192
 
        QList<BarDescriptorDocumentAbstractNodeHandler*> nodeHandlers = nodeHandlerMap.values();
193
 
        foreach (BarDescriptorDocumentAbstractNodeHandler *nodeHandler, nodeHandlers)
194
 
            rootElem.appendChild(nodeHandler->toNode(doc));
195
 
 
196
 
        doc.appendChild(rootElem);
197
 
 
198
 
        return doc.toString(4);
199
 
    }
200
 
}
201
 
 
202
 
bool BarDescriptorDocument::loadContent(const QString &xmlSource, QString *errorMessage, int *errorLine)
203
 
{
204
 
    QDomDocument doc;
205
 
    bool result = doc.setContent(xmlSource, errorMessage, errorLine);
206
 
    if (!result)
207
 
        return false;
208
 
 
209
 
    QDomElement docElem = doc.documentElement();
210
 
    if (docElem.tagName() != QLatin1String("qnx"))
211
 
        return false;
212
 
 
213
 
    m_editorWidget->clear();
214
 
 
215
 
    removeUnknownNodeHandlers();
216
 
    foreach (BarDescriptorDocumentAbstractNodeHandler *nodeHandler, m_nodeHandlers)
217
 
        nodeHandler->clear();
218
 
 
219
 
    QDomNode node = docElem.firstChildElement();
220
 
    while (!node.isNull()) {
221
 
        BarDescriptorDocumentAbstractNodeHandler *nodeHandler = nodeHandlerForDomNode(node);
222
 
        if (!nodeHandler) {
223
 
            nodeHandler = new BarDescriptorDocumentUnknownNodeHandler(m_editorWidget);
224
 
            registerNodeHandler(nodeHandler);
225
 
        }
226
 
 
227
 
        if (!nodeHandler->handle(node))
228
 
            return false;
229
 
 
230
 
        node = node.nextSibling();
231
 
    }
232
 
 
233
 
    m_editorWidget->setXmlSource(xmlSource);
234
 
 
235
 
    return true;
236
 
}
237
 
 
238
 
void BarDescriptorDocument::registerNodeHandler(BarDescriptorDocumentAbstractNodeHandler *nodeHandler)
239
 
{
240
 
    m_nodeHandlers << nodeHandler;
241
 
}
242
 
 
243
 
BarDescriptorDocumentAbstractNodeHandler *BarDescriptorDocument::nodeHandlerForDomNode(const QDomNode &node)
244
 
{
245
 
    foreach (BarDescriptorDocumentAbstractNodeHandler *handler, m_nodeHandlers) {
246
 
        if (handler->canHandle(node) && !dynamic_cast<BarDescriptorDocumentUnknownNodeHandler*>(handler))
247
 
            return handler;
248
 
    }
249
 
 
250
 
    return 0;
251
 
}
252
 
 
253
 
void BarDescriptorDocument::removeUnknownNodeHandlers()
254
 
{
255
 
    for (int i = m_nodeHandlers.size() - 1; i >= 0; --i) {
256
 
        BarDescriptorDocumentUnknownNodeHandler *nodeHandler = dynamic_cast<BarDescriptorDocumentUnknownNodeHandler*>(m_nodeHandlers[i]);
257
 
        if (nodeHandler) {
258
 
            m_nodeHandlers.removeAt(i);
259
 
            delete nodeHandler;
260
 
        }
261
 
    }
 
145
    const int indent = 4;
 
146
    return m_barDocument.toString(indent);
 
147
}
 
148
 
 
149
bool BarDescriptorDocument::loadContent(const QString &xmlCode, bool setDirty, QString *errorMessage, int *errorLine)
 
150
{
 
151
    if (xmlCode == xmlSource())
 
152
        return true;
 
153
 
 
154
    bool result = m_barDocument.setContent(xmlCode, errorMessage, errorLine);
 
155
 
 
156
    m_dirty = setDirty;
 
157
 
 
158
    emitAllChanged();
 
159
    emit Core::IDocument::changed();
 
160
    return result;
 
161
}
 
162
 
 
163
QVariant BarDescriptorDocument::value(BarDescriptorDocument::Tag tag) const
 
164
{
 
165
    const QString tagName = QString::fromLatin1(metaObject()->enumerator(metaObject()->enumeratorOffset()).valueToKey(tag));
 
166
 
 
167
    switch (tag) {
 
168
    case id:
 
169
    case versionNumber:
 
170
    case buildId:
 
171
    case name:
 
172
    case description:
 
173
    case author:
 
174
    case publisher:
 
175
    case authorId:
 
176
        return stringValue(tagName);
 
177
    case icon:
 
178
        return childStringListValue(tagName, QLatin1String("image")).value(0);
 
179
    case splashScreens:
 
180
        return childStringListValue(tagName, QLatin1String("image"));
 
181
    case asset: {
 
182
        QVariant var;
 
183
        var.setValue(assets());
 
184
        return var;
 
185
    }
 
186
    case aspectRatio:
 
187
    case autoOrients:
 
188
    case systemChrome:
 
189
        return childStringListValue(QLatin1String("initialWindow"), tagName).value(0);
 
190
    case transparent:
 
191
        return childStringListValue(QLatin1String("initialWindow"), tagName).value(0) == QLatin1String("true");
 
192
    case arg:
 
193
    case action:
 
194
        return stringListValue(tagName);
 
195
    case env:
 
196
        QVariant var;
 
197
        var.setValue(environment());
 
198
        return var;
 
199
    }
 
200
 
 
201
    return QVariant();
 
202
}
 
203
 
 
204
void BarDescriptorDocument::setValue(BarDescriptorDocument::Tag tag, const QVariant &value)
 
205
{
 
206
    const QMetaEnum tagEnum = metaObject()->enumerator(metaObject()->enumeratorOffset());
 
207
    const QString tagName = QString::fromLatin1(tagEnum.valueToKey(tag));
 
208
 
 
209
    switch (tag) {
 
210
    case id:
 
211
    case versionNumber:
 
212
    case buildId:
 
213
    case name:
 
214
    case description:
 
215
    case authorId:
 
216
        setStringValue(tagName, value.toString());
 
217
        break;
 
218
    case icon:
 
219
    case splashScreens:
 
220
        setChildStringListValue(tagName, QLatin1String("image"), value.toStringList());
 
221
        break;
 
222
    case asset:
 
223
        setAssets(value.value<BarDescriptorAssetList>());
 
224
        break;
 
225
    case aspectRatio:
 
226
    case autoOrients:
 
227
    case systemChrome:
 
228
        setChildStringListValue(QLatin1String("initialWindow"), tagName, value.toStringList());
 
229
        break;
 
230
    case transparent:
 
231
        setChildStringListValue(QLatin1String("initialWindow"), tagName, QStringList() << (value.toBool() ? QLatin1String("true") : QLatin1String("false")));
 
232
        break;
 
233
    case arg:
 
234
    case action:
 
235
        setStringListValue(tagName, value.toStringList());
 
236
        break;
 
237
    case env:
 
238
        setEnvironment(value.value<QList<Utils::EnvironmentItem> >());
 
239
        break;
 
240
    case author:
 
241
    case publisher:
 
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(""));
 
245
        break;
 
246
    }
 
247
 
 
248
    m_dirty = true;
 
249
    emit changed(tag, value);
 
250
    emit Core::IDocument::changed();
 
251
}
 
252
 
 
253
QString BarDescriptorDocument::stringValue(const QString &tagName) const
 
254
{
 
255
    QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
 
256
    if (nodes.isEmpty() || nodes.size() > 1)
 
257
        return QString();
 
258
 
 
259
    QDomNode node = nodes.item(0);
 
260
    QDomText textNode = node.firstChild().toText();
 
261
    if (textNode.isNull())
 
262
        return QString();
 
263
 
 
264
    return textNode.data();
 
265
}
 
266
 
 
267
void BarDescriptorDocument::setStringValue(const QString &tagName, const QString &value)
 
268
{
 
269
    QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
 
270
 
 
271
    if (nodes.size() > 1)
 
272
        return;
 
273
 
 
274
    QDomNode existingNode = nodes.item(0);
 
275
    if (existingNode.isNull() && value.isEmpty())
 
276
        return;
 
277
 
 
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);
 
284
    } else {
 
285
        QDomText textNode = existingNode.firstChild().toText();
 
286
        if (textNode.isNull())
 
287
            return;
 
288
        textNode.setData(value);
 
289
    }
 
290
}
 
291
 
 
292
QStringList BarDescriptorDocument::childStringListValue(const QString &tagName, const QString &childTagName) const
 
293
{
 
294
    QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
 
295
    if (nodes.isEmpty() || nodes.size() > 1)
 
296
        return QStringList();
 
297
 
 
298
    QDomNode parentNode = nodes.item(0);
 
299
    QDomElement childElm = parentNode.firstChildElement(childTagName);
 
300
    if (childElm.isNull())
 
301
        return QStringList();
 
302
 
 
303
    QStringList result;
 
304
    while (!childElm.isNull()) {
 
305
        QDomText textNode = childElm.firstChild().toText();
 
306
        if (textNode.isNull())
 
307
            return QStringList();
 
308
 
 
309
        result.append(textNode.data());
 
310
 
 
311
        childElm = childElm.nextSiblingElement(childTagName);
 
312
    }
 
313
 
 
314
    return result;
 
315
}
 
316
 
 
317
void BarDescriptorDocument::setChildStringListValue(const QString &tagName, const QString &childTagName, const QStringList &stringList)
 
318
{
 
319
    QDomNodeList nodes = m_barDocument.elementsByTagName(tagName);
 
320
 
 
321
    if (nodes.size() > 1)
 
322
        return;
 
323
 
 
324
    QDomNode existingNode = nodes.item(0);
 
325
 
 
326
    if (existingNode.isNull()) {
 
327
        QDomElement newParentNode = m_barDocument.createElement(tagName);
 
328
 
 
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);
 
334
        }
 
335
        m_barDocument.documentElement().appendChild(newParentNode);
 
336
    } else {
 
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())
 
346
                    continue;
 
347
 
 
348
                QDomElement toRemove;
 
349
                if (!values.contains(textNode.data()))
 
350
                    toRemove = childElm;
 
351
                else
 
352
                    values.removeAll(textNode.data());
 
353
 
 
354
                childElm = childElm.nextSiblingElement(childTagName);
 
355
 
 
356
                if (!toRemove.isNull())
 
357
                    existingNode.removeChild(toRemove);
 
358
            }
 
359
        }
 
360
 
 
361
        // Add the new elements
 
362
        int newElementCount = 0;
 
363
        foreach (const QString &value, values) {
 
364
            if (value.isEmpty())
 
365
                continue;
 
366
            QDomElement newChildNode = m_barDocument.createElement(childTagName);
 
367
            newChildNode.appendChild(m_barDocument.createTextNode(value));
 
368
            existingNode.appendChild(newChildNode);
 
369
            ++newElementCount;
 
370
        }
 
371
 
 
372
        if (newElementCount == 0)
 
373
            m_barDocument.documentElement().removeChild(existingNode);
 
374
    }
 
375
}
 
376
 
 
377
QStringList BarDescriptorDocument::stringListValue(const QString &tagName) const
 
378
{
 
379
    QStringList result;
 
380
 
 
381
    QDomElement childElm = m_barDocument.documentElement().firstChildElement(tagName);
 
382
    while (!childElm.isNull()) {
 
383
        QDomText textNode = childElm.firstChild().toText();
 
384
        if (textNode.isNull())
 
385
            continue;
 
386
 
 
387
        result.append(textNode.data());
 
388
 
 
389
        childElm = childElm.nextSiblingElement(tagName);
 
390
    }
 
391
 
 
392
    return result;
 
393
}
 
394
 
 
395
void BarDescriptorDocument::setStringListValue(const QString &tagName, const QStringList &stringList)
 
396
{
 
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())
 
406
                continue;
 
407
 
 
408
            QDomElement toRemove;
 
409
            if (!values.contains(textNode.data()))
 
410
                toRemove = childElm;
 
411
            else
 
412
                values.removeAll(textNode.data());
 
413
 
 
414
            childElm = childElm.nextSiblingElement(tagName);
 
415
 
 
416
            if (!toRemove.isNull())
 
417
                m_barDocument.documentElement().removeChild(toRemove);
 
418
        }
 
419
    }
 
420
 
 
421
    // Add the new elements
 
422
    foreach (const QString &value, values) {
 
423
        if (value.isEmpty())
 
424
            continue;
 
425
        QDomElement newChildNode = m_barDocument.createElement(tagName);
 
426
        newChildNode.appendChild(m_barDocument.createTextNode(value));
 
427
        m_barDocument.documentElement().appendChild(newChildNode);
 
428
    }
 
429
}
 
430
 
 
431
BarDescriptorAssetList BarDescriptorDocument::assets() const
 
432
{
 
433
    BarDescriptorAssetList result;
 
434
    QDomNodeList nodes = m_barDocument.elementsByTagName(QLatin1String("asset"));
 
435
    if (nodes.isEmpty())
 
436
        return result;
 
437
 
 
438
    for (int i = 0; i < nodes.size(); ++i) {
 
439
        QDomElement assetElm = nodes.item(i).toElement();
 
440
        if (assetElm.isNull())
 
441
            continue;
 
442
 
 
443
        QDomText textNode = assetElm.firstChild().toText();
 
444
        if (textNode.isNull())
 
445
            continue;
 
446
 
 
447
        QString path = assetElm.attribute(QLatin1String("path"));
 
448
        QString entry = assetElm.attribute(QLatin1String("entry"));
 
449
        QString dest = textNode.data();
 
450
 
 
451
        BarDescriptorAsset asset;
 
452
        asset.source = path;
 
453
        asset.destination = dest;
 
454
        asset.entry = entry == QLatin1String("true");
 
455
        result.append(asset);
 
456
    }
 
457
 
 
458
    return result;
 
459
}
 
460
 
 
461
void BarDescriptorDocument::setAssets(const BarDescriptorAssetList &assets)
 
462
{
 
463
    QDomNodeList nodes = m_barDocument.elementsByTagName(QLatin1String("asset"));
 
464
 
 
465
    BarDescriptorAssetList newAssets = assets;
 
466
    QList<QDomNode> toRemove;
 
467
 
 
468
    for (int i = 0; i < nodes.size(); ++i) {
 
469
        QDomElement assetElm = nodes.at(i).toElement();
 
470
        if (assetElm.isNull())
 
471
            continue;
 
472
 
 
473
        QDomText textNode = assetElm.firstChild().toText();
 
474
        if (textNode.isNull())
 
475
            continue;
 
476
 
 
477
        QString source = assetElm.attribute(QLatin1String("path"));
 
478
        bool found = false;
 
479
        foreach (const BarDescriptorAsset &asset, newAssets) {
 
480
            if (asset.source == source) {
 
481
                found = true;
 
482
                if (asset.entry) {
 
483
                    assetElm.setAttribute(QLatin1String("type"), QLatin1String("Qnx/Elf"));
 
484
                    assetElm.setAttribute(QLatin1String("entry"), QLatin1String("true"));
 
485
                } else {
 
486
                    assetElm.removeAttribute(QLatin1String("type"));
 
487
                    assetElm.removeAttribute(QLatin1String("entry"));
 
488
                }
 
489
                textNode.setData(asset.destination);
 
490
 
 
491
                newAssets.removeAll(asset);
 
492
                break;
 
493
            }
 
494
        }
 
495
 
 
496
        if (!found)
 
497
            toRemove.append(assetElm);
 
498
    }
 
499
 
 
500
    foreach (const QDomNode &node, toRemove)
 
501
        m_barDocument.documentElement().removeChild(node);
 
502
 
 
503
    foreach (const BarDescriptorAsset &asset, newAssets) {
 
504
        QDomElement assetElm = m_barDocument.createElement(QLatin1String("asset"));
 
505
        assetElm.setAttribute(QLatin1String("path"), asset.source);
 
506
        if (asset.entry) {
 
507
            assetElm.setAttribute(QLatin1String("type"), QLatin1String("Qnx/Elf"));
 
508
            assetElm.setAttribute(QLatin1String("entry"), QLatin1String("true"));
 
509
        }
 
510
        assetElm.appendChild(m_barDocument.createTextNode(asset.destination));
 
511
        m_barDocument.documentElement().appendChild(assetElm);
 
512
    }
 
513
}
 
514
 
 
515
QList<Utils::EnvironmentItem> BarDescriptorDocument::environment() const
 
516
{
 
517
    QList<Utils::EnvironmentItem> result;
 
518
 
 
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"));
 
523
 
 
524
        Utils::EnvironmentItem item(var, value);
 
525
        result.append(item);
 
526
 
 
527
        envElm = envElm.nextSiblingElement(QLatin1String("env"));
 
528
    }
 
529
    return result;
 
530
}
 
531
 
 
532
void BarDescriptorDocument::setEnvironment(const QList<Utils::EnvironmentItem> &environment)
 
533
{
 
534
    QDomNodeList envNodes = m_barDocument.elementsByTagName(QLatin1String("env"));
 
535
 
 
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();
 
540
        if (elm.isNull())
 
541
            continue;
 
542
 
 
543
        QString var = elm.attribute(QLatin1String("var"));
 
544
        bool found = false;
 
545
        foreach (const Utils::EnvironmentItem item, newEnvironment) {
 
546
            if (item.name == var) {
 
547
                found = true;
 
548
                elm.setAttribute(QLatin1String("value"), item.value);
 
549
                newEnvironment.removeAll(item);
 
550
                break;
 
551
            }
 
552
        }
 
553
 
 
554
        if (!found)
 
555
            toRemove.append(elm);
 
556
    }
 
557
 
 
558
    foreach (const QDomNode &node, toRemove)
 
559
        m_barDocument.documentElement().removeChild(node);
 
560
 
 
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);
 
566
    }
 
567
}
 
568
 
 
569
void BarDescriptorDocument::emitAllChanged()
 
570
{
 
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));
 
575
    }
 
576
}
 
577
 
 
578
QString BarDescriptorDocument::bannerComment() const
 
579
{
 
580
    QDomNode nd = m_barDocument.firstChild();
 
581
    QDomProcessingInstruction pi = nd.toProcessingInstruction();
 
582
    if (!pi.isNull())
 
583
        nd = pi.nextSibling();
 
584
 
 
585
    return nd.toComment().data();
 
586
}
 
587
 
 
588
void BarDescriptorDocument::setBannerComment(const QString &commentText)
 
589
{
 
590
    QDomNode nd = m_barDocument.firstChild();
 
591
    QDomProcessingInstruction pi = nd.toProcessingInstruction();
 
592
    if (!pi.isNull())
 
593
        nd = pi.nextSibling();
 
594
 
 
595
    bool oldDirty = m_dirty;
 
596
    QDomComment cnd = nd.toComment();
 
597
    if (cnd.isNull()) {
 
598
        if (!commentText.isEmpty()) {
 
599
            cnd = m_barDocument.createComment(commentText);
 
600
            m_barDocument.insertBefore(cnd, nd);
 
601
            m_dirty = true;
 
602
        }
 
603
    } else {
 
604
        if (commentText.isEmpty()) {
 
605
            m_barDocument.removeChild(cnd);
 
606
            m_dirty = true;
 
607
        } else {
 
608
            if (cnd.data() != commentText) {
 
609
                cnd.setData(commentText);
 
610
                m_dirty = true;
 
611
            }
 
612
        }
 
613
    }
 
614
    if (m_dirty != oldDirty)
 
615
        emit Core::IDocument::changed();
 
616
}
 
617
 
 
618
int BarDescriptorDocument::tagForElement(const QDomElement &element)
 
619
{
 
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());
 
624
        if (n > -1)
 
625
            return n;
 
626
        el = el.parentNode().toElement();
 
627
    }
 
628
    return -1;
 
629
}
 
630
 
 
631
bool BarDescriptorDocument::expandPlaceHolder_helper(const QDomElement &el,
 
632
                                                     const QString &placeholderKey,
 
633
                                                     const QString &placeholderText,
 
634
                                                     QSet<BarDescriptorDocument::Tag> &changedTags)
 
635
{
 
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()) {
 
645
                attr.setValue(s);
 
646
                elementChanged = true;
 
647
            }
 
648
        }
 
649
    }
 
650
 
 
651
    bool documentChanged = false;
 
652
    // replace text
 
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()) {
 
659
                txtnd.setData(s);
 
660
                elementChanged = true;
 
661
            }
 
662
        }
 
663
        QDomElement child = nd.toElement();
 
664
        if (!child.isNull()) {
 
665
            bool hit = expandPlaceHolder_helper(child, placeholderKey, placeholderText, changedTags);
 
666
            documentChanged = documentChanged || hit;
 
667
        }
 
668
    }
 
669
    if (elementChanged) {
 
670
        int n = tagForElement(el);
 
671
        if (n >= 0)
 
672
            changedTags << static_cast<Tag>(n);
 
673
    }
 
674
    documentChanged = documentChanged || elementChanged;
 
675
    return documentChanged;
 
676
}
 
677
 
 
678
void BarDescriptorDocument::expandPlaceHolders(const QHash<QString, QString> &placeholdersKeyVals)
 
679
{
 
680
    QSet<Tag> changedTags;
 
681
    QHashIterator<QString, QString> it(placeholdersKeyVals);
 
682
    bool docChanged = false;
 
683
    while (it.hasNext()) {
 
684
        it.next();
 
685
        bool expanded = expandPlaceHolder_helper(m_barDocument.documentElement(),
 
686
                                                 it.key(), it.value(), changedTags);
 
687
        docChanged = docChanged || expanded;
 
688
    }
 
689
    m_dirty = m_dirty || docChanged;
 
690
    foreach (Tag tag, changedTags)
 
691
        emit changed(tag, value(tag));
 
692
    if (docChanged)
 
693
        emit Core::IDocument::changed();
262
694
}