metainfo.cpp 22.4 KB
Newer Older
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "metainfo.h"

#include "abstractproperty.h"
#include "modelnode.h"
#include "invalidmodelnodeexception.h"
#include "invalidargumentexception.h"
#include "propertymetainfo.h"
#include "metainfoparser.h"
#include "iwidgetplugin.h"

#include "model/variantparser.h"
#include "pluginmanager/widgetpluginmanager.h"

#include <QtDebug>
#include <QPair>
#include <QtAlgorithms>
#include <QMetaProperty>
47
#include <QDeclarativeEngine>
48

49
50
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativeanchors_p.h>
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

enum {
    debug = false
};

namespace QmlDesigner {
namespace Internal {

class MetaInfoPrivate
{
    Q_DISABLE_COPY(MetaInfoPrivate)
public:
    typedef QSharedPointer<MetaInfoPrivate> Pointer;
    typedef QWeakPointer<MetaInfoPrivate> WeakPointer;


    MetaInfoPrivate(MetaInfo *q);
    void clear();

    void initialize();
71
    void loadPlugins(QDeclarativeEngine *engine);
72
73
74
    void parseQmlTypes();
    void parseNonQmlTypes();
    void parseValueTypes();
75
    void parseNonQmlClassRecursively(const QMetaObject *qMetaObject);
76
77
78
    void parseProperties(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const;
    void parseClassInfo(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const;

79
80
    QList<QDeclarativeType*> qmlTypes();
    void typeInfo(const QMetaObject *qMetaObject, QString *typeName, int *majorVersion = 0, int *minorVersion = 0) const;
81
82
83

    void parseXmlFiles();

84
    QMultiHash<QString, NodeMetaInfo> m_nodeMetaInfoHash;
85
86
    QHash<QString, EnumeratorMetaInfo> m_enumeratorMetaInfoHash;
    QHash<QString, QString> m_QtTypesToQmlTypes;
87
    QScopedPointer<ItemLibraryInfo> m_itemLibraryInfo;
88
89
90
91
92
93

    MetaInfo *m_q;
    bool m_isInitialized;
};

MetaInfoPrivate::MetaInfoPrivate(MetaInfo *q) :
94
        m_itemLibraryInfo(new ItemLibraryInfo()),
95
96
97
        m_q(q),
        m_isInitialized(false)
{
98
    if (!m_q->isGlobal())
99
        m_itemLibraryInfo->setBaseInfo(MetaInfo::global().itemLibraryInfo());
100
101
102
103
104
105
}

void MetaInfoPrivate::clear()
{
    m_nodeMetaInfoHash.clear();
    m_enumeratorMetaInfoHash.clear();
106
    m_itemLibraryInfo->clearEntries();
107
108
109
110
111
    m_isInitialized = false;
}

void MetaInfoPrivate::initialize()
{
Kai Koehne's avatar
Kai Koehne committed
112
113
    // make sure QmlGraphicsItemsModule gets initialized, that is
    // QmlGraphicsItemsModule::defineModule called
114
    QDeclarativeEngine engine;
Kai Koehne's avatar
Kai Koehne committed
115
116
    Q_UNUSED(engine);

117
    loadPlugins(&engine);
118
119
    parseQmlTypes();
    parseNonQmlTypes();
120
    parseValueTypes();
121
    parseXmlFiles();
122
123
124
125

    m_isInitialized = true;
}

126
127
128
void MetaInfoPrivate::loadPlugins(QDeclarativeEngine *engine)
{
    // hack to load plugins
129
    QDeclarativeComponent pluginComponent(engine, 0);
130
131

    QStringList pluginList;
132
    pluginList += "import Qt 4.7";
133
    pluginList += "import QtWebKit 1.0";
134
135
136
137
138

    // load maybe useful plugins
    pluginList += "import Qt.labs.folderlistmodel 1.0";
    pluginList += "import Qt.labs.gestures 1.0";
    pluginList += "import Qt.labs.particles 1.0";
139
140
141
    pluginList += "import Qt.labs.components 1.0";
    pluginList += "import com.meego.themebridge 1.0";
    pluginList += "import com.meego 1.0";
142

143
144
    QString componentString = QString("%1\n Item {}\n").arg(pluginList.join("\n"));

145

146
147
    pluginComponent.setData(componentString.toLatin1(), QUrl());
}
148

149
150
151
152
153
154
155
156
QString static inline stripPrefix(const QString &typeName)
{
    QStringList list = typeName.split('/');
    if (list.count() == 2)
        return list.last();
    return typeName;
}

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
void MetaInfoPrivate::parseProperties(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const
{
    Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject");
    Q_ASSERT_X(nodeMetaInfo.isValid(), Q_FUNC_INFO, "invalid NodeMetaInfo");

    for (int i = qMetaObject->propertyOffset(); i < qMetaObject->propertyCount(); ++i) {
        QMetaProperty qProperty = qMetaObject->property(i);

        PropertyMetaInfo propertyInfo;

        propertyInfo.setName(QLatin1String(qProperty.name()));

        QString typeName(qProperty.typeName());
        QString noStar = typeName;
        bool star = false;
        while (noStar.contains('*')) {//strip star
            noStar.chop(1);
            star = true;
        }
        if (m_QtTypesToQmlTypes.contains(noStar)) {
            typeName = star ? m_QtTypesToQmlTypes.value(noStar) + '*' : m_QtTypesToQmlTypes.value(noStar);
            //### versions
        }
        propertyInfo.setType(typeName);
        propertyInfo.setValid(true);
        propertyInfo.setReadable(qProperty.isReadable());
        propertyInfo.setWritable(qProperty.isWritable());
        propertyInfo.setResettable(qProperty.isResettable());
        propertyInfo.setEnumType(qProperty.isEnumType());
        propertyInfo.setFlagType(qProperty.isFlagType());

        if (propertyInfo.isEnumType()) {
            QMetaEnum qEnumerator = qProperty.enumerator();
190
191
            EnumeratorMetaInfo enumerator = m_q->addEnumerator(qEnumerator.scope(), qEnumerator.name());

192
193
            enumerator.setValid(qEnumerator.isValid());
            enumerator.setIsFlagType(qEnumerator.isFlag());
194
195
196
197
198
            QString scope = qEnumerator.scope();
            if (m_QtTypesToQmlTypes.contains(scope))
                scope = stripPrefix(m_QtTypesToQmlTypes.value(scope));

            enumerator.setScope(scope);
199
200
201
202
203
204
205
            enumerator.setName(qEnumerator.name());
            for (int i = 0 ;i < qEnumerator.keyCount(); i++)
            {
                enumerator.addElement(qEnumerator.valueToKey(i), i);
            }

            propertyInfo.setEnumerator(enumerator);
206
            
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
        }

        nodeMetaInfo.addProperty(propertyInfo);
    }
}

void MetaInfoPrivate::parseClassInfo(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const
{
    Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject");
    Q_ASSERT_X(nodeMetaInfo.isValid(), Q_FUNC_INFO, "invalid NodeMetaInfo");
    for (int index = qMetaObject->classInfoCount() - 1 ; index >= 0 ; --index) {
        QMetaClassInfo classInfo = qMetaObject->classInfo(index);
        if (QLatin1String(classInfo.name()) == QLatin1String("DefaultProperty")) {
            nodeMetaInfo.setDefaultProperty(classInfo.value());
            return;
        }
    }
}

226
void MetaInfoPrivate::parseNonQmlClassRecursively(const QMetaObject *qMetaObject)
227
228
{
    Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject");
229

230
231
232
233
234
235
    QString typeName;
    int majorVersion = -1;
    int minorVersion = -1;
    typeInfo(qMetaObject, &typeName, &majorVersion, &minorVersion);

    if (typeName.isEmpty()) {
236
237
238
239
        qWarning() << "Meta type system: Registered class has no name.";
        return;
    }

240
241
242
243
244
245
    NodeMetaInfo existingInfo = m_q->nodeMetaInfo(typeName, majorVersion, minorVersion);
    if (existingInfo.isValid()
        && existingInfo.majorVersion() == majorVersion
        && existingInfo.minorVersion() == minorVersion) {
        return;
    }
246

247
248
249
250
    NodeMetaInfo nodeMetaInfo(*m_q);
    nodeMetaInfo.setType(typeName, majorVersion, minorVersion);
    parseProperties(nodeMetaInfo, qMetaObject);
    parseClassInfo(nodeMetaInfo, qMetaObject);
251

252
253
254
    QString superTypeName;
    int superTypeMajorVersion = -1;
    int superTypeMinorVersion = -1;
255

256
257
258
    if (qMetaObject->superClass()) {
        typeInfo(qMetaObject->superClass(), &superTypeName, &superTypeMajorVersion, &superTypeMinorVersion);
        nodeMetaInfo.setSuperClass(superTypeName, superTypeMajorVersion, superTypeMinorVersion);
259
    }
260
261
262
263
264
265
266
267
    if (debug)
        qDebug() << "adding non qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion()
                 << ", parent type" << superTypeName << superTypeMajorVersion << superTypeMinorVersion;

    m_q->addNodeInfo(nodeMetaInfo);

    if (const QMetaObject *superClass = qMetaObject->superClass())
        parseNonQmlClassRecursively(superClass);
268
269
}

270
271
272
273
274
275
276
277
278
279
QList<QDeclarativeType*> MetaInfoPrivate::qmlTypes()
{
    QList<QDeclarativeType*> list;
    foreach (QDeclarativeType *type, QDeclarativeMetaType::qmlTypes()) {
        if (!type->qmlTypeName().startsWith("Bauhaus/")
            && !type->qmlTypeName().startsWith("QmlProject/"))
            list += type;
    }
    return list;
}
280

281
282
283

static inline bool isDepricatedQtType(const QString &typeName)
{
284
    if (typeName.length() < 8)
285
286
        return false;

287
    return typeName.contains("QtQuick/");
288
289
}

290
void MetaInfoPrivate::typeInfo(const QMetaObject *qMetaObject, QString *typeName, int *majorVersion, int *minorVersion) const
291
{
292
293
    Q_ASSERT(typeName);

294
    if (!qMetaObject)
295
296
297
298
299
300
301
302
303
304
305
306
        return;

    *typeName = qMetaObject->className();
    int majVersion = -1;
    int minVersion = -1;
    QDeclarativeType *qmlType = QDeclarativeMetaType::qmlType(qMetaObject);
    if (qmlType) {
        if (!qmlType->qmlTypeName().isEmpty()) {
            *typeName = qmlType->qmlTypeName();
            majVersion = qmlType->majorVersion();
            minVersion = qmlType->minorVersion();
        }
307
308
        if (isDepricatedQtType(qmlType->qmlTypeName())) { //### todo there has to be an alternative
            QString properTypeName = qmlType->qmlTypeName();
309
            properTypeName.replace("QtQuick/", "Qt/");
310
311
312
313
            *typeName = properTypeName;
            majVersion = 1;
            minVersion = 0;
        }
314
    }
315
316
317
318
    if (majorVersion)
        *majorVersion = majVersion;
    if (minorVersion)
        *minorVersion = minVersion;
319
320
321
322
323
324
325
326
327
328
329
330
331
}

void MetaInfoPrivate::parseValueTypes()
{
    QStringList valueTypes;
    //there is no global list of all supported value types
    valueTypes << "QFont"
               << "QPoint"
               << "QPointF"
               << "QRect"
               << "QRectF"
               << "QSize"
               << "QSizeF"
332
333
               << "QVector3D"
               << "QEasingCurve";
334
335
336

    foreach (const QString &type, valueTypes) {
        NodeMetaInfo nodeMetaInfo(*m_q);
337
        nodeMetaInfo.setType(type, -1, -1);
338
339
340
341
342
343
344
345
346
        foreach (const QString &propertyName, VariantParser::create(type).properties()) {
            PropertyMetaInfo propertyInfo;
            propertyInfo.setName(propertyName);
            propertyInfo.setType("real");
            if (type == ("QFont")) {
                if (propertyName == "bold")
                    propertyInfo.setType("bool");
                else if (propertyName == "italic")
                    propertyInfo.setType("bool");
347
348
349
350
                else if (propertyName == "underline")
                    propertyInfo.setType("bool");
                else if (propertyName == "strikeout")
                    propertyInfo.setType("bool");
351
352
353
354
355
356
357
358
359
360
                else if (propertyName == "family")
                    propertyInfo.setType("string");
                else if (propertyName == "pixelSize")
                    propertyInfo.setType("int");
            } else if (type == ("QPoint")) {
                propertyInfo.setType("int");
            } else if (type == ("QSize")) {
                propertyInfo.setType("int");
            } else if (type == ("QRect")) {
                propertyInfo.setType("int");
361
362
363
364
365
366
            } else if (type == ("QEasingCurve")) {
                if (propertyName == "type") {
                    propertyInfo.setEnumType("true");
                    propertyInfo.setType("QEasingCurve::Type");
                    propertyInfo.setEnumerator(m_q->enumerator("QEasingCurve::Type"));
                }
367
368
369
370
371
372
373
374
            }
            propertyInfo.setValid(true);
            propertyInfo.setReadable(true);
            propertyInfo.setWritable(true);
            nodeMetaInfo.addProperty(propertyInfo);
        }
        if (debug)
            qDebug() << "adding value type" << nodeMetaInfo.typeName();
375
        m_q->addNodeInfo(nodeMetaInfo);
376
377
378
379
380
    }
}

void MetaInfoPrivate::parseQmlTypes()
{
381
    foreach (QDeclarativeType *qmlType, qmlTypes()) {
382
383
        const QString qtTypeName(qmlType->typeName());
        const QString qmlTypeName(qmlType->qmlTypeName());
384
385
386
        
        if (!isDepricatedQtType(qmlType->qmlTypeName()))
            m_QtTypesToQmlTypes.insert(qtTypeName, qmlTypeName);
387
    }
388
    foreach (QDeclarativeType *qmlType, qmlTypes()) {
389
390
391
392
393
394
        const QMetaObject *qMetaObject = qmlType->metaObject();

        // parseQmlTypes is called iteratively e.g. when plugins are loaded
        if (m_q->hasNodeMetaInfo(qmlType->qmlTypeName(), qmlType->majorVersion(), qmlType->minorVersion()))
            continue;

Tobias Hunger's avatar
Tobias Hunger committed
395
        // we ignore the deprecated Qt/ namespace
396
397
398
        if (isDepricatedQtType(qmlType->qmlTypeName()))
            continue;

399
        NodeMetaInfo nodeMetaInfo(*m_q);
400
        nodeMetaInfo.setType(qmlType->qmlTypeName(), qmlType->majorVersion(), qmlType->minorVersion());
401
402
403
404
405
406
407

        parseProperties(nodeMetaInfo, qMetaObject);
        if (qmlType->baseMetaObject() != qMetaObject) {
            // type is declared with Q_DECLARE_EXTENDED_TYPE
            parseProperties(nodeMetaInfo, qmlType->baseMetaObject());
        }

408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
        parseClassInfo(nodeMetaInfo, qMetaObject);

        QString superTypeName;
        int superTypeMajorVersion = -1;
        int superTypeMinorVersion = -1;
        if (const QMetaObject *superClassObject = qmlType->baseMetaObject()->superClass())
            typeInfo(superClassObject, &superTypeName, &superTypeMajorVersion, &superTypeMinorVersion);

        if (!superTypeName.isEmpty())
            nodeMetaInfo.setSuperClass(superTypeName, superTypeMajorVersion, superTypeMinorVersion);

        if (debug) {
            qDebug() << "adding qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion()
                     << ", super class" << superTypeName << superTypeMajorVersion << superTypeMinorVersion;
        }
423
424

        m_q->addNodeInfo(nodeMetaInfo);
425
426
427
428
429
    }
}

void MetaInfoPrivate::parseNonQmlTypes()
{
430
431
432
433
434
435
    foreach (QDeclarativeType *qmlType, qmlTypes()) {
        if (qmlType->qmlTypeName().startsWith("Bauhaus/")
             || qmlType->qmlTypeName().startsWith("QmlProject/"))
            continue;
        if (qmlType->metaObject()->superClass())
            parseNonQmlClassRecursively(qmlType->metaObject()->superClass());
436
437
    }

438
    parseNonQmlClassRecursively(&QDeclarativeAnchors::staticMetaObject);
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
}


void MetaInfoPrivate::parseXmlFiles()
{
    Internal::WidgetPluginManager pluginManager;
    foreach (const QString &pluginDir, m_q->s_pluginDirs)
        pluginManager.addPath(pluginDir);
    QList<IWidgetPlugin *> widgetPluginList = pluginManager.instances();
    foreach (IWidgetPlugin *plugin, widgetPluginList) {
        parseQmlTypes();
        Internal::MetaInfoParser parser(*m_q);
        parser.parseFile(plugin->metaInfo());
    }
}

} // namespace Internal

using QmlDesigner::Internal::MetaInfoPrivate;

MetaInfo MetaInfo::s_global;
QStringList MetaInfo::s_pluginDirs;


/*!
\class QmlDesigner::MetaInfo
\ingroup CoreModel
\brief The MetaInfo class provides meta information about qml types and properties.

The MetaInfo, NodeMetaInfo, PropertyMetaInfo and EnumeratorMetaInfo
classes provide information about the (static and dynamic) qml types available in
a specific model. Just like their Model, ModelNode and AbstractProperty counterparts,
objects of these classes are handles - that means, they are implicitly shared, and
should be created on the stack.

The MetaInfo object should always be accessed via the model (see Model::metaInfo()).
Otherwise types specific to a model (like sub components) might
be missed.

\see Model::metaInfo(), QmlDesigner::NodeMetaInfo, QmlDesigner::PropertyMetaInfo, QmlDesigner::EnumeratorMetaInfo
*/

/*!
  \brief Constructs a copy of the given meta info.
  */
MetaInfo::MetaInfo(const MetaInfo &metaInfo) :
        m_p(metaInfo.m_p)
{
}

/*!
  \brief Creates a meta information object with just the qml types registered statically.
  You almost always want to use Model::metaInfo() instead!

  You almost certainly want to access the meta information for the model.

  \see Model::metaInfo()
  */
MetaInfo::MetaInfo() :
        m_p(new MetaInfoPrivate(this))
{
}

MetaInfo::~MetaInfo()
{
}

/*!
  \brief Assigns other to this meta information and returns a reference to this meta information.
  */
MetaInfo& MetaInfo::operator=(const MetaInfo &other)
{
    m_p = other.m_p;
    return *this;
}

/*!
  \brief Returns whether a type with the given name is registered in the meta system.
  */
518
bool MetaInfo::hasNodeMetaInfo(const QString &typeName, int majorVersion, int minorVersion) const
519
{
520
    foreach (const NodeMetaInfo &info, m_p->m_nodeMetaInfoHash.values(typeName)) {
521
        if (info.availableInVersion(majorVersion, minorVersion)) { {
522
523
            return true;
        }
524
        }
525
    }
526
527
    if (!isGlobal())
        return global().hasNodeMetaInfo(typeName);
528

529
530
531
532
533
534
    return false;
}

/*!
  \brief Returns meta information for a qml type. An invalid NodeMetaInfo object if the type is unknown.
  */
535
NodeMetaInfo MetaInfo::nodeMetaInfo(const QString &typeName, int majorVersion, int minorVersion) const
536
{
537
    NodeMetaInfo returnInfo;
538
539
    foreach (const NodeMetaInfo &info, m_p->m_nodeMetaInfoHash.values(typeName)) {
        if (info.availableInVersion(majorVersion, minorVersion)) {
540
541
542
543
544
            if (!returnInfo.isValid()
                || returnInfo.majorVersion() < info.majorVersion()
                || (returnInfo.majorVersion() == info.minorVersion()
                    && returnInfo.minorVersion() < info.minorVersion()))
            returnInfo = info;
545
546
        }
    }
547
548
    if (!returnInfo.isValid()
        && !isGlobal())
549
550
        return global().nodeMetaInfo(typeName);

551
    return returnInfo;
552
553
}

554
555
556
557
QString MetaInfo::fromQtTypes(const QString &type) const
{
    if (m_p->m_QtTypesToQmlTypes.contains(type))
        return m_p->m_QtTypesToQmlTypes.value(type);
558
559
    if (!isGlobal())
        return global().fromQtTypes(type);
560
561
562
    return type;
}

563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
/*!
  \brief Returns whether an enumerator is registered in the meta type system.
  */
bool MetaInfo::hasEnumerator(const QString &enumeratorName) const
{
    return m_p->m_enumeratorMetaInfoHash.contains(enumeratorName)
            || (!isGlobal() ? global().hasEnumerator(enumeratorName) : false);
}

/*!
  \brief Returns meta information about an enumerator. An invalid EnumeratorMetaInfo object if the enumerator is not known.
  */
EnumeratorMetaInfo MetaInfo::enumerator(const QString &enumeratorName) const
{
    if (m_p->m_enumeratorMetaInfoHash.contains(enumeratorName))
        return m_p->m_enumeratorMetaInfoHash.value(enumeratorName);
    if (!isGlobal())
        return global().enumerator(enumeratorName);
    return EnumeratorMetaInfo();
}

584
ItemLibraryInfo *MetaInfo::itemLibraryInfo() const
585
{
586
    return m_p->m_itemLibraryInfo.data();
587
588
}

589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
/*!
  \brief Access to the global meta information object.
  You almost always want to use Model::metaInfo() instead.

  Internally all meta information objects share this "global" object
  where static qml type information is stored.
  */
MetaInfo MetaInfo::global()
{
    if (!s_global.m_p->m_isInitialized) {
        s_global.m_p = QSharedPointer<MetaInfoPrivate>(new MetaInfoPrivate(&s_global));
        s_global.m_p->initialize();
    }
    return s_global;
}

/*!
  \brief Clears the global meta information object.

  This method should be called once on application shutdown to free static data structures.
  */
void MetaInfo::clearGlobal()
{
612
613
614
    if (s_global.m_p->m_isInitialized) {
        s_global.m_p->clear();
    }
615
616
617
618
619
620
621
}

void MetaInfo::setPluginPaths(const QStringList &paths)
{
    s_pluginDirs = paths;
}

622
void MetaInfo::addNodeInfo(NodeMetaInfo &nodeInfo)
623
624
625
626
627
{
    if (nodeInfo.typeName().isEmpty() || nodeInfo.metaInfo() != *this)
        throw new InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, QLatin1String("nodeInfo"));


628
    m_p->m_nodeMetaInfoHash.insertMulti(nodeInfo.typeName(), nodeInfo);
629
630
631
632
}

void MetaInfo::removeNodeInfo(NodeMetaInfo &info)
{
633
634
635
636
    if (!info.isValid()) {
        qWarning() << "NodeMetaInfo is invalid";
        return;
    }
637

638
639
    if (m_p->m_nodeMetaInfoHash.contains(info.typeName())
        && m_p->m_nodeMetaInfoHash.remove(info.typeName(), info)) {
640

641
        foreach (const ItemLibraryEntry &entry,
642
643
                 m_p->m_itemLibraryInfo->entriesForType(info.typeName(), info.majorVersion(), info.minorVersion())) {
            m_p->m_itemLibraryInfo->removeEntry(entry.name());
644
        }
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696

    } else if (!isGlobal()) {
        global().removeNodeInfo(info);
    } else {
        Q_ASSERT_X(0, Q_FUNC_INFO, "Node meta info not in db");
    }

    info.setInvalid();
}

EnumeratorMetaInfo MetaInfo::addEnumerator(const QString &enumeratorScope, const QString &enumeratorName)
{
    Q_ASSERT(!enumeratorName.isEmpty());

    EnumeratorMetaInfo enumeratorMetaInfo;
    enumeratorMetaInfo.setName(enumeratorName);
    enumeratorMetaInfo.setScope(enumeratorScope);
    enumeratorMetaInfo.setIsFlagType(false);
    enumeratorMetaInfo.setValid(true);

    m_p->m_enumeratorMetaInfoHash.insert(enumeratorMetaInfo.scopeAndName(), enumeratorMetaInfo);

    return enumeratorMetaInfo;
}

EnumeratorMetaInfo MetaInfo::addFlag(const QString &enumeratorScope, const QString &enumeratorName)
{
    Q_ASSERT(!enumeratorName.isEmpty());

    EnumeratorMetaInfo enumeratorMetaInfo;
    enumeratorMetaInfo.setName(enumeratorName);
    enumeratorMetaInfo.setScope(enumeratorScope);
    enumeratorMetaInfo.setIsFlagType(true);
    m_p->m_enumeratorMetaInfoHash.insert(enumeratorMetaInfo.scopeAndName(), enumeratorMetaInfo);

    return enumeratorMetaInfo;
}

bool MetaInfo::isGlobal() const
{
    return (this->m_p == s_global.m_p);
}

bool operator==(const MetaInfo &first, const MetaInfo &second)
{
    return first.m_p == second.m_p;
}

bool operator!=(const MetaInfo &first, const MetaInfo &second)
{
    return !(first == second);
}
697

698
} //namespace QmlDesigner