summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@nokia.com>2009-12-07 16:57:31 +0100
committerErik Verbruggen <erik.verbruggen@nokia.com>2009-12-08 11:52:43 +0100
commit96e5cae4c83adfd55dad8f5f76cbb97660d91040 (patch)
treeb103047eb319196f5eaa321d679cf8023c068cd8 /src
parent5a0b7f8ec8376882bf2c1dc5a701fd813d8d827d (diff)
downloadqt-creator-96e5cae4c83adfd55dad8f5f76cbb97660d91040.tar.gz
Added metainfo classes from Bauhaus for use in the QML editor.
Diffstat (limited to 'src')
-rw-r--r--src/plugins/qmleditor/qmlcodecompletion.cpp12
-rw-r--r--src/plugins/qmleditor/qmlcodecompletion.h4
-rw-r--r--src/plugins/qmleditor/qmleditor.cpp8
-rw-r--r--src/plugins/qmleditor/qmleditor.h7
-rw-r--r--src/plugins/qmleditor/qmleditorplugin.cpp4
-rw-r--r--src/plugins/qmleditor/qmlexpressionundercursor.cpp5
-rw-r--r--src/plugins/qmleditor/qmlexpressionundercursor.h4
-rw-r--r--src/plugins/qmleditor/qmlhoverhandler.cpp5
-rw-r--r--src/plugins/qmleditor/qmllookupcontext.cpp138
-rw-r--r--src/plugins/qmleditor/qmllookupcontext.h27
-rw-r--r--src/plugins/qmleditor/qmlmodelmanagerinterface.h1
-rw-r--r--src/plugins/qmleditor/qmlresolveexpression.cpp4
-rw-r--r--src/plugins/qmleditor/qmlresolveexpression.h8
-rw-r--r--src/shared/qml/metatype/QmlMetaTypeBackend.cpp14
-rw-r--r--src/shared/qml/metatype/QmlMetaTypeBackend.h33
-rw-r--r--src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.cpp232
-rw-r--r--src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.h47
-rw-r--r--src/shared/qml/metatype/exception.cpp163
-rw-r--r--src/shared/qml/metatype/exception.h42
-rw-r--r--src/shared/qml/metatype/invalidmetainfoexception.cpp35
-rw-r--r--src/shared/qml/metatype/invalidmetainfoexception.h21
-rw-r--r--src/shared/qml/metatype/metainfo.cpp461
-rw-r--r--src/shared/qml/metatype/metainfo.h83
-rw-r--r--src/shared/qml/metatype/nodemetainfo.cpp695
-rw-r--r--src/shared/qml/metatype/nodemetainfo.h103
-rw-r--r--src/shared/qml/metatype/propertymetainfo.cpp378
-rw-r--r--src/shared/qml/metatype/propertymetainfo.h84
-rw-r--r--src/shared/qml/metatype/qmltypesystem.cpp42
-rw-r--r--src/shared/qml/metatype/qmltypesystem.h34
-rw-r--r--src/shared/qml/qml.pri30
-rw-r--r--src/shared/qml/qmldocument.cpp3
-rw-r--r--src/shared/qml/qmldocument.h8
-rw-r--r--src/shared/qml/qmlidcollector.cpp10
-rw-r--r--src/shared/qml/qmlidcollector.h14
-rw-r--r--src/shared/qml/qmlpackageinfo.cpp10
-rw-r--r--src/shared/qml/qmlpackageinfo.h32
-rw-r--r--src/shared/qml/qmlsymbol.cpp11
-rw-r--r--src/shared/qml/qmlsymbol.h51
38 files changed, 2687 insertions, 176 deletions
diff --git a/src/plugins/qmleditor/qmlcodecompletion.cpp b/src/plugins/qmleditor/qmlcodecompletion.cpp
index 6ee377ccb0..49bac43895 100644
--- a/src/plugins/qmleditor/qmlcodecompletion.cpp
+++ b/src/plugins/qmleditor/qmlcodecompletion.cpp
@@ -42,14 +42,16 @@
using namespace QmlEditor;
using namespace QmlEditor::Internal;
-QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent)
+QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent)
: TextEditor::ICompletionCollector(parent),
m_modelManager(modelManager),
m_editor(0),
m_startPosition(0),
- m_caseSensitivity(Qt::CaseSensitive)
+ m_caseSensitivity(Qt::CaseSensitive),
+ m_typeSystem(typeSystem)
{
Q_ASSERT(modelManager);
+ Q_ASSERT(typeSystem);
}
QmlCodeCompletion::~QmlCodeCompletion()
@@ -119,13 +121,13 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
cursor.setPosition(pos);
expressionUnderCursor(cursor, qmlDocument);
- QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot());
+ QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot(), m_typeSystem);
QmlResolveExpression resolver(context);
// qDebug()<<"*** expression under cursor:"<<expressionUnderCursor.expressionNode();
- QList<QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());
+ QList<Qml::QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());
// qDebug()<<"***"<<symbols.size()<<"visible symbols";
- foreach (QmlSymbol *symbol, symbols) {
+ foreach (Qml::QmlSymbol *symbol, symbols) {
QString word;
if (symbol->isIdSymbol()) {
diff --git a/src/plugins/qmleditor/qmlcodecompletion.h b/src/plugins/qmleditor/qmlcodecompletion.h
index 8ed9aaf05a..0b8c8edfa8 100644
--- a/src/plugins/qmleditor/qmlcodecompletion.h
+++ b/src/plugins/qmleditor/qmlcodecompletion.h
@@ -1,6 +1,7 @@
#ifndef QMLCODECOMPLETION_H
#define QMLCODECOMPLETION_H
+#include <qml/metatype/qmltypesystem.h>
#include <texteditor/icompletioncollector.h>
namespace TextEditor {
@@ -18,7 +19,7 @@ class QmlCodeCompletion: public TextEditor::ICompletionCollector
Q_OBJECT
public:
- QmlCodeCompletion(QmlModelManagerInterface *modelManager, QObject *parent = 0);
+ QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent = 0);
virtual ~QmlCodeCompletion();
Qt::CaseSensitivity caseSensitivity() const;
@@ -38,6 +39,7 @@ private:
int m_startPosition;
QList<TextEditor::CompletionItem> m_completions;
Qt::CaseSensitivity m_caseSensitivity;
+ Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
diff --git a/src/plugins/qmleditor/qmleditor.cpp b/src/plugins/qmleditor/qmleditor.cpp
index ab312bc258..6cc759496a 100644
--- a/src/plugins/qmleditor/qmleditor.cpp
+++ b/src/plugins/qmleditor/qmleditor.cpp
@@ -37,6 +37,7 @@
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
+#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsastvisitor_p.h>
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
@@ -68,6 +69,7 @@ enum {
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 250
};
+using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
using namespace SharedTools;
@@ -378,7 +380,8 @@ ScriptEditorEditable::ScriptEditorEditable(ScriptEditor *editor)
ScriptEditor::ScriptEditor(QWidget *parent) :
TextEditor::BaseTextEditor(parent),
m_methodCombo(0),
- m_modelManager(0)
+ m_modelManager(0),
+ m_typeSystem(0)
{
setParenthesesMatchingEnabled(true);
setMarksVisible(true);
@@ -397,6 +400,7 @@ ScriptEditor::ScriptEditor(QWidget *parent) :
baseTextDocument()->setSyntaxHighlighter(new QmlHighlighter);
m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>();
+ m_typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
if (m_modelManager) {
connect(m_modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)),
@@ -768,7 +772,7 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
QmlExpressionUnderCursor expressionUnderCursor;
expressionUnderCursor(expressionCursor, doc);
- QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot);
+ QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot, m_typeSystem);
QmlResolveExpression resolver(context);
QmlSymbol *symbol = resolver.typeOf(expressionUnderCursor.expressionNode());
diff --git a/src/plugins/qmleditor/qmleditor.h b/src/plugins/qmleditor/qmleditor.h
index 90af86fe9c..6ad1c2c32c 100644
--- a/src/plugins/qmleditor/qmleditor.h
+++ b/src/plugins/qmleditor/qmleditor.h
@@ -43,6 +43,12 @@ namespace Core {
class ICore;
}
+namespace Qml {
+ namespace MetaType {
+ class QmlTypeSystem;
+ }
+}
+
namespace QmlEditor {
class QmlModelManagerInterface;
@@ -146,6 +152,7 @@ private:
QList<QmlJS::DiagnosticMessage> m_diagnosticMessages;
QmlDocument::Ptr m_document;
QmlModelManagerInterface *m_modelManager;
+ Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
} // namespace Internal
diff --git a/src/plugins/qmleditor/qmleditorplugin.cpp b/src/plugins/qmleditor/qmleditorplugin.cpp
index 8e1441f7c5..3e1d032ee7 100644
--- a/src/plugins/qmleditor/qmleditorplugin.cpp
+++ b/src/plugins/qmleditor/qmleditorplugin.cpp
@@ -94,6 +94,8 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
m_modelManager = new QmlModelManager(this);
addAutoReleasedObject(m_modelManager);
+ Qml::MetaType::QmlTypeSystem *typeSystem = new Qml::MetaType::QmlTypeSystem;
+ addAutoReleasedObject(typeSystem);
QList<int> context;
context<< core->uniqueIDManager()->uniqueIdentifier(QmlEditor::Constants::C_QMLEDITOR);
@@ -122,7 +124,7 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION);
contextMenu->addAction(cmd);
- m_completion = new QmlCodeCompletion(m_modelManager);
+ m_completion = new QmlCodeCompletion(m_modelManager, typeSystem);
addAutoReleasedObject(m_completion);
addAutoReleasedObject(new QmlHoverHandler());
diff --git a/src/plugins/qmleditor/qmlexpressionundercursor.cpp b/src/plugins/qmleditor/qmlexpressionundercursor.cpp
index 5fd7c5031f..b664d5d410 100644
--- a/src/plugins/qmleditor/qmlexpressionundercursor.cpp
+++ b/src/plugins/qmleditor/qmlexpressionundercursor.cpp
@@ -9,6 +9,7 @@
#include <QDebug>
+using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
@@ -118,7 +119,7 @@ namespace QmlEditor {
virtual bool visit(UiObjectBinding *ast)
{
- if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) {
+ if (ast->initializer && ast->initializer->lbraceToken.offset < _pos && _pos <= ast->initializer->rbraceToken.end()) {
push(ast);
Node::accept(ast->initializer, this);
}
@@ -128,7 +129,7 @@ namespace QmlEditor {
virtual bool visit(UiObjectDefinition *ast)
{
- if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) {
+ if (ast->initializer && ast->initializer->lbraceToken.offset < _pos && _pos <= ast->initializer->rbraceToken.end()) {
push(ast);
Node::accept(ast->initializer, this);
}
diff --git a/src/plugins/qmleditor/qmlexpressionundercursor.h b/src/plugins/qmleditor/qmlexpressionundercursor.h
index 9468190580..29c9b4b1d7 100644
--- a/src/plugins/qmleditor/qmlexpressionundercursor.h
+++ b/src/plugins/qmleditor/qmlexpressionundercursor.h
@@ -26,7 +26,7 @@ public:
void operator()(const QTextCursor &cursor, const QmlDocument::Ptr &doc);
- QStack<QmlSymbol *> expressionScopes() const
+ QStack<Qml::QmlSymbol *> expressionScopes() const
{ return _expressionScopes; }
QmlJS::AST::Node *expressionNode() const
@@ -45,7 +45,7 @@ private:
QmlJS::AST::UiObjectMember *tryBinding(const QString &text);
private:
- QStack<QmlSymbol *> _expressionScopes;
+ QStack<Qml::QmlSymbol *> _expressionScopes;
QmlJS::AST::Node *_expressionNode;
int _expressionOffset;
int _expressionLength;
diff --git a/src/plugins/qmleditor/qmlhoverhandler.cpp b/src/plugins/qmleditor/qmlhoverhandler.cpp
index a23e660766..4e04553973 100644
--- a/src/plugins/qmleditor/qmlhoverhandler.cpp
+++ b/src/plugins/qmleditor/qmlhoverhandler.cpp
@@ -52,6 +52,7 @@
#include <QtHelp/QHelpEngineCore>
using namespace Core;
+using namespace Qml;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
@@ -186,7 +187,9 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
QmlExpressionUnderCursor expressionUnderCursor;
expressionUnderCursor(tc, doc);
- QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot());
+ Qml::MetaType::QmlTypeSystem *typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
+
+ QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot(), typeSystem);
QmlResolveExpression resolver(context);
QmlSymbol *resolvedSymbol = resolver.typeOf(expressionUnderCursor.expressionNode());
diff --git a/src/plugins/qmleditor/qmllookupcontext.cpp b/src/plugins/qmleditor/qmllookupcontext.cpp
index d5869c0bfc..e4fc033656 100644
--- a/src/plugins/qmleditor/qmllookupcontext.cpp
+++ b/src/plugins/qmleditor/qmllookupcontext.cpp
@@ -2,11 +2,14 @@
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
+#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
#include <QDebug>
+using namespace Qml;
+using namespace Qml::MetaType;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace QmlJS;
@@ -14,11 +17,14 @@ using namespace QmlJS::AST;
QmlLookupContext::QmlLookupContext(const QStack<QmlSymbol *> &scopes,
const QmlDocument::Ptr &doc,
- const Snapshot &snapshot):
+ const Snapshot &snapshot,
+ QmlTypeSystem *typeSystem):
_scopes(scopes),
_doc(doc),
- _snapshot(snapshot)
+ _snapshot(snapshot),
+ m_typeSystem(typeSystem)
{
+ Q_ASSERT(typeSystem != 0);
}
static inline int findFirstQmlObjectScope(const QStack<QmlSymbol*> &scopes, int startIdx)
@@ -114,104 +120,12 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fil
return resolveBuildinType(name);
}
-// FIXME: use a REAL mete-type system here!
-static QSet<QString> qmlMetaTypes = QSet<QString>()
- << QLatin1String("AnchorChanges")
- << QLatin1String("AnimatedImage")
- << QLatin1String("Animation")
- << QLatin1String("Behavior")
- << QLatin1String("Binding")
- << QLatin1String("BorderImage")
- << QLatin1String("ColorAnimation")
- << QLatin1String("Column")
- << QLatin1String("Component")
- << QLatin1String("Connection")
- << QLatin1String("DateTimeFormatter")
- << QLatin1String("EaseFollow")
- << QLatin1String("Flickable")
- << QLatin1String("Flipable")
- << QLatin1String("FocusPanel")
- << QLatin1String("FocusScope")
- << QLatin1String("FolderListModel")
- << QLatin1String("FontLoader")
- << QLatin1String("Gradient")
- << QLatin1String("GradientStop")
- << QLatin1String("GraphicsObjectContainer")
- << QLatin1String("Grid")
- << QLatin1String("GridView")
- << QLatin1String("Image")
- << QLatin1String("Item")
- << QLatin1String("KeyEvent")
- << QLatin1String("Keys")
- << QLatin1String("LayoutItem")
- << QLatin1String("ListModel")
- << QLatin1String("ListView")
- << QLatin1String("Loader")
- << QLatin1String("MouseEvent")
- << QLatin1String("MouseRegion")
- << QLatin1String("NumberAnimation")
- << QLatin1String("NumberFormatter")
- << QLatin1String("ParallelAnimation")
- << QLatin1String("ParentAction")
- << QLatin1String("ParentChange")
- << QLatin1String("ParticleMotionGravity")
- << QLatin1String("ParticleMotionLinear")
- << QLatin1String("ParticleMotionWander")
- << QLatin1String("Particles")
- << QLatin1String("Path")
- << QLatin1String("PathAttribute")
- << QLatin1String("PathCubic")
- << QLatin1String("PathElement")
- << QLatin1String("PathLine")
- << QLatin1String("PathPercent")
- << QLatin1String("PathQuad")
- << QLatin1String("PathView")
- << QLatin1String("PauseAnimation")
- << QLatin1String("PropertyAction")
- << QLatin1String("PropertyAnimation")
- << QLatin1String("PropertyChanges")
- << QLatin1String("Rectangle")
- << QLatin1String("Repeater")
- << QLatin1String("Rotation")
- << QLatin1String("Row")
- << QLatin1String("Scale")
- << QLatin1String("Script")
- << QLatin1String("ScriptAction")
- << QLatin1String("SequentialAnimation")
- << QLatin1String("SpringFollow")
- << QLatin1String("SqlBind")
- << QLatin1String("SqlConnection")
- << QLatin1String("SqlQuery")
- << QLatin1String("State")
- << QLatin1String("StateChangeScript")
- << QLatin1String("SystemPalette")
- << QLatin1String("Text")
- << QLatin1String("TextEdit")
- << QLatin1String("TextInput")
- << QLatin1String("Timer")
- << QLatin1String("Transform")
- << QLatin1String("Transition")
- << QLatin1String("VisualItemModel")
- << QLatin1String("WebView")
- << QLatin1String("XmlListModel")
- << QLatin1String("XmlRole");
-
QmlSymbol *QmlLookupContext::resolveBuildinType(const QString &name)
{
- // FIXME: use a REAL mete-type system here!
-
- if (name == "Rectangle") {
- QmlBuildInSymbol *rectSymbol = new QmlBuildInSymbol(name);
- rectSymbol->addMember(new QmlBuildInSymbol("x"));
- rectSymbol->addMember(new QmlBuildInSymbol("y"));
- rectSymbol->addMember(new QmlBuildInSymbol("height"));
- rectSymbol->addMember(new QmlBuildInSymbol("width"));
- return rectSymbol;
- } else if (qmlMetaTypes.contains(name)) {
- return new QmlBuildInSymbol(name);
- } else {
- return 0;
- }
+ QList<Qml::PackageInfo> packages;
+ // FIXME:
+ packages.append(PackageInfo("Qt", 4, 6));
+ return m_typeSystem->resolve(name, packages);
}
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName)
@@ -270,7 +184,11 @@ QList<QmlSymbol*> QmlLookupContext::visibleSymbolsInScope()
if (!_scopes.isEmpty()) {
QmlSymbol *scope = _scopes.top();
+ // add members defined in this symbol:
result.append(scope->members());
+
+ // add the members of the type of this scope (= object):
+ result.append(expandType(scope));
}
return result;
@@ -301,9 +219,27 @@ QList<QmlSymbol*> QmlLookupContext::visibleTypes()
}
}
- // TODO: handle Qt imports, hack for now:
- foreach (const QString &name, qmlMetaTypes)
- result.append(resolveBuildinType(name));
+ result.append(m_typeSystem->availableTypes("Qt", 4, 6));
return result;
}
+
+QList<QmlSymbol*> QmlLookupContext::expandType(Qml::QmlSymbol *symbol)
+{
+ if (symbol == 0) {
+ return QList<QmlSymbol*>();
+ } else if (QmlBuildInSymbol *buildInSymbol = symbol->asBuildInSymbol()) {
+ return buildInSymbol->members(true);
+ } else if (QmlSymbolFromFile *symbolFromFile = symbol->asSymbolFromFile()){
+ QList<QmlSymbol*> result;
+
+ if (QmlSymbol *superTypeSymbol = resolveType(symbolFromFile->name(), symbolFromFile->fileName())) {
+ result.append(superTypeSymbol->members());
+ result.append(expandType(superTypeSymbol));
+ }
+
+ return result;
+ } else {
+ return QList<QmlSymbol*>();
+ }
+}
diff --git a/src/plugins/qmleditor/qmllookupcontext.h b/src/plugins/qmleditor/qmllookupcontext.h
index 32b508a3cc..e9708dc853 100644
--- a/src/plugins/qmleditor/qmllookupcontext.h
+++ b/src/plugins/qmleditor/qmllookupcontext.h
@@ -1,6 +1,7 @@
#ifndef QMLLOOKUPCONTEXT_H
#define QMLLOOKUPCONTEXT_H
+#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsastvisitor_p.h>
#include <qml/qmldocument.h>
#include <qml/qmlsymbol.h>
@@ -13,33 +14,37 @@ namespace Internal {
class QmlLookupContext
{
public:
- QmlLookupContext(const QStack<QmlSymbol *> &scopes,
+ QmlLookupContext(const QStack<Qml::QmlSymbol *> &scopes,
const QmlDocument::Ptr &doc,
- const Snapshot &snapshot);
+ const Snapshot &snapshot,
+ Qml::MetaType::QmlTypeSystem *typeSystem);
- QmlSymbol *resolve(const QString &name);
- QmlSymbol *resolveType(const QString &name)
+ Qml::QmlSymbol *resolve(const QString &name);
+ Qml::QmlSymbol *resolveType(const QString &name)
{ return resolveType(name, _doc->fileName()); }
- QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
+ Qml::QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
{ return resolveType(toString(name), _doc->fileName()); }
QmlDocument::Ptr document() const
{ return _doc; }
- QList<QmlSymbol*> visibleSymbolsInScope();
- QList<QmlSymbol*> visibleTypes();
+ QList<Qml::QmlSymbol*> visibleSymbolsInScope();
+ QList<Qml::QmlSymbol*> visibleTypes();
+
+ QList<Qml::QmlSymbol*> expandType(Qml::QmlSymbol *symbol);
private:
- QmlSymbol *resolveType(const QString &name, const QString &fileName);
- QmlSymbol *resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName);
- QmlSymbol *resolveBuildinType(const QString &name);
+ Qml::QmlSymbol *resolveType(const QString &name, const QString &fileName);
+ Qml::QmlSymbol *resolveProperty(const QString &name, Qml::QmlSymbol *scope, const QString &fileName);
+ Qml::QmlSymbol *resolveBuildinType(const QString &name);
static QString toString(QmlJS::AST::UiQualifiedId *id);
private:
- QStack<QmlSymbol *> _scopes;
+ QStack<Qml::QmlSymbol *> _scopes;
QmlDocument::Ptr _doc;
Snapshot _snapshot;
+ Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
} // namespace Internal
diff --git a/src/plugins/qmleditor/qmlmodelmanagerinterface.h b/src/plugins/qmleditor/qmlmodelmanagerinterface.h
index 3599f44672..896f76a871 100644
--- a/src/plugins/qmleditor/qmlmodelmanagerinterface.h
+++ b/src/plugins/qmleditor/qmlmodelmanagerinterface.h
@@ -37,6 +37,7 @@
#include <QSharedPointer>
#include <qml/qmldocument.h>
+#include <qml/metatype/qmltypesystem.h>
namespace QmlEditor {
diff --git a/src/plugins/qmleditor/qmlresolveexpression.cpp b/src/plugins/qmleditor/qmlresolveexpression.cpp
index 1c798cd58f..fa09b07aca 100644
--- a/src/plugins/qmleditor/qmlresolveexpression.cpp
+++ b/src/plugins/qmleditor/qmlresolveexpression.cpp
@@ -3,6 +3,7 @@
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
+using namespace Qml;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace QmlJS;
@@ -16,8 +17,7 @@ QmlResolveExpression::QmlResolveExpression(const QmlLookupContext &context)
QmlSymbol *QmlResolveExpression::typeOf(Node *node)
{
QmlSymbol *previousValue = switchValue(0);
- if (node)
- node->accept(this);
+ Node::accept(node, this);
return switchValue(previousValue);
}
diff --git a/src/plugins/qmleditor/qmlresolveexpression.h b/src/plugins/qmleditor/qmlresolveexpression.h
index 6030f1c29c..d876afaf2e 100644
--- a/src/plugins/qmleditor/qmlresolveexpression.h
+++ b/src/plugins/qmleditor/qmlresolveexpression.h
@@ -14,13 +14,13 @@ class QmlResolveExpression: protected QmlJS::AST::Visitor
public:
QmlResolveExpression(const QmlLookupContext &context);
- QmlSymbol *typeOf(QmlJS::AST::Node *node);
- QList<QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
+ Qml::QmlSymbol *typeOf(QmlJS::AST::Node *node);
+ QList<Qml::QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
protected:
using QmlJS::AST::Visitor::visit;
- QmlSymbol *switchValue(QmlSymbol *symbol);
+ Qml::QmlSymbol *switchValue(Qml::QmlSymbol *symbol);
virtual bool visit(QmlJS::AST::FieldMemberExpression *ast);
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
@@ -28,7 +28,7 @@ protected:
private:
QmlLookupContext _context;
- QmlSymbol *_value;
+ Qml::QmlSymbol *_value;
};
} // namespace Internal
diff --git a/src/shared/qml/metatype/QmlMetaTypeBackend.cpp b/src/shared/qml/metatype/QmlMetaTypeBackend.cpp
new file mode 100644
index 0000000000..ec65714989
--- /dev/null
+++ b/src/shared/qml/metatype/QmlMetaTypeBackend.cpp
@@ -0,0 +1,14 @@
+#include "QmlMetaTypeBackend.h"
+#include "qmltypesystem.h"
+
+using namespace Qml::MetaType;
+
+QmlMetaTypeBackend::QmlMetaTypeBackend(QmlTypeSystem *typeSystem):
+ m_typeSystem(typeSystem)
+{
+ Q_ASSERT(typeSystem);
+}
+
+QmlMetaTypeBackend::~QmlMetaTypeBackend()
+{
+}
diff --git a/src/shared/qml/metatype/QmlMetaTypeBackend.h b/src/shared/qml/metatype/QmlMetaTypeBackend.h
new file mode 100644
index 0000000000..cd400bfa66
--- /dev/null
+++ b/src/shared/qml/metatype/QmlMetaTypeBackend.h
@@ -0,0 +1,33 @@
+#ifndef QMLMETATYPEBACKEND_H
+#define QMLMETATYPEBACKEND_H
+
+#include <qml/qml_global.h>
+#include <qml/qmlpackageinfo.h>
+#include <qml/qmlsymbol.h>
+
+namespace Qml {
+namespace MetaType {
+
+class QmlTypeSystem;
+
+class QML_EXPORT QmlMetaTypeBackend
+{
+public:
+ QmlMetaTypeBackend(QmlTypeSystem *typeSystem);
+ virtual ~QmlMetaTypeBackend() = 0;
+
+ virtual QList<QmlSymbol *> availableTypes(const QString &package, int majorVersion, int minorVersion) = 0;
+ virtual QmlSymbol *resolve(const QString &typeName, const QList<PackageInfo> &packages) = 0;
+
+protected:
+ QmlTypeSystem *typeSystem() const
+ { return m_typeSystem; }
+
+private:
+ QmlTypeSystem *m_typeSystem;
+};
+
+} // namespace MetaType
+} // namespace Qml
+
+#endif // QMLMETATYPEBACKEND_H
diff --git a/src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.cpp b/src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.cpp
new file mode 100644
index 0000000000..53c1308b9a
--- /dev/null
+++ b/src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.cpp
@@ -0,0 +1,232 @@
+#include "metainfo.h"
+#include "QtDeclarativeMetaTypeBackend.h"
+
+#include <QDebug>
+
+namespace Qml {
+namespace MetaType {
+namespace Internal {
+
+class QmlDeclarativeSymbol: public QmlBuildInSymbol
+{
+public:
+ virtual ~QmlDeclarativeSymbol()
+ {}
+
+protected:
+ QmlDeclarativeSymbol(QtDeclarativeMetaTypeBackend* backend):
+ m_backend(backend)
+ { Q_ASSERT(backend); }
+
+ QtDeclarativeMetaTypeBackend* backend() const
+ { return m_backend; }
+
+private:
+ QtDeclarativeMetaTypeBackend* m_backend;
+};
+
+class QmlDeclarativeObjectSymbol: public QmlDeclarativeSymbol
+{
+ QmlDeclarativeObjectSymbol(const QmlDeclarativeObjectSymbol &);
+ QmlDeclarativeObjectSymbol &operator=(const QmlDeclarativeObjectSymbol &);
+
+public:
+ QmlDeclarativeObjectSymbol(const QKineticDesigner::NodeMetaInfo &metaInfo, QtDeclarativeMetaTypeBackend* backend):
+ QmlDeclarativeSymbol(backend),
+ m_metaInfo(metaInfo)
+ {
+ Q_ASSERT(metaInfo.isValid());
+
+ m_name = m_metaInfo.typeName();
+ const int slashIdx = m_name.indexOf('/');
+ if (slashIdx != -1)
+ m_name = m_name.mid(slashIdx + 1);
+ }
+
+ virtual ~QmlDeclarativeObjectSymbol()
+ { qDeleteAll(m_members); }
+
+ virtual const QString name() const
+ { return m_name; }
+
+ virtual QmlBuildInSymbol *type() const
+ { return 0; }
+
+ virtual const List members()
+ {
+ if (m_membersToBeDone)
+ initMembers();
+
+ return m_members;
+ }
+
+ virtual List members(bool includeBaseClassMembers)
+ {
+ List result = members();
+
+ if (includeBaseClassMembers)
+ result.append(backend()->inheritedMembers(m_metaInfo));
+
+ return result;
+ }
+
+public:
+ static QString key(const QKineticDesigner::NodeMetaInfo &metaInfo)
+ {
+ return key(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
+ }
+
+ static QString key(const QString &typeNameWithPackage, int majorVersion, int minorVersion)
+ {
+ return QString(typeNameWithPackage)
+ + QLatin1Char('@')
+ + QString::number(majorVersion)
+ + QLatin1Char('.')
+ + QString::number(minorVersion);
+ }
+
+ static QString key(const QString &packageName, const QString &typeName, int majorVersion, int minorVersion)
+ {
+ return packageName
+ + QLatin1Char('/')
+ + typeName
+ + QLatin1Char('@')
+ + QString::number(majorVersion)
+ + QLatin1Char('.')
+ + QString::number(minorVersion);
+ }
+
+private:
+ void initMembers()
+ {
+ if (!m_membersToBeDone)
+ return;
+ m_membersToBeDone = false;
+
+ m_members = backend()->members(m_metaInfo);
+ }
+
+private:
+ QKineticDesigner::NodeMetaInfo m_metaInfo;
+ QString m_name;
+
+ bool m_membersToBeDone;
+ List m_members;
+};
+
+class QmlDeclarativePropertySymbol: public QmlDeclarativeSymbol
+{
+ QmlDeclarativePropertySymbol(const QmlDeclarativePropertySymbol &);
+ QmlDeclarativePropertySymbol &operator=(const QmlDeclarativePropertySymbol &);
+
+public:
+ QmlDeclarativePropertySymbol(const QKineticDesigner::PropertyMetaInfo &metaInfo, QtDeclarativeMetaTypeBackend* backend):
+ QmlDeclarativeSymbol(backend),
+ m_metaInfo(metaInfo)
+ {
+ }
+
+ virtual ~QmlDeclarativePropertySymbol()
+ {}
+
+ virtual const QString name() const
+ { return m_metaInfo.name(); }
+
+ virtual QmlBuildInSymbol *type() const
+ { return backend()->typeOf(m_metaInfo); }
+
+ virtual const List members()
+ {
+ return List();
+ }
+
+ virtual List members(bool /*includeBaseClassMembers*/)
+ {
+ return members();
+ }
+
+private:
+ QKineticDesigner::PropertyMetaInfo m_metaInfo;
+};
+
+} // namespace Internal
+} // namespace MetaType
+} // namespace Qml
+
+using namespace Qml;
+using namespace Qml::MetaType;
+using namespace Qml::MetaType::Internal;
+
+QtDeclarativeMetaTypeBackend::QtDeclarativeMetaTypeBackend(QmlTypeSystem *typeSystem):
+ QmlMetaTypeBackend(typeSystem)
+{
+ foreach (const QKineticDesigner::NodeMetaInfo &metaInfo, QKineticDesigner::MetaInfo::global().allTypes()) {
+ m_symbols.insert(QmlDeclarativeObjectSymbol::key(metaInfo), new QmlDeclarativeObjectSymbol(metaInfo, this));
+ }
+}
+
+QtDeclarativeMetaTypeBackend::~QtDeclarativeMetaTypeBackend()
+{
+ qDeleteAll(m_symbols.values());
+}
+
+QList<QmlSymbol *> QtDeclarativeMetaTypeBackend::availableTypes(const QString &package, int majorVersion, int minorVersion)
+{
+ QList<QmlSymbol *> result;
+ const QString prefix = package + QLatin1Char('/');
+
+ foreach (const QKineticDesigner::NodeMetaInfo &metaInfo, QKineticDesigner::MetaInfo::global().allTypes()) {
+ if (metaInfo.typeName().startsWith(prefix) && metaInfo.majorVersion() == majorVersion && metaInfo.minorVersion() == minorVersion)
+ result.append(getSymbol(metaInfo));
+ }
+
+ return result;
+}
+
+QmlSymbol *QtDeclarativeMetaTypeBackend::resolve(const QString &typeName, const QList<PackageInfo> &packages)
+{
+ QList<QmlSymbol *> result;
+
+ foreach (const PackageInfo &package, packages) {
+ if (QmlSymbol *symbol = m_symbols.value(QmlDeclarativeObjectSymbol::key(package.name(), typeName, package.majorVersion(), package.minorVersion()), 0))
+ return symbol;
+ }
+
+ return 0;
+}
+
+QList<QmlSymbol *> QtDeclarativeMetaTypeBackend::members(const QKineticDesigner::NodeMetaInfo &metaInfo)
+{
+ QList<QmlSymbol *> result;
+
+ foreach (const QKineticDesigner::PropertyMetaInfo &propertyInfo, metaInfo.properties(false).values()) {
+ result.append(new QmlDeclarativePropertySymbol(propertyInfo, this));
+ }
+
+ return result;
+}
+
+QList<QmlSymbol *> QtDeclarativeMetaTypeBackend::inheritedMembers(const QKineticDesigner::NodeMetaInfo &metaInfo)
+{
+ QList<QmlSymbol *> result;
+
+ foreach (const QKineticDesigner::NodeMetaInfo &superNode, metaInfo.directSuperClasses()) {
+ result.append(getSymbol(superNode)->members(true));
+ }
+
+ return result;
+}
+
+QmlDeclarativeSymbol *QtDeclarativeMetaTypeBackend::typeOf(const QKineticDesigner::PropertyMetaInfo &metaInfo)
+{
+ const QString key = QmlDeclarativeObjectSymbol::key(metaInfo.type(), metaInfo.typeMajorVersion(), metaInfo.typeMinorVersion());
+
+ return m_symbols.value(key, 0);
+}
+
+QmlDeclarativeSymbol *QtDeclarativeMetaTypeBackend::getSymbol(const QKineticDesigner::NodeMetaInfo &metaInfo)
+{
+ const QString key = QmlDeclarativeObjectSymbol::key(metaInfo);
+
+ return m_symbols.value(key, 0);
+}
diff --git a/src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.h b/src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.h
new file mode 100644
index 0000000000..e0693c124c
--- /dev/null
+++ b/src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.h
@@ -0,0 +1,47 @@
+#ifndef QTDECLARATIVEMETATYPEBACKEND_H
+#define QTDECLARATIVEMETATYPEBACKEND_H
+
+#include <qml/metatype/QmlMetaTypeBackend.h>
+#include <qml/metatype/nodemetainfo.h>
+#include <qml/metatype/propertymetainfo.h>
+
+#include <QtCore/QList>
+
+namespace Qml {
+namespace MetaType {
+namespace Internal {
+
+class QmlDeclarativeSymbol;
+class QmlDeclarativeObjectSymbol;
+class QmlDeclarativePropertySymbol;
+
+class QtDeclarativeMetaTypeBackend: public QmlMetaTypeBackend
+{
+ friend class QmlDeclarativeSymbol;
+ friend class QmlDeclarativeObjectSymbol;
+ friend class QmlDeclarativePropertySymbol;
+
+public:
+ QtDeclarativeMetaTypeBackend(QmlTypeSystem *typeSystem);
+ ~QtDeclarativeMetaTypeBackend();
+
+ virtual QList<QmlSymbol *> availableTypes(const QString &package, int majorVersion, int minorVersion);
+ virtual QmlSymbol *resolve(const QString &typeName, const QList<PackageInfo> &packages);
+
+protected:
+ QList<QmlSymbol *> members(const QKineticDesigner::NodeMetaInfo &metaInfo);
+ QList<QmlSymbol *> inheritedMembers(const QKineticDesigner::NodeMetaInfo &metaInfo);
+ QmlDeclarativeSymbol *typeOf(const QKineticDesigner::PropertyMetaInfo &metaInfo);
+
+private:
+ QmlDeclarativeSymbol *getSymbol(const QKineticDesigner::NodeMetaInfo &metaInfo);
+
+private:
+ QMap<QString, QmlDeclarativeSymbol*> m_symbols;
+};
+
+} // namespace Internal
+} // namespace MetaType
+} // namespace Qml
+
+#endif // QTDECLARATIVEMETATYPEBACKEND_H
diff --git a/src/shared/qml/metatype/exception.cpp b/src/shared/qml/metatype/exception.cpp
new file mode 100644
index 0000000000..1d836476e2
--- /dev/null
+++ b/src/shared/qml/metatype/exception.cpp
@@ -0,0 +1,163 @@
+#include "exception.h"
+
+#ifdef Q_OS_LINUX
+#include <execinfo.h>
+#include <cxxabi.h>
+#endif
+
+#include <QRegExp>
+
+/*!
+\defgroup CoreExceptions
+*/
+/*!
+\class QKineticDesigner::Exception
+\ingroup CoreExceptions
+\brief This is the abstract base class for all excetions.
+ Exceptions should be used in cases there is no other way to say something goes wrong. For example
+ the result would be a inconsistent model or a crash.
+*/
+
+
+namespace QKineticDesigner {
+
+#ifdef Q_OS_LINUX
+const char* demangle(const char* name)
+{
+ char buf[1024];
+ size_t size = 1024;
+ int status;
+ char* res;
+ res = abi::__cxa_demangle(name,
+ buf,
+ &size,
+ &status);
+ return res;
+}
+#else
+const char* demangle(const char* name)
+{
+ return name;
+}
+#endif
+
+
+bool Exception::s_shouldAssert = true;
+
+void Exception::setShouldAssert(bool assert)
+{
+ s_shouldAssert = assert;
+}
+
+bool Exception::shouldAssert()
+{
+ return s_shouldAssert;
+}
+
+/*!
+\brief Constructor
+
+\param line use the __LINE__ macro
+\param function use the __FUNCTION__ or the Q_FUNC_INFO macro
+\param file use the __FILE__ macro
+*/
+Exception::Exception(int line,
+ const QString &function,
+ const QString &file)
+ : m_line(line),
+ m_function(function),
+ m_file(file)
+{
+#ifdef Q_OS_LINUX
+ void * array[50];
+ int nSize = backtrace(array, 50);
+ char ** symbols = backtrace_symbols(array, nSize);
+
+ for (int i = 0; i < nSize; i++)
+ {
+ m_backTrace.append(QString("%1\n").arg(symbols[i]));
+ }
+
+ free(symbols);
+#endif
+
+if (s_shouldAssert)
+ Q_ASSERT_X(false, function.toLatin1(), QString("%1:%2 - %3").arg(file).arg(line).arg(function).toLatin1());
+}
+
+Exception::~Exception()
+{
+}
+
+/*!
+\brief Returns the unmangled backtrace of this exception
+
+\returns the backtrace as a string
+*/
+QString Exception::backTrace() const
+{
+ return m_backTrace;
+}
+
+/*!
+\brief Returns the optional description of this exception
+
+\returns the description as string
+*/
+QString Exception::description() const
+{
+ return QString();
+}
+
+/*!
+\brief Returns the line number where this exception was thrown
+
+\returns the line number as integer
+*/
+int Exception::line() const
+{
+ return m_line;
+}
+
+/*!
+\brief Returns the function name where this exception was thrown
+
+\returns the function name as string
+*/
+QString Exception::function() const
+{
+ return m_function;
+}
+
+/*!
+\brief Returns the file name where this exception was thrown
+
+\returns the file name as string
+*/
+QString Exception::file() const
+{
+ return m_file;
+}
+
+QDebug operator<<(QDebug debug, const Exception &exception)
+{
+ debug.nospace() << "Exception: " << exception.type() << "\n"
+ "Function: " << exception.function() << "\n"
+ "File: " << exception.file() << "\n"
+ "Line: " << exception.line() << "\n";
+ if (!exception.description().isEmpty())
+ debug.nospace() << exception.description();
+
+ if (!exception.backTrace().isEmpty())
+ debug.nospace() << exception.backTrace();
+
+ return debug.space();
+}
+
+/*!
+\fn QString Exception::type() const
+\brief Returns the type of this exception
+
+\returns the type as a string
+*/
+}
diff --git a/src/shared/qml/metatype/exception.h b/src/shared/qml/metatype/exception.h
new file mode 100644
index 0000000000..093859db6b
--- /dev/null
+++ b/src/shared/qml/metatype/exception.h
@@ -0,0 +1,42 @@
+#ifndef EXCEPTION_H
+#define EXCEPTION_H
+
+#include <qml/qml_global.h>
+
+#include <QString>
+#include <QtDebug>
+
+namespace QKineticDesigner {
+
+class QML_EXPORT Exception
+{
+public:
+ Exception(int line,
+ const QString &function,
+ const QString &file);
+ virtual ~Exception();
+
+ virtual QString type() const=0;
+ virtual QString description() const;
+
+ int line() const;
+ QString function() const;
+ QString file() const;
+ QString backTrace() const;
+
+ static void setShouldAssert(bool assert);
+ static bool shouldAssert();
+
+private:
+ int m_line;
+ QString m_function;
+ QString m_file;
+ QString m_backTrace;
+ static bool s_shouldAssert;
+};
+
+QML_EXPORT QDebug operator<<(QDebug debug, const Exception &exception);
+
+}
+
+#endif // EXCEPTION_H
diff --git a/src/shared/qml/metatype/invalidmetainfoexception.cpp b/src/shared/qml/metatype/invalidmetainfoexception.cpp
new file mode 100644
index 0000000000..a6caa45b5f
--- /dev/null
+++ b/src/shared/qml/metatype/invalidmetainfoexception.cpp
@@ -0,0 +1,35 @@
+#include "invalidmetainfoexception.h"
+
+/*!
+\class QKineticDesigner::InvalidMetaInfoException
+\ingroup CoreExceptions
+\brief Exception for a invalid meta info
+
+\see NodeMetaInfo PropertyMetaInfo MetaInfo
+*/
+namespace QKineticDesigner {
+/*!
+\brief Constructor
+
+\param line use the __LINE__ macro
+\param function use the __FUNCTION__ or the Q_FUNC_INFO macro
+\param file use the __FILE__ macro
+*/
+InvalidMetaInfoException::InvalidMetaInfoException(int line,
+ const QString &function,
+ const QString &file)
+ : Exception(line, function, file)
+{
+}
+
+/*!
+\brief Returns the type of this exception
+
+\returns the type as a string
+*/
+QString InvalidMetaInfoException::type() const
+{
+ return "InvalidMetaInfoException";
+}
+
+}
diff --git a/src/shared/qml/metatype/invalidmetainfoexception.h b/src/shared/qml/metatype/invalidmetainfoexception.h
new file mode 100644
index 0000000000..883616884a
--- /dev/null
+++ b/src/shared/qml/metatype/invalidmetainfoexception.h
@@ -0,0 +1,21 @@
+#ifndef INVALIDMETAINFOEXCEPTION_H
+#define INVALIDMETAINFOEXCEPTION_H
+
+#include "exception.h"
+
+namespace QKineticDesigner {
+
+class QML_EXPORT InvalidMetaInfoException : public Exception
+{
+public:
+ InvalidMetaInfoException(int line,
+ const QString &function,
+ const QString &file);
+
+ QString type() const;
+
+};
+
+}
+
+#endif // INVALIDMETAINFOEXCEPTION_H
diff --git a/src/shared/qml/metatype/metainfo.cpp b/src/shared/qml/metatype/metainfo.cpp
new file mode 100644
index 0000000000..356c6805b4
--- /dev/null
+++ b/src/shared/qml/metatype/metainfo.cpp
@@ -0,0 +1,461 @@
+#include "invalidmetainfoexception.h"
+#include "metainfo.h"
+#include "propertymetainfo.h"
+
+#include <QPair>
+#include <QtAlgorithms>
+#include <QMetaProperty>
+#include <QmlMetaType>
+
+enum {
+ debug = false
+};
+
+namespace QKineticDesigner {
+namespace Internal {
+
+class MetaInfoPrivate
+{
+ Q_DISABLE_COPY(MetaInfoPrivate)
+public:
+ typedef QSharedPointer<MetaInfoPrivate> Pointer;
+ typedef QWeakPointer<MetaInfoPrivate> WeakPointer;
+
+
+ MetaInfoPrivate(MetaInfo *q);
+ void clear();
+
+ void initialize();
+ void parseQmlTypes();
+ void parseNonQmlTypes();
+ void parseValueTypes();
+ void parseNonQmlClassRecursively(const QMetaObject *qMetaObject);
+ void parseProperties(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const;
+ void parseClassInfo(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const;
+
+ QString typeName(const QMetaObject *qMetaObject) const;
+
+ void parseXmlFiles();
+
+ QMultiHash<QString, QString> m_superClassHash; // the list of direct superclasses
+ QHash<QString, NodeMetaInfo> m_nodeMetaInfoHash;
+ QHash<QString, QString> m_QtTypesToQmlTypes;
+
+ MetaInfo *m_q;
+ bool m_isInitialized;
+};
+
+MetaInfoPrivate::MetaInfoPrivate(MetaInfo *q) :
+ m_q(q),
+ m_isInitialized(false)
+{
+}
+
+void MetaInfoPrivate::clear()
+{
+ m_superClassHash.clear();
+ m_nodeMetaInfoHash.clear();
+ m_isInitialized = false;
+}
+
+void MetaInfoPrivate::initialize()
+{
+ parseQmlTypes();
+ parseNonQmlTypes();
+// parseValueTypes();
+// parseXmlFiles();
+
+ m_isInitialized = true;
+}
+
+
+
+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
+ }
+ int majorVersion = -1, minorVersion = -1;
+ if (QmlType *propertyType = QmlMetaType::qmlType(qMetaObject)) {
+ majorVersion = propertyType->majorVersion();
+ minorVersion = propertyType->minorVersion();
+ }
+
+ propertyInfo.setType(typeName, majorVersion, minorVersion);
+ 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()) {
+// EnumeratorMetaInfo enumerator;
+//
+// QMetaEnum qEnumerator = qProperty.enumerator();
+// enumerator.setValid(qEnumerator.isValid());
+// enumerator.setIsFlagType(qEnumerator.isFlag());
+// enumerator.setScope(qEnumerator.scope());
+// enumerator.setName(qEnumerator.name());
+// for (int i = 0 ;i < qEnumerator.keyCount(); i++)
+// {
+// enumerator.addElement(qEnumerator.valueToKey(i), i);
+// }
+//
+// propertyInfo.setEnumerator(enumerator);
+// }
+
+ 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;
+ }
+ }
+}
+
+void MetaInfoPrivate::parseNonQmlClassRecursively(const QMetaObject *qMetaObject)
+{
+ Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject");
+ const QString className = qMetaObject->className();
+ if ( !m_q->hasNodeMetaInfo(className)
+ && !QmlMetaType::qmlTypeNames().contains(typeName(qMetaObject).toAscii()) ) {
+ NodeMetaInfo nodeMetaInfo(*m_q);
+ nodeMetaInfo.setTypeName(typeName(qMetaObject));
+ parseProperties(nodeMetaInfo, qMetaObject);
+ parseClassInfo(nodeMetaInfo, qMetaObject);
+
+ if (debug)
+ qDebug() << "adding non qml type" << className << typeName(qMetaObject) << ", parent type" << typeName(qMetaObject->superClass());
+ m_q->addNodeInfo(nodeMetaInfo, typeName(qMetaObject->superClass()));
+ }
+
+ if (const QMetaObject *superClass = qMetaObject->superClass()) {
+ parseNonQmlClassRecursively(superClass);
+ }
+}
+
+
+QString MetaInfoPrivate::typeName(const QMetaObject *qMetaObject) const
+{
+ if (!qMetaObject)
+ return QString();
+ QString className = qMetaObject->className();
+ if (QmlType *qmlType = QmlMetaType::qmlType(qMetaObject)) {
+ QString qmlClassName(qmlType->qmlTypeName());
+ if (!qmlClassName.isEmpty())
+ className = qmlType->qmlTypeName(); // Ensure that we always use the qml name,
+ // if available.
+ }
+ return className;
+}
+
+void MetaInfoPrivate::parseQmlTypes()
+{
+ foreach (QmlType *qmlType, QmlMetaType::qmlTypes()) {
+ const QString qtTypeName(qmlType->typeName());
+ const QString qmlTypeName(qmlType->qmlTypeName());
+ m_QtTypesToQmlTypes.insert(qtTypeName, qmlTypeName);
+ }
+ foreach (QmlType *qmlType, QmlMetaType::qmlTypes()) {
+ 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;
+
+ NodeMetaInfo nodeMetaInfo(*m_q);
+ nodeMetaInfo.setTypeName(qmlType->qmlTypeName());
+ nodeMetaInfo.setMajorVersion(qmlType->majorVersion());
+ nodeMetaInfo.setMinorVersion(qmlType->minorVersion());
+
+ parseProperties(nodeMetaInfo, qMetaObject);
+ parseClassInfo(nodeMetaInfo, qMetaObject);
+
+ QString superTypeName = typeName(qMetaObject->superClass());
+ if (qmlType->baseMetaObject() != qMetaObject) {
+ // type is declared with Q_DECLARE_EXTENDED_TYPE
+ // also parse properties of original type
+ parseProperties(nodeMetaInfo, qmlType->baseMetaObject());
+ superTypeName = typeName(qmlType->baseMetaObject()->superClass());
+ }
+
+ m_q->addNodeInfo(nodeMetaInfo, superTypeName);
+ }
+}
+
+void MetaInfoPrivate::parseNonQmlTypes()
+{
+ foreach (QmlType *qmlType, QmlMetaType::qmlTypes()) {
+ parseNonQmlClassRecursively(qmlType->metaObject());
+ }
+}
+
+} // namespace Internal
+
+using QKineticDesigner::Internal::MetaInfoPrivate;
+
+MetaInfo MetaInfo::s_global;
+QStringList MetaInfo::s_pluginDirs;
+
+
+/*!
+\class QKineticDesigner::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(), QKineticDesigner::NodeMetaInfo, QKineticDesigner::PropertyMetaInfo, QKineticDesigner::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;
+}
+
+QList<NodeMetaInfo> MetaInfo::allTypes() const
+{
+ return m_p->m_nodeMetaInfoHash.values();
+}
+
+/*!
+ \brief Returns whether a type with the given name is registered in the meta system.
+ */
+bool MetaInfo::hasNodeMetaInfo(const QString &typeName, int /*majorVersion*/, int /*minorVersion*/) const
+{
+ if (m_p->m_nodeMetaInfoHash.contains(typeName))
+ return true;
+ if (!isGlobal())
+ return global().hasNodeMetaInfo(typeName);
+ return false;
+}
+
+/*!
+ \brief Returns meta information for a qml type. An invalid NodeMetaInfo object if the type is unknown.
+ */
+NodeMetaInfo MetaInfo::nodeMetaInfo(const QString &typeName, int /*majorVersion*/, int /*minorVersion*/) const
+{
+ if (m_p->m_nodeMetaInfoHash.contains(typeName))
+ return m_p->m_nodeMetaInfoHash.value(typeName, NodeMetaInfo());
+ if (!isGlobal())
+ return global().nodeMetaInfo(typeName);
+
+ return NodeMetaInfo();
+}
+
+QStringList MetaInfo::superClasses(const QString &className) const
+{
+ QStringList ancestorList = m_p->m_superClassHash.values(className);
+ foreach (const QString &ancestor, ancestorList) {
+ QStringList superClassList = superClasses(ancestor);
+ if (!superClassList.isEmpty())
+ ancestorList += superClassList;
+ }
+ if (!isGlobal())
+ ancestorList += global().superClasses(className);
+ return ancestorList;
+}
+
+QStringList MetaInfo::directSuperClasses(const QString &className) const
+{
+ QStringList directAncestorList = m_p->m_superClassHash.values(className);
+ if (!isGlobal())
+ directAncestorList += global().directSuperClasses(className);
+ return directAncestorList;
+}
+
+QList<NodeMetaInfo> MetaInfo::superClasses(const NodeMetaInfo &nodeInfo) const
+{
+ if (!nodeInfo.isValid()) {
+ Q_ASSERT_X(nodeInfo.isValid(), Q_FUNC_INFO, "Invalid nodeInfo argument");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ QList<NodeMetaInfo> superClassList;
+
+ foreach (const QString &typeName, superClasses(nodeInfo.typeName())) {
+ if (!hasNodeMetaInfo(typeName))
+ continue;
+ const NodeMetaInfo superClass = nodeMetaInfo(typeName);
+ if (!superClassList.contains(superClass))
+ superClassList.append(superClass);
+ }
+ return superClassList;
+}
+
+QList<NodeMetaInfo> MetaInfo::directSuperClasses(const NodeMetaInfo &nodeInfo) const
+{
+ if (!nodeInfo.isValid()) {
+ Q_ASSERT_X(nodeInfo.isValid(), Q_FUNC_INFO, "Invalid nodeInfo argument");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ QList<NodeMetaInfo> superClassList;
+
+ foreach (const QString &typeName, directSuperClasses(nodeInfo.typeName())) {
+ if (!hasNodeMetaInfo(typeName))
+ continue;
+ const NodeMetaInfo superClass = nodeMetaInfo(typeName);
+ if (!superClassList.contains(superClass))
+ superClassList.append(superClass);
+ }
+ return superClassList;
+}
+
+QStringList MetaInfo::itemLibraryItems() const
+{
+ QStringList completeList = m_p->m_nodeMetaInfoHash.keys();
+ QStringList finalList;
+ foreach (const QString &name, completeList) {
+ if (nodeMetaInfo(name).isVisibleToItemLibrary())
+ finalList.append(name);
+ }
+
+ if (!isGlobal())
+ finalList += global().itemLibraryItems();
+
+ return finalList;
+}
+
+/*!
+ \brief Returns whether className is the same type or a type derived from superClassName.
+ */
+bool MetaInfo::isSubclassOf(const QString &className, const QString &superClassName) const
+{
+ return (className == superClassName) || superClasses(className).contains(superClassName);
+}
+
+/*!
+ \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()
+{
+ MetaInfo::global().m_p->clear();
+}
+
+void MetaInfo::setPluginPaths(const QStringList &paths)
+{
+ s_pluginDirs = paths;
+}
+
+/*!
+ This bypasses the notifications to the model that the metatype has changed.
+ Use MetaInfo::addNodeInfo() instead
+ */
+void MetaInfo::addSuperClassRelationship(const QString &superClassName, const QString &className)
+{
+ m_p->m_superClassHash.insert(className, superClassName);
+}
+
+void MetaInfo::addNodeInfo(NodeMetaInfo &nodeInfo, const QString &baseType)
+{
+ if (nodeInfo.typeName().isEmpty() || nodeInfo.metaInfo() != *this)
+ throw new InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+
+ if (nodeInfo.typeName() == baseType) // prevent simple recursion
+ throw new InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+
+ m_p->m_nodeMetaInfoHash.insert(nodeInfo.typeName(), nodeInfo);
+
+ if (!baseType.isEmpty()) {
+ m_p->m_superClassHash.insert(nodeInfo.typeName(), baseType);
+ }
+}
+
+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);
+}
+} //namespace QKineticDesigner
diff --git a/src/shared/qml/metatype/metainfo.h b/src/shared/qml/metatype/metainfo.h
new file mode 100644
index 0000000000..86a2447c7f
--- /dev/null
+++ b/src/shared/qml/metatype/metainfo.h
@@ -0,0 +1,83 @@
+#ifndef METAINFO_H
+#define METAINFO_H
+
+#include <qml/qml_global.h>
+#include <qml/metatype/nodemetainfo.h>
+#include <qml/metatype/propertymetainfo.h>
+
+#include <QMultiHash>
+#include <QString>
+#include <QStringList>
+#include <QtCore/QSharedPointer>
+
+namespace QKineticDesigner {
+
+class ModelNode;
+class AbstractProperty;
+
+namespace Internal {
+ class MetaInfoPrivate;
+ class ModelPrivate;
+ class SubComponentManagerPrivate;
+ typedef QSharedPointer<MetaInfoPrivate> MetaInfoPrivatePointer;
+}
+
+QML_EXPORT bool operator==(const MetaInfo &first, const MetaInfo &second);
+QML_EXPORT bool operator!=(const MetaInfo &first, const MetaInfo &second);
+
+class QML_EXPORT MetaInfo
+{
+ friend class QKineticDesigner::Internal::MetaInfoPrivate;
+ friend class QKineticDesigner::Internal::MetaInfoParser;
+ friend class QKineticDesigner::NodeMetaInfo;
+ friend bool QKineticDesigner::operator==(const MetaInfo &, const MetaInfo &);
+
+public:
+ MetaInfo(const MetaInfo &metaInfo);
+ ~MetaInfo();
+ MetaInfo& operator=(const MetaInfo &other);
+
+ QList<NodeMetaInfo> allTypes() const;
+
+ bool hasNodeMetaInfo(const QString &typeName, int majorVersion = 4, int minorVersion = 6) const;
+ // ### makes no sense since ModelNode has minor/major version
+ NodeMetaInfo nodeMetaInfo(const ModelNode &node) const;
+ NodeMetaInfo nodeMetaInfo(const QString &typeName, int majorVersion = 4, int minorVersion = 6) const;
+
+ // TODO: Move these to private
+ bool isSubclassOf(const QString &className, const QString &superClassName) const;
+ bool isSubclassOf(const ModelNode &modelNode, const QString &superClassName) const;
+
+ bool hasEnumerator(const QString &enumeratorName) const;
+
+ QStringList itemLibraryItems() const;
+
+public:
+ static MetaInfo global();
+ static void clearGlobal();
+
+ static void setPluginPaths(const QStringList &paths);
+
+private:
+ QStringList superClasses(const QString &className) const;
+ QStringList directSuperClasses(const QString &className) const;
+ QList<NodeMetaInfo> superClasses(const NodeMetaInfo &nodeMetaInfo) const;
+ QList<NodeMetaInfo> directSuperClasses(const NodeMetaInfo &nodeMetaInfo) const;
+
+ void addSuperClassRelationship(const QString &superClassName, const QString &className);
+
+ void addNodeInfo(NodeMetaInfo &info, const QString &baseType);
+
+ bool isGlobal() const;
+
+private:
+ MetaInfo();
+
+ Internal::MetaInfoPrivatePointer m_p;
+ static MetaInfo s_global;
+ static QStringList s_pluginDirs;
+};
+
+} //namespace QKineticDesigner
+
+#endif // METAINFO_H
diff --git a/src/shared/qml/metatype/nodemetainfo.cpp b/src/shared/qml/metatype/nodemetainfo.cpp
new file mode 100644
index 0000000000..b3b136c076
--- /dev/null
+++ b/src/shared/qml/metatype/nodemetainfo.cpp
@@ -0,0 +1,695 @@
+#include "invalidmetainfoexception.h"
+#include "metainfo.h"
+#include "nodemetainfo.h"
+#include "propertymetainfo.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QtDebug>
+#include <QtGui/QIcon>
+#include <QtDeclarative/QmlMetaType>
+#include <QtDeclarative/QmlContext>
+#include <QtDeclarative/QmlEngine>
+#include <QtDeclarative/QmlComponent>
+#include <private/qmlvaluetype_p.h>
+
+namespace QKineticDesigner {
+
+namespace Internal {
+
+class NodeMetaInfoData : public QSharedData
+{
+public:
+ typedef enum {
+ No = -1,
+ Unknown = 0,
+ Yes = 1,
+ } TristateBoolean;
+
+public:
+ NodeMetaInfoData(const MetaInfo &metaInfo) :
+ metaInfo(metaInfo),
+ isContainer(false),
+ isVisibleToItemLibrary(false),
+ isFXItem(Unknown),
+ icon(),
+ category("misc")
+ { }
+
+ MetaInfo metaInfo;
+ QString typeName;
+ bool isContainer;
+ bool isVisibleToItemLibrary;
+ TristateBoolean isFXItem;
+ QHash<QString, PropertyMetaInfo> propertyMetaInfoHash;
+ QIcon icon;
+ QString category;
+ QString qmlFile;
+ QString defaultProperty;
+ int majorVersion;
+ int minorVersion;
+};
+
+} // namespace Internal
+
+/*!
+\class QKineticDesigner::NodeMetaInfo
+\ingroup CoreModel
+\brief The NodeMetaInfo class provides meta information about a qml type.
+
+A NodeMetaInfo object can be created via ModelNode::metaInfo, or MetaInfo::nodeMetaInfo.
+
+The object can be invalid - you can check this by calling isValid().
+The object is invalid if you ask for meta information for
+an non-existing qml property. Also the node meta info can become invalid
+if the enclosing type is deregistered from the meta type system (e.g.
+a sub component qml file is deleted). Trying to call any accessor methods on an invalid
+NodeMetaInfo object will result in an InvalidMetaInfoException being thrown.
+
+\see QKineticDesigner::MetaInfo, QKineticDesigner::PropertyMetaInfo, QKineticDesigner::EnumeratorMetaInfo
+*/
+
+NodeMetaInfo::NodeMetaInfo()
+ : m_data(0)
+{
+ // create invalid node
+}
+
+NodeMetaInfo::NodeMetaInfo(const MetaInfo &metaInfo)
+ : m_data(new Internal::NodeMetaInfoData(metaInfo))
+{
+}
+
+NodeMetaInfo::~NodeMetaInfo()
+{
+}
+
+/*!
+ \brief Creates a copy of the handle.
+ */
+NodeMetaInfo::NodeMetaInfo(const NodeMetaInfo &other)
+ : m_data(other.m_data)
+{
+}
+
+/*!
+ \brief Copies the handle.
+ */
+NodeMetaInfo &NodeMetaInfo::operator=(const NodeMetaInfo &other)
+{
+ if (this != &other)
+ this->m_data = other.m_data;
+
+ return *this;
+}
+
+/*!
+ \brief Returns whether the meta information system knows about this type.
+ */
+bool NodeMetaInfo::isValid() const
+{
+ return (m_data.data() != 0);
+}
+
+MetaInfo NodeMetaInfo::metaInfo() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return m_data->metaInfo;
+}
+
+/*!
+ \brief Creates an instance of the qml type in the given qml context.
+
+ \throws InvalidArgumentException when the context argument is a null pointer
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+QObject *NodeMetaInfo::createInstance(QmlContext *parentContext) const
+{
+ if (!parentContext) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Context cannot be null");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ QObject *object = 0;
+ if (isComponent()) {
+ // qml component
+ // TODO: This is maybe expensive ...
+ QmlComponent component(parentContext->engine(), QUrl::fromLocalFile(m_data->qmlFile));
+ object = component.create(parentContext);
+ } else {
+ // primitive
+ object = QmlMetaType::qmlType(typeName().toAscii(), 4, 6)->create();
+ if (object && parentContext)
+ QmlEngine::setContextForObject(object, new QmlContext(parentContext, object));
+ }
+ return object;
+}
+
+/*!
+ \brief Returns all (direct and indirect) ancestor types.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+QList<NodeMetaInfo> NodeMetaInfo::superClasses() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return m_data->metaInfo.superClasses(*this);
+}
+
+/*!
+ \brief Returns direct ancestor types.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+QList<NodeMetaInfo> NodeMetaInfo::directSuperClasses() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return m_data->metaInfo.directSuperClasses(*this);
+}
+
+/*!
+ \brief Returns meta information for all properties, including properties inherited from base types.
+
+ Returns a Hash with the name of the property as key and property meta information as value. Node
+ In case there are multiple properties with the same name in the hierarchy the property defined
+ in the more concrete subclass is chosen.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+QHash<QString,PropertyMetaInfo> NodeMetaInfo::properties(bool resolveDotSyntax ) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ QHash<QString,PropertyMetaInfo> propertiesInfo;
+ propertiesInfo = m_data->propertyMetaInfoHash;
+ foreach (const NodeMetaInfo &nodeInfo, directSuperClasses()) {
+ QHash<QString,PropertyMetaInfo> superClassProperties = nodeInfo.properties();
+ QHashIterator<QString,PropertyMetaInfo> iter(superClassProperties);
+ while (iter.hasNext()) {
+ iter.next();
+ if (!propertiesInfo.contains(iter.key()))
+ propertiesInfo.insert(iter.key(), iter.value());
+ }
+ }
+ if (resolveDotSyntax) {
+ QHashIterator<QString,PropertyMetaInfo> iter(dotProperties());
+ while (iter.hasNext()) {
+ iter.next();
+ if (!propertiesInfo.contains(iter.key()))
+ propertiesInfo.insert(iter.key(), iter.value());
+ }
+ }
+ return propertiesInfo;
+}
+
+/*!
+ \brief Returns meta information for all dot properties, including properties inherited from base types.
+
+ */
+QHash<QString,PropertyMetaInfo> NodeMetaInfo::dotProperties() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ QHash<QString,PropertyMetaInfo> propertiesInfo;
+
+ foreach (const QString &propertyName, properties().keys()) {
+ if (property(propertyName).hasDotSubProperties()) {
+ QString propertyType = property(propertyName).type();
+ if (propertyType.right(1) == "*")
+ propertyType = propertyType.left(propertyType.size() - 1).trimmed();
+ NodeMetaInfo nodeInfo(m_data->metaInfo.nodeMetaInfo(propertyType, majorVersion(), minorVersion()));
+ if (nodeInfo.isValid()) {
+ QHashIterator<QString,PropertyMetaInfo> iter(nodeInfo.properties());
+ while (iter.hasNext()) {
+ iter.next();
+ if (!propertiesInfo.contains(iter.key()) && iter.key() != "objectName")
+ propertiesInfo.insert(propertyName + "." + iter.key(), iter.value());
+ }
+ }
+ }
+ }
+ return propertiesInfo;
+}
+
+/*!
+ \brief Returns meta information for a property. An invalid PropertyMetaInfo object if the given property name is unknown.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+PropertyMetaInfo NodeMetaInfo::property(const QString &propertyName, bool resolveDotSyntax) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ if (resolveDotSyntax && propertyName.contains('.')) {
+ const QStringList nameParts = propertyName.split('.');
+ NodeMetaInfo nodeInfo = *this;
+ const int partCount = nameParts.size();
+ for (int i = 0; i < partCount; ++i) {
+ const QString namePart(nameParts.at(i));
+ const PropertyMetaInfo propInfo = nodeInfo.property(namePart, false);
+
+ if (!propInfo.isValid())
+ break;
+
+ if (i + 1 == partCount)
+ return propInfo;
+
+ QString propertyType = propInfo.type();
+ if (propertyType.right(1) == "*")
+ propertyType = propertyType.left(propertyType.size() - 1).trimmed();
+ nodeInfo = m_data->metaInfo.nodeMetaInfo(propertyType, majorVersion(), minorVersion());
+ if (!nodeInfo.isValid()) {
+ qDebug() << "no type info available for" << propertyType;
+ break;
+ }
+ }
+
+ return PropertyMetaInfo();
+ } else {
+ PropertyMetaInfo propertyMetaInfo;
+
+ if (hasLocalProperty(propertyName)) {
+ propertyMetaInfo = m_data->propertyMetaInfoHash.value(propertyName, PropertyMetaInfo());
+ } else {
+ foreach (const NodeMetaInfo &superTypeMetaInfo, directSuperClasses()) {
+ Q_ASSERT(superTypeMetaInfo.isValid());
+ propertyMetaInfo = superTypeMetaInfo.property(propertyName);
+ if (propertyMetaInfo.isValid())
+ break;
+ }
+ }
+
+ return propertyMetaInfo;
+ }
+}
+
+/*!
+ \brief Returns whether the type has a (not inherited) property.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::hasLocalProperty(const QString &propertyName, bool resolveDotSyntax) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ if (resolveDotSyntax && propertyName.contains('.')) {
+ const QStringList nameParts = propertyName.split('.');
+ NodeMetaInfo nodeInfo = *this;
+ const int partCount = nameParts.size();
+ for (int i = 0; i < partCount; ++i) {
+ QString namePart(nameParts.at(i));
+ const PropertyMetaInfo propInfo = nodeInfo.property(namePart, false);
+
+ if (!propInfo.isValid())
+ break;
+
+ if (i + 1 == partCount)
+ return true;
+
+ QString propertyType = propInfo.type();
+ if (propertyType.right(1) == "*")
+ propertyType = propertyType.left(propertyType.size() - 1).trimmed();
+ nodeInfo = m_data->metaInfo.nodeMetaInfo(propertyType, majorVersion(), minorVersion());
+ if (!nodeInfo.isValid()) {
+ qDebug() << "no type info available for" << propertyType;
+ break;
+ }
+ }
+
+ return false;
+ } else {
+ return m_data->propertyMetaInfoHash.contains(propertyName);
+ }
+}
+
+/*!
+ \brief Returns whether the type has a (inherited or not inherited) property.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::hasProperty(const QString &propertyName, bool resolveDotSyntax) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ if (hasLocalProperty(propertyName, resolveDotSyntax))
+ return true;
+
+ foreach (const NodeMetaInfo &nodeMetaInfo, directSuperClasses()) {
+ if (nodeMetaInfo.hasProperty(propertyName, resolveDotSyntax))
+ return true;
+ }
+
+ return false;
+}
+
+void NodeMetaInfo::addProperty(const PropertyMetaInfo &property)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->propertyMetaInfoHash.insert(property.name(), property);
+}
+
+/*!
+ \brief Returns the name of the qml type.
+
+ This is not necessarily the class name: E.g. the class defining "Item" is QmlGraphicsItem.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+QString NodeMetaInfo::typeName() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->typeName;
+}
+
+/*!
+ \brief Returns the name of the major number of the qml type.
+
+ \throws InvalidMetaInfoException if the object is not valid
+*/
+int NodeMetaInfo::majorVersion() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return 4;
+}
+
+
+/*!
+ \brief Returns the name of the minor number of the qml type to which the type is used.
+
+ \throws InvalidMetaInfoException if the object is not valid
+*/
+int NodeMetaInfo::minorVersion() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return m_data->minorVersion;
+}
+
+bool NodeMetaInfo::hasDefaultProperty() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return m_data->defaultProperty.isNull();
+}
+
+QString NodeMetaInfo::defaultProperty() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ return m_data->defaultProperty;
+}
+
+void NodeMetaInfo::setDefaultProperty(const QString &defaultProperty)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ m_data->defaultProperty = defaultProperty;
+}
+
+void NodeMetaInfo::setMajorVersion(int version)
+{
+ m_data->majorVersion = version;
+}
+
+void NodeMetaInfo::setMinorVersion(int version)
+{
+ m_data->minorVersion = version;
+}
+
+void NodeMetaInfo::setInvalid()
+{
+ if (!isValid())
+ return;
+
+ m_data = 0;
+}
+
+void NodeMetaInfo::setTypeName(const QString &typeName)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->typeName = typeName;
+}
+
+uint qHash(const NodeMetaInfo &nodeMetaInfo)
+{
+ if (!nodeMetaInfo.isValid())
+ return 0;
+ return qHash(nodeMetaInfo.m_data->typeName);
+}
+
+bool operator==(const NodeMetaInfo &firstNodeInfo,
+ const NodeMetaInfo &secondNodeInfo)
+{
+ if (!firstNodeInfo.isValid() || !secondNodeInfo.isValid())
+ return false;
+ return firstNodeInfo.m_data->typeName == secondNodeInfo.m_data->typeName;
+}
+
+/*!
+ \brief Returns whether objects of these type can have children.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::isContainer() const
+{
+ // TODO KAI: Is this too generic?
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->isContainer;
+}
+
+bool NodeMetaInfo::isVisibleToItemLibrary() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->isVisibleToItemLibrary;
+}
+
+void NodeMetaInfo::setIsContainer(bool isContainer)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->isContainer = isContainer;
+}
+
+void NodeMetaInfo::setIsVisibleToItemLibrary(bool isVisibleToItemLibrary)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->isVisibleToItemLibrary = isVisibleToItemLibrary;
+}
+
+QIcon NodeMetaInfo::icon() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->icon;
+}
+
+QString NodeMetaInfo::category() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->category;
+}
+
+void NodeMetaInfo::setIcon(const QIcon &icon)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->icon = icon;
+}
+
+void NodeMetaInfo::setCategory(const QString &category)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->category = category;
+}
+
+/*!
+ \brief Returns whether the type inherits from "QWidget".
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::isWidget() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->metaInfo.isSubclassOf(m_data->typeName, "Qt/QWidget");
+}
+
+/*!
+ \brief Returns whether the type inherits from "QGraphicsWidget".
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::isGraphicsWidget() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->metaInfo.isSubclassOf(m_data->typeName, "Qt/QGraphicsWidget");
+}
+
+/*!
+ \brief Returns whether the type inherits from "QGraphicsObject".
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::isGraphicsObject() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->metaInfo.isSubclassOf(m_data->typeName, "QGraphicsObject");
+}
+
+/*!
+ \brief Returns whether the type inherits from "Item/QmlGraphicsItem".
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::isQmlGraphicsItem() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+
+ if (m_data->isFXItem == Internal::NodeMetaInfoData::Unknown) {
+ m_data->isFXItem = m_data->metaInfo.isSubclassOf(m_data->typeName, "Qt/Item") ? Internal::NodeMetaInfoData::Yes : Internal::NodeMetaInfoData::No;
+ }
+
+ return m_data->isFXItem == Internal::NodeMetaInfoData::Yes;
+}
+
+bool NodeMetaInfo::isComponent() const
+{
+ return !m_data->qmlFile.isEmpty();
+}
+
+/*!
+ \brief Returns whether the type inherits from a type.
+
+ \throws InvalidMetaInfoException if the object is not valid
+ */
+bool NodeMetaInfo::isSubclassOf(const QString &type, int /*majorVersion*/, int /*minorVersion*/) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ return m_data->metaInfo.isSubclassOf(m_data->typeName, type);
+}
+
+void NodeMetaInfo::setQmlFile(const QString &filePath)
+{
+ if (!isValid()) {
+ Q_ASSERT_X(0, Q_FUNC_INFO, "Invalid NodeMetaInfo object");
+ throw InvalidMetaInfoException(__LINE__, __FUNCTION__, __FILE__);
+ }
+ m_data->qmlFile = filePath;
+}
+
+//QDataStream& operator<<(QDataStream& stream, const NodeMetaInfo& nodeMetaInfo)
+//{
+// stream << nodeMetaInfo.typeName();
+// stream << nodeMetaInfo.majorVersion();
+// stream << nodeMetaInfo.minorVersionTo();
+//
+// return stream;
+//}
+//
+//QDataStream& operator>>(QDataStream& stream, NodeMetaInfo& nodeMetaInfo)
+//{
+// QString typeName;
+// int minorVersion;
+// int majorVersion;
+//
+// stream >> minorVersion;
+// stream >> majorVersion;
+// stream >> typeName;
+//
+// nodeMetaInfo = MetaInfo::global().nodeMetaInfo(typeName/*, majorVersion ,minorVersion*/);
+//
+// return stream;
+//}
+
+} // namespace QKineticDesigner
diff --git a/src/shared/qml/metatype/nodemetainfo.h b/src/shared/qml/metatype/nodemetainfo.h
new file mode 100644
index 0000000000..1d1215a90d
--- /dev/null
+++ b/src/shared/qml/metatype/nodemetainfo.h
@@ -0,0 +1,103 @@
+#ifndef NODEMETAINFO_H
+#define NODEMETAINFO_H
+
+#include <qml/qml_global.h>
+
+#include <QList>
+#include <QString>
+#include <QExplicitlySharedDataPointer>
+#include <QIcon>
+
+class QmlContext;
+
+namespace QKineticDesigner {
+
+class MetaInfo;
+
+namespace Internal {
+ class MetaInfoPrivate;
+ class MetaInfoParser;
+ class NodeMetaInfoData;
+ class SubComponentManagerPrivate;
+ class ItemLibraryInfoData;
+}
+
+class PropertyMetaInfo;
+
+class QML_EXPORT NodeMetaInfo
+{
+ friend class QKineticDesigner::MetaInfo;
+ friend class QKineticDesigner::Internal::ItemLibraryInfoData;
+ friend class QKineticDesigner::Internal::MetaInfoPrivate;
+ friend class QKineticDesigner::Internal::MetaInfoParser;
+ friend QML_EXPORT uint qHash(const NodeMetaInfo &nodeMetaInfo);
+ friend QML_EXPORT bool operator ==(const NodeMetaInfo &firstNodeInfo, const NodeMetaInfo &secondNodeInfo);
+
+public:
+ ~NodeMetaInfo();
+
+ NodeMetaInfo(const NodeMetaInfo &other);
+ NodeMetaInfo &operator=(const NodeMetaInfo &other);
+
+ bool isValid() const;
+ MetaInfo metaInfo() const;
+
+ QObject *createInstance(QmlContext *parentContext) const;
+
+ PropertyMetaInfo property(const QString &propertyName, bool resolveDotSyntax = false) const;
+
+ QList<NodeMetaInfo> superClasses() const;
+ QList<NodeMetaInfo> directSuperClasses() const;
+ QHash<QString,PropertyMetaInfo> properties(bool resolveDotSyntax = false) const;
+
+
+ QString typeName() const;
+ int majorVersion() const;
+ int minorVersion() const;
+
+ bool hasDefaultProperty() const;
+ QString defaultProperty() const;
+
+ bool hasProperty(const QString &propertyName, bool resolveDotSyntax = false) const;
+ bool isContainer() const;
+ bool isVisibleToItemLibrary() const;
+
+ bool isWidget() const;
+ bool isGraphicsWidget() const;
+ bool isGraphicsObject() const;
+ bool isQmlGraphicsItem() const;
+ bool isComponent() const;
+ bool isSubclassOf(const QString& type, int majorVersion = 4, int minorVersion = 6) const;
+
+ QIcon icon() const;
+ QString category() const;
+
+private:
+ NodeMetaInfo();
+ NodeMetaInfo(const MetaInfo &metaInfo);
+
+ void setInvalid();
+ void setTypeName(const QString &typeName);
+ void addProperty(const PropertyMetaInfo &property);
+ void setIsContainer(bool isContainer);
+ void setIsVisibleToItemLibrary(bool isVisibleToItemLibrary);
+ void setIcon(const QIcon &icon);
+ void setCategory(const QString &category);
+ void setQmlFile(const QString &filePath);
+ void setDefaultProperty(const QString &defaultProperty);
+ void setMajorVersion(int version);
+ void setMinorVersion(int version);
+
+ bool hasLocalProperty(const QString &propertyName, bool resolveDotSyntax = false) const;
+ QHash<QString,PropertyMetaInfo> dotProperties() const;
+
+private:
+ QExplicitlySharedDataPointer<Internal::NodeMetaInfoData> m_data;
+};
+
+QML_EXPORT uint qHash(const NodeMetaInfo &nodeMetaInfo);
+QML_EXPORT bool operator ==(const NodeMetaInfo &firstNodeInfo,
+ const NodeMetaInfo &secondNodeInfo);
+}
+
+#endif // NODEMETAINFO_H
diff --git a/src/shared/qml/metatype/propertymetainfo.cpp b/src/shared/qml/metatype/propertymetainfo.cpp
new file mode 100644
index 0000000000..fae7fa49be
--- /dev/null
+++ b/src/shared/qml/metatype/propertymetainfo.cpp
@@ -0,0 +1,378 @@
+#include "propertymetainfo.h"
+
+#include <QSharedData>
+
+#include "invalidmetainfoexception.h"
+#include "metainfo.h"
+#include <private/qmlvaluetype_p.h>
+
+namespace QKineticDesigner {
+
+namespace Internal
+{
+
+class PropertyMetaInfoData : public QSharedData
+{
+public:
+ PropertyMetaInfoData()
+ : QSharedData(),
+ isValid(false),
+ readable(false),
+ writeable(false),
+ resettable(false),
+ enumType(false),
+ flagType(false),
+ isVisible(false)
+ {}
+
+ QString name;
+ QString type;
+ int majorVersion;
+ int minorVersion;
+ bool isValid;
+
+ bool readable;
+ bool writeable;
+ bool resettable;
+
+ bool enumType;
+ bool flagType;
+ bool isVisible;
+
+ QHash<QString, QVariant> defaultValueHash;
+};
+
+}
+
+/*!
+\class QKineticDesigner::PropertyMetaInfo
+\ingroup CoreModel
+\brief The PropertyMetaInfo class provides meta information about a qml type property.
+
+A PropertyMetaInfo object can be NodeMetaInfo, or AbstractProperty::metaInfo.
+
+The object can be invalid - you can check this by calling isValid().
+The object is invalid if you ask for meta information for
+an non-existing qml type. Also the node meta info can become invalid
+if the type is deregistered from the meta type system (e.g.
+a sub component qml file is deleted). Trying to call any accessor methods on an invalid
+PropertyMetaInfo object will result in an InvalidMetaInfoException being thrown.
+
+
+\see QKineticDesigner::MetaInfo, QKineticDesigner::NodeMetaInfo, QKineticDesigner::EnumeratorMetaInfo
+*/
+
+PropertyMetaInfo::PropertyMetaInfo()
+ : m_data(new Internal::PropertyMetaInfoData)
+{
+}
+
+PropertyMetaInfo::~PropertyMetaInfo()
+{
+}
+
+/*!
+ \brief Creates a copy of the handle.
+ */
+PropertyMetaInfo::PropertyMetaInfo(const PropertyMetaInfo &other)
+ : m_data(other.m_data)
+{
+}
+
+/*!
+ \brief Copies the handle.
+ */
+PropertyMetaInfo &PropertyMetaInfo::operator=(const PropertyMetaInfo &other)
+{
+ if (this != &other)
+ m_data = other.m_data;
+
+ return *this;
+}
+
+/*!
+ \brief Returns whether the meta information system knows about this property.
+ */
+bool PropertyMetaInfo::isValid() const
+{
+ return m_data->isValid;
+}
+
+/*!
+ \brief Returns the name of the property.
+ */
+QString PropertyMetaInfo::name() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->name;
+}
+
+/*!
+ \brief Returns the type name of the property.
+ */
+QString PropertyMetaInfo::type() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->type;
+}
+
+int PropertyMetaInfo::typeMajorVersion() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->majorVersion;
+}
+
+int PropertyMetaInfo::typeMinorVersion() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->minorVersion;
+}
+
+bool PropertyMetaInfo::isVisibleToPropertyEditor() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->isVisible;
+}
+
+void PropertyMetaInfo::setIsVisibleToPropertyEditor(bool isVisible)
+{
+ m_data->isVisible = isVisible;
+}
+
+/*!
+ \brief Returns the QVariant type of the property.
+ */
+QVariant::Type PropertyMetaInfo::variantTypeId() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ Q_ASSERT(!m_data->type.isEmpty());
+ return QVariant::nameToType(m_data->type.toLatin1().data());
+}
+
+/*!
+ \brief Returns whether the propery is readable.
+ */
+bool PropertyMetaInfo::isReadable() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->readable;
+}
+
+/*!
+ \brief Returns whether the propery is writeable.
+ */
+bool PropertyMetaInfo::isWriteable() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->writeable;
+}
+
+/*!
+ \brief Returns whether the propery is resettable.
+ */
+bool PropertyMetaInfo::isResettable() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->resettable;
+}
+
+/*!
+ \brief Returns whether the propery is complex value type.
+ */
+bool PropertyMetaInfo::isValueType() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+
+ QmlValueType *valueType(QmlValueTypeFactory::valueType(variantTypeId()));
+ return valueType;
+}
+
+/*!
+ \brief Returns whether the propery is a QmlList.
+ */
+bool PropertyMetaInfo::isListProperty() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+
+ return type().contains("QmlList");
+}
+
+/*!
+ \brief Returns whether the propery has sub properties with "." syntax e.g. font
+ */
+bool PropertyMetaInfo::hasDotSubProperties() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+
+ return isValueType() || !isWriteable();
+}
+
+/*!
+ \brief Returns whether the propery stores an enum value.
+ */
+bool PropertyMetaInfo::isEnumType() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->enumType;
+}
+
+/*!
+ \brief Returns whether the propery stores a flag value.
+ */
+bool PropertyMetaInfo::isFlagType() const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+ return m_data->flagType;
+}
+
+/*!
+ \brief Returns a default value if there is one specified, an invalid QVariant otherwise.
+ */
+QVariant PropertyMetaInfo::defaultValue(const NodeMetaInfo &nodeMetaInfoArg) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+
+ QList<NodeMetaInfo> nodeMetaInfoList(nodeMetaInfoArg.superClasses());
+ nodeMetaInfoList.prepend(nodeMetaInfoArg);
+ foreach (const NodeMetaInfo &nodeMetaInfo, nodeMetaInfoList) {
+ if (m_data->defaultValueHash.contains(nodeMetaInfo.typeName()))
+ return m_data->defaultValueHash.value(nodeMetaInfo.typeName());
+ }
+
+ return QVariant();
+}
+
+void PropertyMetaInfo::setName(const QString &name)
+{
+ m_data->name = name;
+}
+
+void PropertyMetaInfo::setType(const QString &type, int majorVersion, int minorVersion)
+{
+ m_data->type = type;
+ m_data->majorVersion = majorVersion;
+ m_data->minorVersion = minorVersion;
+}
+
+void PropertyMetaInfo::setValid(bool isValid)
+{
+ m_data->isValid = isValid;
+}
+
+void PropertyMetaInfo::setReadable(bool isReadable)
+{
+ m_data->readable = isReadable;
+}
+
+void PropertyMetaInfo::setWritable(bool isWritable)
+{
+ m_data->writeable = isWritable;
+}
+
+void PropertyMetaInfo::setResettable(bool isRessetable)
+{
+ m_data->resettable = isRessetable;
+}
+
+void PropertyMetaInfo::setEnumType(bool isEnumType)
+{
+ m_data->enumType = isEnumType;
+}
+
+void PropertyMetaInfo::setFlagType(bool isFlagType)
+{
+ m_data->flagType = isFlagType;
+}
+
+void PropertyMetaInfo::setDefaultValue(const NodeMetaInfo &nodeMetaInfo, const QVariant &value)
+{
+ m_data->defaultValueHash.insert(nodeMetaInfo.typeName(), value);
+}
+
+/*!
+ \brief cast value type of QVariant parameter
+
+ If the type of the passed variant does not correspond to type(), the method tries to convert
+ the value according to QVariant::convert(). Returns a new QVariant with casted value type
+ if successful, an invalid QVariant otherwise.
+
+ \param variant the QVariant to take the value from
+ \returns QVariant with aligned value type, or invalid QVariant
+ */
+QVariant PropertyMetaInfo::castedValue(const QVariant &originalVariant) const
+{
+ if (!isValid()) {
+ Q_ASSERT_X(isValid(), Q_FUNC_INFO, "");
+ throw InvalidMetaInfoException(__LINE__, Q_FUNC_INFO, __FILE__);
+ }
+
+ QVariant variant = originalVariant;
+ if (m_data->enumType) {
+ return variant;
+ }
+
+ QVariant::Type typeId = variantTypeId();
+
+ if (typeId == QVariant::UserType && m_data->type == QLatin1String("QVariant")) {
+ return variant;
+ } else if (variant.type() == QVariant::List && variant.type() == QVariant::List) {
+ // TODO: check the contents of the list
+ return variant;
+ } else if (type() == "var" || type() == "variant") {
+ return variant;
+ } else if (type() == "alias") {
+ // TODO: The Qml compiler resolves the alias type. We probably should do the same.
+ return variant;
+ } else if (variant.convert(typeId)) {
+ return variant;
+ } else {
+ return QVariant();
+ }
+}
+
+}
diff --git a/src/shared/qml/metatype/propertymetainfo.h b/src/shared/qml/metatype/propertymetainfo.h
new file mode 100644
index 0000000000..d24b340b78
--- /dev/null
+++ b/src/shared/qml/metatype/propertymetainfo.h
@@ -0,0 +1,84 @@
+#ifndef PROPERTYMETAINFO_H
+#define PROPERTYMETAINFO_H
+
+#include <qml/qml_global.h>
+
+#include <QString>
+#include <QExplicitlySharedDataPointer>
+#include <QVariant>
+
+namespace QKineticDesigner {
+
+class MetaInfo;
+class NodeMetaInfo;
+
+namespace Internal {
+
+class MetaInfoPrivate;
+class MetaInfoParser;
+class PropertyMetaInfoData;
+
+}
+
+class QML_EXPORT PropertyMetaInfo
+{
+ friend class QKineticDesigner::Internal::MetaInfoPrivate;
+ friend class QKineticDesigner::Internal::MetaInfoParser;
+ friend class QKineticDesigner::MetaInfo;
+ friend class QKineticDesigner::NodeMetaInfo;
+public:
+ PropertyMetaInfo();
+ ~PropertyMetaInfo();
+
+ PropertyMetaInfo(const PropertyMetaInfo &other);
+ PropertyMetaInfo& operator=(const PropertyMetaInfo &other);
+
+ bool isValid() const;
+
+ QString name() const;
+ QString type() const;
+ int typeMajorVersion() const;
+ int typeMinorVersion() const;
+
+ QVariant::Type variantTypeId() const;
+
+ bool isReadable() const;
+ bool isWriteable() const;
+ bool isResettable() const;
+ bool isValueType() const;
+ bool isListProperty() const;
+
+ bool isEnumType() const;
+ bool isFlagType() const;
+
+ QVariant defaultValue(const NodeMetaInfo &nodeMetaInfo) const;
+ bool isVisibleToPropertyEditor() const;
+
+ QVariant castedValue(const QVariant &variant) const;
+
+private:
+ void setName(const QString &name);
+ void setType(const QString &type, int majorVersion, int minorVersion);
+ void setValid(bool isValid);
+
+ void setReadable(bool isReadable);
+ void setWritable(bool isWritable);
+ void setResettable(bool isRessetable);
+
+ void setEnumType(bool isEnumType);
+ void setFlagType(bool isFlagType);
+
+ void setDefaultValue(const NodeMetaInfo &nodeMetaInfo, const QVariant &value);
+ void setIsVisibleToPropertyEditor(bool isVisible);
+
+ bool hasDotSubProperties() const;
+
+
+private:
+ QExplicitlySharedDataPointer<Internal::PropertyMetaInfoData> m_data;
+};
+
+}
+
+
+#endif // PROPERTYMETAINFO_H
diff --git a/src/shared/qml/metatype/qmltypesystem.cpp b/src/shared/qml/metatype/qmltypesystem.cpp
new file mode 100644
index 0000000000..4186151eac
--- /dev/null
+++ b/src/shared/qml/metatype/qmltypesystem.cpp
@@ -0,0 +1,42 @@
+#include "QmlMetaTypeBackend.h"
+#include "qmltypesystem.h"
+
+#ifdef BUILD_DECLARATIVE_BACKEND
+# include "QtDeclarativeMetaTypeBackend.h"
+#endif // BUILD_DECLARATIVE_BACKEND
+
+#include <QDebug>
+
+using namespace Qml;
+using namespace Qml::MetaType;
+
+QmlTypeSystem::QmlTypeSystem()
+{
+#ifdef BUILD_DECLARATIVE_BACKEND
+ backends.append(new Internal::QtDeclarativeMetaTypeBackend(this));
+#endif // BUILD_DECLARATIVE_BACKEND
+}
+
+QmlTypeSystem::~QmlTypeSystem()
+{
+ qDeleteAll(backends);
+}
+
+QList<QmlSymbol *> QmlTypeSystem::availableTypes(const QString &package, int majorVersion, int minorVersion)
+{
+ QList<QmlSymbol *> results;
+
+ foreach (QmlMetaTypeBackend *backend, backends)
+ results.append(backend->availableTypes(package, majorVersion, minorVersion));
+
+ return results;
+}
+
+QmlSymbol *QmlTypeSystem::resolve(const QString &typeName, const QList<PackageInfo> &packages)
+{
+ foreach (QmlMetaTypeBackend *backend, backends)
+ if (QmlSymbol *symbol = backend->resolve(typeName, packages))
+ return symbol;
+
+ return 0;
+}
diff --git a/src/shared/qml/metatype/qmltypesystem.h b/src/shared/qml/metatype/qmltypesystem.h
new file mode 100644
index 0000000000..d12b172686
--- /dev/null
+++ b/src/shared/qml/metatype/qmltypesystem.h
@@ -0,0 +1,34 @@
+#ifndef QMLTYPESYSTEM_H
+#define QMLTYPESYSTEM_H
+
+#include <qml/qml_global.h>
+#include <qml/qmlpackageinfo.h>
+#include <qml/qmlsymbol.h>
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+
+namespace Qml {
+namespace MetaType {
+
+class QmlMetaTypeBackend;
+
+class QML_EXPORT QmlTypeSystem: public QObject
+{
+ Q_OBJECT
+
+public:
+ QmlTypeSystem();
+ virtual ~QmlTypeSystem();
+
+ QList<QmlSymbol *> availableTypes(const QString &package, int majorVersion, int minorVersion);
+ QmlSymbol *resolve(const QString &typeName, const QList<PackageInfo> &packages);
+
+private:
+ QList<QmlMetaTypeBackend *> backends;
+};
+
+} // namespace MetaType
+} // namespace Qml
+
+#endif // QMLTYPESYSTEM_H
diff --git a/src/shared/qml/qml.pri b/src/shared/qml/qml.pri
index 2fa8886672..caafdd10ab 100644
--- a/src/shared/qml/qml.pri
+++ b/src/shared/qml/qml.pri
@@ -7,11 +7,37 @@ HEADERS += \
$$PWD/qml_global.h \
$$PWD/qmlidcollector.h \
$$PWD/qmldocument.h \
- $$PWD/qmlsymbol.h
+ $$PWD/qmlpackageinfo.h \
+ $$PWD/qmlsymbol.h \
+ $$PWD/metatype/QmlMetaTypeBackend.h \
+ $$PWD/metatype/qmltypesystem.h
SOURCES += \
$$PWD/qmlidcollector.cpp \
$$PWD/qmldocument.cpp \
- $$PWD/qmlsymbol.cpp
+ $$PWD/qmlsymbol.cpp \
+ $$PWD/qmlpackageinfo.cpp \
+ $$PWD/metatype/QmlMetaTypeBackend.cpp \
+ $$PWD/metatype/qmltypesystem.cpp
+contains(QT_CONFIG, declarative) {
+ QT += declarative
+ DEFINES += BUILD_DECLARATIVE_BACKEND
+
+ HEADERS += \
+ $$PWD/metatype/metainfo.h \
+ $$PWD/metatype/nodemetainfo.h \
+ $$PWD/metatype/propertymetainfo.h \
+ $$PWD/metatype/QtDeclarativeMetaTypeBackend.h \
+ $$PWD/metatype/invalidmetainfoexception.h \
+ $$PWD/metatype/exception.h
+
+ SOURCES += \
+ $$PWD/metatype/metainfo.cpp \
+ $$PWD/metatype/nodemetainfo.cpp \
+ $$PWD/metatype/propertymetainfo.cpp \
+ $$PWD/metatype/QtDeclarativeMetaTypeBackend.cpp \
+ $$PWD/metatype/invalidmetainfoexception.cpp \
+ $$PWD/metatype/exception.cpp
+}
diff --git a/src/shared/qml/qmldocument.cpp b/src/shared/qml/qmldocument.cpp
index a71152119f..06e1162673 100644
--- a/src/shared/qml/qmldocument.cpp
+++ b/src/shared/qml/qmldocument.cpp
@@ -35,6 +35,7 @@
#include "qmljsnodepool_p.h"
#include "qmljsastfwd_p.h"
+using namespace Qml;
using namespace QmlEditor;
using namespace QmlJS;
@@ -115,7 +116,7 @@ bool QmlDocument::parse()
_symbols.append(new QmlSymbolFromFile(_fileName, iter->member));
Internal::QmlIdCollector collect;
- _ids = collect(this);
+ _ids = collect(*this);
}
return _parsedCorrectly;
diff --git a/src/shared/qml/qmldocument.h b/src/shared/qml/qmldocument.h
index 5797d7299e..c45a3af09d 100644
--- a/src/shared/qml/qmldocument.h
+++ b/src/shared/qml/qmldocument.h
@@ -46,7 +46,7 @@ class QML_EXPORT QmlDocument
public:
typedef QSharedPointer<QmlDocument> Ptr;
typedef QList<QmlDocument::Ptr> PtrList;
- typedef QMap<QString, QmlIdSymbol*> IdTable;
+ typedef QMap<QString, Qml::QmlIdSymbol*> IdTable;
protected:
QmlDocument(const QString &fileName);
@@ -73,8 +73,8 @@ public:
QString path() const { return _path; }
QString componentName() const { return _componentName; }
- QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const;
- QmlSymbol::List symbols() const
+ Qml::QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const;
+ Qml::QmlSymbol::List symbols() const
{ return _symbols; }
private:
@@ -88,7 +88,7 @@ private:
QString _source;
bool _parsedCorrectly;
IdTable _ids;
- QmlSymbol::List _symbols;
+ Qml::QmlSymbol::List _symbols;
};
class QML_EXPORT Snapshot: public QMap<QString, QmlDocument::Ptr>
diff --git a/src/shared/qml/qmlidcollector.cpp b/src/shared/qml/qmlidcollector.cpp
index a06ae2dde3..0b348c5d74 100644
--- a/src/shared/qml/qmlidcollector.cpp
+++ b/src/shared/qml/qmlidcollector.cpp
@@ -6,16 +6,16 @@
using namespace QmlJS;
using namespace QmlJS::AST;
-using namespace QmlEditor;
-using namespace QmlEditor::Internal;
+using namespace Qml;
+using namespace Qml::Internal;
-QMap<QString, QmlIdSymbol*> QmlIdCollector::operator()(QmlDocument *doc)
+QMap<QString, QmlIdSymbol*> QmlIdCollector::operator()(QmlEditor::QmlDocument &doc)
{
- _doc = doc;
+ _doc = &doc;
_ids.clear();
_currentSymbol = 0;
- Node::accept(doc->program(), this);
+ Node::accept(doc.program(), this);
return _ids;
}
diff --git a/src/shared/qml/qmlidcollector.h b/src/shared/qml/qmlidcollector.h
index 0e8c88df3b..5a0a92fb44 100644
--- a/src/shared/qml/qmlidcollector.h
+++ b/src/shared/qml/qmlidcollector.h
@@ -10,13 +10,13 @@
#include <qml/qmldocument.h>
#include <qml/qmlsymbol.h>
-namespace QmlEditor {
+namespace Qml {
namespace Internal {
class QML_EXPORT QmlIdCollector: protected QmlJS::AST::Visitor
{
public:
- QMap<QString, QmlIdSymbol*> operator()(QmlDocument *doc);
+ QMap<QString, Qml::QmlIdSymbol*> operator()(QmlEditor::QmlDocument &doc);
protected:
virtual bool visit(QmlJS::AST::UiArrayBinding *ast);
@@ -25,16 +25,16 @@ protected:
virtual bool visit(QmlJS::AST::UiScriptBinding *ast);
private:
- QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node);
+ Qml::QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node);
void addId(const QString &id, QmlJS::AST::UiScriptBinding *ast);
private:
- QmlDocument *_doc;
- QMap<QString, QmlIdSymbol*> _ids;
- QmlSymbolFromFile *_currentSymbol;
+ QmlEditor::QmlDocument *_doc;
+ QMap<QString, Qml::QmlIdSymbol*> _ids;
+ Qml::QmlSymbolFromFile *_currentSymbol;
};
} // namespace Internal
-} // namespace QmlEditor
+} // namespace Qml
#endif // QMLIDCOLLECTOR_H
diff --git a/src/shared/qml/qmlpackageinfo.cpp b/src/shared/qml/qmlpackageinfo.cpp
new file mode 100644
index 0000000000..d9223877bc
--- /dev/null
+++ b/src/shared/qml/qmlpackageinfo.cpp
@@ -0,0 +1,10 @@
+#include "qmlpackageinfo.h"
+
+using namespace Qml;
+
+PackageInfo::PackageInfo(const QString &name, int majorVersion, int minorVersion):
+ m_name(name),
+ m_majorVersion(majorVersion),
+ m_minorVersion(minorVersion)
+{
+}
diff --git a/src/shared/qml/qmlpackageinfo.h b/src/shared/qml/qmlpackageinfo.h
new file mode 100644
index 0000000000..770606904b
--- /dev/null
+++ b/src/shared/qml/qmlpackageinfo.h
@@ -0,0 +1,32 @@
+#ifndef PACKAGEINFO_H
+#define PACKAGEINFO_H
+
+#include <qml/qml_global.h>
+
+#include <QtCore/QString>
+
+namespace Qml {
+
+class QML_EXPORT PackageInfo
+{
+public:
+ PackageInfo(const QString &name, int majorVersion, int minorVersion);
+
+ QString name() const
+ { return m_name; }
+
+ int majorVersion() const
+ { return m_majorVersion; }
+
+ int minorVersion() const
+ { return m_minorVersion; }
+
+private:
+ QString m_name;
+ int m_majorVersion;
+ int m_minorVersion;
+};
+
+} // namespace Qml
+
+#endif // PACKAGEINFO_H
diff --git a/src/shared/qml/qmlsymbol.cpp b/src/shared/qml/qmlsymbol.cpp
index afd0f7e719..ad8491685b 100644
--- a/src/shared/qml/qmlsymbol.cpp
+++ b/src/shared/qml/qmlsymbol.cpp
@@ -2,13 +2,12 @@
#include "qmljsengine_p.h"
#include "qmlsymbol.h"
-using namespace QmlEditor;
+using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
QmlSymbol::~QmlSymbol()
{
- qDeleteAll(_members);
}
bool QmlSymbol::isBuildInSymbol()
@@ -35,15 +34,17 @@ QmlIdSymbol *QmlSymbol::asIdSymbol()
QmlPropertyDefinitionSymbol *QmlSymbol::asPropertyDefinitionSymbol()
{ return 0; }
-const QmlSymbol::List QmlSymbol::members()
-{ return _members; }
-
QmlBuildInSymbol::~QmlBuildInSymbol()
{}
QmlBuildInSymbol *QmlBuildInSymbol::asBuildInSymbol()
{ return this; }
+QmlSymbolWithMembers::~QmlSymbolWithMembers()
+{ qDeleteAll(_members); }
+
+const QmlSymbol::List QmlSymbolWithMembers::members()
+{ return _members; }
QmlSymbolFromFile::QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node):
_fileName(fileName),
diff --git a/src/shared/qml/qmlsymbol.h b/src/shared/qml/qmlsymbol.h
index 159badf0bb..33561daa06 100644
--- a/src/shared/qml/qmlsymbol.h
+++ b/src/shared/qml/qmlsymbol.h
@@ -1,24 +1,24 @@
#ifndef QMLSYMBOL_H
#define QMLSYMBOL_H
-#include <QList>
-#include <QString>
-
#include <qml/parser/qmljsastfwd_p.h>
#include <qml/qml_global.h>
-namespace QmlEditor {
+#include <QList>
+#include <QString>
+
+namespace Qml {
class QML_EXPORT QmlSymbol
{
public:
- typedef QList<QmlSymbol*> List;
+ typedef QList<QmlSymbol *> List;
public:
- virtual ~QmlSymbol();
+ virtual ~QmlSymbol() = 0;
virtual const QString name() const = 0;
- virtual const List members();
+ virtual const List members() = 0;
bool isBuildInSymbol();
bool isSymbolFromFile();
@@ -29,30 +29,41 @@ public:
virtual class QmlSymbolFromFile *asSymbolFromFile();
virtual class QmlIdSymbol *asIdSymbol();
virtual class QmlPropertyDefinitionSymbol *asPropertyDefinitionSymbol();
-
-protected:
- List _members;
};
class QML_EXPORT QmlBuildInSymbol: public QmlSymbol
{
public:
- QmlBuildInSymbol(const QString &name): _name(name) {}
- virtual ~QmlBuildInSymbol();
+ virtual ~QmlBuildInSymbol() = 0;
virtual QmlBuildInSymbol *asBuildInSymbol();
- virtual const QString name() const
- { return _name; }
+ virtual QmlBuildInSymbol *type() const = 0;
+ virtual List members(bool includeBaseClassMembers) = 0;
+};
- void addMember(QmlBuildInSymbol *symbol)
- { _members.append(symbol); }
+class QML_EXPORT QmlPrimitiveSymbol: public QmlBuildInSymbol
+{
+public:
+ virtual ~QmlPrimitiveSymbol() = 0;
-private:
- QString _name;
+ virtual bool isString() const = 0;
+ virtual bool isNumber() const = 0;
+ virtual bool isObject() const = 0;
+};
+
+class QML_EXPORT QmlSymbolWithMembers: public QmlSymbol
+{
+public:
+ virtual ~QmlSymbolWithMembers() = 0;
+
+ virtual const List members();
+
+protected:
+ List _members;
};
-class QML_EXPORT QmlSymbolFromFile: public QmlSymbol
+class QML_EXPORT QmlSymbolFromFile: public QmlSymbolWithMembers
{
public:
QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node);
@@ -125,6 +136,6 @@ private:
QmlJS::AST::UiPublicMember *propertyNode() const;
};
-} // namespace QmlEditor
+} // namespace Qml
#endif // QMLSYMBOL_H