forked from qt-creator/qt-creator
Added metainfo classes from Bauhaus for use in the QML editor.
This commit is contained in:
@@ -42,14 +42,16 @@
|
|||||||
using namespace QmlEditor;
|
using namespace QmlEditor;
|
||||||
using namespace QmlEditor::Internal;
|
using namespace QmlEditor::Internal;
|
||||||
|
|
||||||
QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent)
|
QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent)
|
||||||
: TextEditor::ICompletionCollector(parent),
|
: TextEditor::ICompletionCollector(parent),
|
||||||
m_modelManager(modelManager),
|
m_modelManager(modelManager),
|
||||||
m_editor(0),
|
m_editor(0),
|
||||||
m_startPosition(0),
|
m_startPosition(0),
|
||||||
m_caseSensitivity(Qt::CaseSensitive)
|
m_caseSensitivity(Qt::CaseSensitive),
|
||||||
|
m_typeSystem(typeSystem)
|
||||||
{
|
{
|
||||||
Q_ASSERT(modelManager);
|
Q_ASSERT(modelManager);
|
||||||
|
Q_ASSERT(typeSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlCodeCompletion::~QmlCodeCompletion()
|
QmlCodeCompletion::~QmlCodeCompletion()
|
||||||
@@ -119,13 +121,13 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
|||||||
cursor.setPosition(pos);
|
cursor.setPosition(pos);
|
||||||
expressionUnderCursor(cursor, qmlDocument);
|
expressionUnderCursor(cursor, qmlDocument);
|
||||||
|
|
||||||
QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot());
|
QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot(), m_typeSystem);
|
||||||
QmlResolveExpression resolver(context);
|
QmlResolveExpression resolver(context);
|
||||||
// qDebug()<<"*** expression under cursor:"<<expressionUnderCursor.expressionNode();
|
// 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";
|
// qDebug()<<"***"<<symbols.size()<<"visible symbols";
|
||||||
|
|
||||||
foreach (QmlSymbol *symbol, symbols) {
|
foreach (Qml::QmlSymbol *symbol, symbols) {
|
||||||
QString word;
|
QString word;
|
||||||
|
|
||||||
if (symbol->isIdSymbol()) {
|
if (symbol->isIdSymbol()) {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#ifndef QMLCODECOMPLETION_H
|
#ifndef QMLCODECOMPLETION_H
|
||||||
#define QMLCODECOMPLETION_H
|
#define QMLCODECOMPLETION_H
|
||||||
|
|
||||||
|
#include <qml/metatype/qmltypesystem.h>
|
||||||
#include <texteditor/icompletioncollector.h>
|
#include <texteditor/icompletioncollector.h>
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
@@ -18,7 +19,7 @@ class QmlCodeCompletion: public TextEditor::ICompletionCollector
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QmlCodeCompletion(QmlModelManagerInterface *modelManager, QObject *parent = 0);
|
QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent = 0);
|
||||||
virtual ~QmlCodeCompletion();
|
virtual ~QmlCodeCompletion();
|
||||||
|
|
||||||
Qt::CaseSensitivity caseSensitivity() const;
|
Qt::CaseSensitivity caseSensitivity() const;
|
||||||
@@ -38,6 +39,7 @@ private:
|
|||||||
int m_startPosition;
|
int m_startPosition;
|
||||||
QList<TextEditor::CompletionItem> m_completions;
|
QList<TextEditor::CompletionItem> m_completions;
|
||||||
Qt::CaseSensitivity m_caseSensitivity;
|
Qt::CaseSensitivity m_caseSensitivity;
|
||||||
|
Qml::MetaType::QmlTypeSystem *m_typeSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#include "qmllookupcontext.h"
|
#include "qmllookupcontext.h"
|
||||||
#include "qmlresolveexpression.h"
|
#include "qmlresolveexpression.h"
|
||||||
|
|
||||||
|
#include <qml/metatype/qmltypesystem.h>
|
||||||
#include <qml/parser/qmljsastvisitor_p.h>
|
#include <qml/parser/qmljsastvisitor_p.h>
|
||||||
#include <qml/parser/qmljsast_p.h>
|
#include <qml/parser/qmljsast_p.h>
|
||||||
#include <qml/parser/qmljsengine_p.h>
|
#include <qml/parser/qmljsengine_p.h>
|
||||||
@@ -68,6 +69,7 @@ enum {
|
|||||||
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 250
|
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 250
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using namespace Qml;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
using namespace QmlJS::AST;
|
using namespace QmlJS::AST;
|
||||||
using namespace SharedTools;
|
using namespace SharedTools;
|
||||||
@@ -378,7 +380,8 @@ ScriptEditorEditable::ScriptEditorEditable(ScriptEditor *editor)
|
|||||||
ScriptEditor::ScriptEditor(QWidget *parent) :
|
ScriptEditor::ScriptEditor(QWidget *parent) :
|
||||||
TextEditor::BaseTextEditor(parent),
|
TextEditor::BaseTextEditor(parent),
|
||||||
m_methodCombo(0),
|
m_methodCombo(0),
|
||||||
m_modelManager(0)
|
m_modelManager(0),
|
||||||
|
m_typeSystem(0)
|
||||||
{
|
{
|
||||||
setParenthesesMatchingEnabled(true);
|
setParenthesesMatchingEnabled(true);
|
||||||
setMarksVisible(true);
|
setMarksVisible(true);
|
||||||
@@ -397,6 +400,7 @@ ScriptEditor::ScriptEditor(QWidget *parent) :
|
|||||||
baseTextDocument()->setSyntaxHighlighter(new QmlHighlighter);
|
baseTextDocument()->setSyntaxHighlighter(new QmlHighlighter);
|
||||||
|
|
||||||
m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>();
|
m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>();
|
||||||
|
m_typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
|
||||||
|
|
||||||
if (m_modelManager) {
|
if (m_modelManager) {
|
||||||
connect(m_modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)),
|
connect(m_modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)),
|
||||||
@@ -768,7 +772,7 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
|
|||||||
QmlExpressionUnderCursor expressionUnderCursor;
|
QmlExpressionUnderCursor expressionUnderCursor;
|
||||||
expressionUnderCursor(expressionCursor, doc);
|
expressionUnderCursor(expressionCursor, doc);
|
||||||
|
|
||||||
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot);
|
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot, m_typeSystem);
|
||||||
QmlResolveExpression resolver(context);
|
QmlResolveExpression resolver(context);
|
||||||
QmlSymbol *symbol = resolver.typeOf(expressionUnderCursor.expressionNode());
|
QmlSymbol *symbol = resolver.typeOf(expressionUnderCursor.expressionNode());
|
||||||
|
|
||||||
|
@@ -43,6 +43,12 @@ namespace Core {
|
|||||||
class ICore;
|
class ICore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Qml {
|
||||||
|
namespace MetaType {
|
||||||
|
class QmlTypeSystem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace QmlEditor {
|
namespace QmlEditor {
|
||||||
|
|
||||||
class QmlModelManagerInterface;
|
class QmlModelManagerInterface;
|
||||||
@@ -146,6 +152,7 @@ private:
|
|||||||
QList<QmlJS::DiagnosticMessage> m_diagnosticMessages;
|
QList<QmlJS::DiagnosticMessage> m_diagnosticMessages;
|
||||||
QmlDocument::Ptr m_document;
|
QmlDocument::Ptr m_document;
|
||||||
QmlModelManagerInterface *m_modelManager;
|
QmlModelManagerInterface *m_modelManager;
|
||||||
|
Qml::MetaType::QmlTypeSystem *m_typeSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -94,6 +94,8 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
|
|||||||
|
|
||||||
m_modelManager = new QmlModelManager(this);
|
m_modelManager = new QmlModelManager(this);
|
||||||
addAutoReleasedObject(m_modelManager);
|
addAutoReleasedObject(m_modelManager);
|
||||||
|
Qml::MetaType::QmlTypeSystem *typeSystem = new Qml::MetaType::QmlTypeSystem;
|
||||||
|
addAutoReleasedObject(typeSystem);
|
||||||
|
|
||||||
QList<int> context;
|
QList<int> context;
|
||||||
context<< core->uniqueIDManager()->uniqueIdentifier(QmlEditor::Constants::C_QMLEDITOR);
|
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);
|
cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION);
|
||||||
contextMenu->addAction(cmd);
|
contextMenu->addAction(cmd);
|
||||||
|
|
||||||
m_completion = new QmlCodeCompletion(m_modelManager);
|
m_completion = new QmlCodeCompletion(m_modelManager, typeSystem);
|
||||||
addAutoReleasedObject(m_completion);
|
addAutoReleasedObject(m_completion);
|
||||||
|
|
||||||
addAutoReleasedObject(new QmlHoverHandler());
|
addAutoReleasedObject(new QmlHoverHandler());
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
using namespace Qml;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
using namespace QmlJS::AST;
|
using namespace QmlJS::AST;
|
||||||
|
|
||||||
@@ -118,7 +119,7 @@ namespace QmlEditor {
|
|||||||
|
|
||||||
virtual bool visit(UiObjectBinding *ast)
|
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);
|
push(ast);
|
||||||
Node::accept(ast->initializer, this);
|
Node::accept(ast->initializer, this);
|
||||||
}
|
}
|
||||||
@@ -128,7 +129,7 @@ namespace QmlEditor {
|
|||||||
|
|
||||||
virtual bool visit(UiObjectDefinition *ast)
|
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);
|
push(ast);
|
||||||
Node::accept(ast->initializer, this);
|
Node::accept(ast->initializer, this);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ public:
|
|||||||
|
|
||||||
void operator()(const QTextCursor &cursor, const QmlDocument::Ptr &doc);
|
void operator()(const QTextCursor &cursor, const QmlDocument::Ptr &doc);
|
||||||
|
|
||||||
QStack<QmlSymbol *> expressionScopes() const
|
QStack<Qml::QmlSymbol *> expressionScopes() const
|
||||||
{ return _expressionScopes; }
|
{ return _expressionScopes; }
|
||||||
|
|
||||||
QmlJS::AST::Node *expressionNode() const
|
QmlJS::AST::Node *expressionNode() const
|
||||||
@@ -45,7 +45,7 @@ private:
|
|||||||
QmlJS::AST::UiObjectMember *tryBinding(const QString &text);
|
QmlJS::AST::UiObjectMember *tryBinding(const QString &text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStack<QmlSymbol *> _expressionScopes;
|
QStack<Qml::QmlSymbol *> _expressionScopes;
|
||||||
QmlJS::AST::Node *_expressionNode;
|
QmlJS::AST::Node *_expressionNode;
|
||||||
int _expressionOffset;
|
int _expressionOffset;
|
||||||
int _expressionLength;
|
int _expressionLength;
|
||||||
|
@@ -52,6 +52,7 @@
|
|||||||
#include <QtHelp/QHelpEngineCore>
|
#include <QtHelp/QHelpEngineCore>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
using namespace Qml;
|
||||||
using namespace QmlEditor;
|
using namespace QmlEditor;
|
||||||
using namespace QmlEditor::Internal;
|
using namespace QmlEditor::Internal;
|
||||||
|
|
||||||
@@ -186,7 +187,9 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
|||||||
QmlExpressionUnderCursor expressionUnderCursor;
|
QmlExpressionUnderCursor expressionUnderCursor;
|
||||||
expressionUnderCursor(tc, doc);
|
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);
|
QmlResolveExpression resolver(context);
|
||||||
QmlSymbol *resolvedSymbol = resolver.typeOf(expressionUnderCursor.expressionNode());
|
QmlSymbol *resolvedSymbol = resolver.typeOf(expressionUnderCursor.expressionNode());
|
||||||
|
|
||||||
|
@@ -2,11 +2,14 @@
|
|||||||
#include "qmllookupcontext.h"
|
#include "qmllookupcontext.h"
|
||||||
#include "qmlresolveexpression.h"
|
#include "qmlresolveexpression.h"
|
||||||
|
|
||||||
|
#include <qml/metatype/qmltypesystem.h>
|
||||||
#include <qml/parser/qmljsast_p.h>
|
#include <qml/parser/qmljsast_p.h>
|
||||||
#include <qml/parser/qmljsengine_p.h>
|
#include <qml/parser/qmljsengine_p.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
using namespace Qml;
|
||||||
|
using namespace Qml::MetaType;
|
||||||
using namespace QmlEditor;
|
using namespace QmlEditor;
|
||||||
using namespace QmlEditor::Internal;
|
using namespace QmlEditor::Internal;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
@@ -14,11 +17,14 @@ using namespace QmlJS::AST;
|
|||||||
|
|
||||||
QmlLookupContext::QmlLookupContext(const QStack<QmlSymbol *> &scopes,
|
QmlLookupContext::QmlLookupContext(const QStack<QmlSymbol *> &scopes,
|
||||||
const QmlDocument::Ptr &doc,
|
const QmlDocument::Ptr &doc,
|
||||||
const Snapshot &snapshot):
|
const Snapshot &snapshot,
|
||||||
|
QmlTypeSystem *typeSystem):
|
||||||
_scopes(scopes),
|
_scopes(scopes),
|
||||||
_doc(doc),
|
_doc(doc),
|
||||||
_snapshot(snapshot)
|
_snapshot(snapshot),
|
||||||
|
m_typeSystem(typeSystem)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(typeSystem != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int findFirstQmlObjectScope(const QStack<QmlSymbol*> &scopes, int startIdx)
|
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);
|
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)
|
QmlSymbol *QmlLookupContext::resolveBuildinType(const QString &name)
|
||||||
{
|
{
|
||||||
// FIXME: use a REAL mete-type system here!
|
QList<Qml::PackageInfo> packages;
|
||||||
|
// FIXME:
|
||||||
if (name == "Rectangle") {
|
packages.append(PackageInfo("Qt", 4, 6));
|
||||||
QmlBuildInSymbol *rectSymbol = new QmlBuildInSymbol(name);
|
return m_typeSystem->resolve(name, packages);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName)
|
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName)
|
||||||
@@ -270,7 +184,11 @@ QList<QmlSymbol*> QmlLookupContext::visibleSymbolsInScope()
|
|||||||
if (!_scopes.isEmpty()) {
|
if (!_scopes.isEmpty()) {
|
||||||
QmlSymbol *scope = _scopes.top();
|
QmlSymbol *scope = _scopes.top();
|
||||||
|
|
||||||
|
// add members defined in this symbol:
|
||||||
result.append(scope->members());
|
result.append(scope->members());
|
||||||
|
|
||||||
|
// add the members of the type of this scope (= object):
|
||||||
|
result.append(expandType(scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -301,9 +219,27 @@ QList<QmlSymbol*> QmlLookupContext::visibleTypes()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle Qt imports, hack for now:
|
result.append(m_typeSystem->availableTypes("Qt", 4, 6));
|
||||||
foreach (const QString &name, qmlMetaTypes)
|
|
||||||
result.append(resolveBuildinType(name));
|
|
||||||
|
|
||||||
return result;
|
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*>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#ifndef QMLLOOKUPCONTEXT_H
|
#ifndef QMLLOOKUPCONTEXT_H
|
||||||
#define QMLLOOKUPCONTEXT_H
|
#define QMLLOOKUPCONTEXT_H
|
||||||
|
|
||||||
|
#include <qml/metatype/qmltypesystem.h>
|
||||||
#include <qml/parser/qmljsastvisitor_p.h>
|
#include <qml/parser/qmljsastvisitor_p.h>
|
||||||
#include <qml/qmldocument.h>
|
#include <qml/qmldocument.h>
|
||||||
#include <qml/qmlsymbol.h>
|
#include <qml/qmlsymbol.h>
|
||||||
@@ -13,33 +14,37 @@ namespace Internal {
|
|||||||
class QmlLookupContext
|
class QmlLookupContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlLookupContext(const QStack<QmlSymbol *> &scopes,
|
QmlLookupContext(const QStack<Qml::QmlSymbol *> &scopes,
|
||||||
const QmlDocument::Ptr &doc,
|
const QmlDocument::Ptr &doc,
|
||||||
const Snapshot &snapshot);
|
const Snapshot &snapshot,
|
||||||
|
Qml::MetaType::QmlTypeSystem *typeSystem);
|
||||||
|
|
||||||
QmlSymbol *resolve(const QString &name);
|
Qml::QmlSymbol *resolve(const QString &name);
|
||||||
QmlSymbol *resolveType(const QString &name)
|
Qml::QmlSymbol *resolveType(const QString &name)
|
||||||
{ return resolveType(name, _doc->fileName()); }
|
{ return resolveType(name, _doc->fileName()); }
|
||||||
QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
|
Qml::QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
|
||||||
{ return resolveType(toString(name), _doc->fileName()); }
|
{ return resolveType(toString(name), _doc->fileName()); }
|
||||||
|
|
||||||
QmlDocument::Ptr document() const
|
QmlDocument::Ptr document() const
|
||||||
{ return _doc; }
|
{ return _doc; }
|
||||||
|
|
||||||
QList<QmlSymbol*> visibleSymbolsInScope();
|
QList<Qml::QmlSymbol*> visibleSymbolsInScope();
|
||||||
QList<QmlSymbol*> visibleTypes();
|
QList<Qml::QmlSymbol*> visibleTypes();
|
||||||
|
|
||||||
|
QList<Qml::QmlSymbol*> expandType(Qml::QmlSymbol *symbol);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QmlSymbol *resolveType(const QString &name, const QString &fileName);
|
Qml::QmlSymbol *resolveType(const QString &name, const QString &fileName);
|
||||||
QmlSymbol *resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName);
|
Qml::QmlSymbol *resolveProperty(const QString &name, Qml::QmlSymbol *scope, const QString &fileName);
|
||||||
QmlSymbol *resolveBuildinType(const QString &name);
|
Qml::QmlSymbol *resolveBuildinType(const QString &name);
|
||||||
|
|
||||||
static QString toString(QmlJS::AST::UiQualifiedId *id);
|
static QString toString(QmlJS::AST::UiQualifiedId *id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStack<QmlSymbol *> _scopes;
|
QStack<Qml::QmlSymbol *> _scopes;
|
||||||
QmlDocument::Ptr _doc;
|
QmlDocument::Ptr _doc;
|
||||||
Snapshot _snapshot;
|
Snapshot _snapshot;
|
||||||
|
Qml::MetaType::QmlTypeSystem *m_typeSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
|
|
||||||
#include <qml/qmldocument.h>
|
#include <qml/qmldocument.h>
|
||||||
|
#include <qml/metatype/qmltypesystem.h>
|
||||||
|
|
||||||
namespace QmlEditor {
|
namespace QmlEditor {
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include <qml/parser/qmljsast_p.h>
|
#include <qml/parser/qmljsast_p.h>
|
||||||
#include <qml/parser/qmljsengine_p.h>
|
#include <qml/parser/qmljsengine_p.h>
|
||||||
|
|
||||||
|
using namespace Qml;
|
||||||
using namespace QmlEditor;
|
using namespace QmlEditor;
|
||||||
using namespace QmlEditor::Internal;
|
using namespace QmlEditor::Internal;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
@@ -16,8 +17,7 @@ QmlResolveExpression::QmlResolveExpression(const QmlLookupContext &context)
|
|||||||
QmlSymbol *QmlResolveExpression::typeOf(Node *node)
|
QmlSymbol *QmlResolveExpression::typeOf(Node *node)
|
||||||
{
|
{
|
||||||
QmlSymbol *previousValue = switchValue(0);
|
QmlSymbol *previousValue = switchValue(0);
|
||||||
if (node)
|
Node::accept(node, this);
|
||||||
node->accept(this);
|
|
||||||
return switchValue(previousValue);
|
return switchValue(previousValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,13 +14,13 @@ class QmlResolveExpression: protected QmlJS::AST::Visitor
|
|||||||
public:
|
public:
|
||||||
QmlResolveExpression(const QmlLookupContext &context);
|
QmlResolveExpression(const QmlLookupContext &context);
|
||||||
|
|
||||||
QmlSymbol *typeOf(QmlJS::AST::Node *node);
|
Qml::QmlSymbol *typeOf(QmlJS::AST::Node *node);
|
||||||
QList<QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
|
QList<Qml::QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using QmlJS::AST::Visitor::visit;
|
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::FieldMemberExpression *ast);
|
||||||
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
|
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
|
||||||
@@ -28,7 +28,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QmlLookupContext _context;
|
QmlLookupContext _context;
|
||||||
QmlSymbol *_value;
|
Qml::QmlSymbol *_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
14
src/shared/qml/metatype/QmlMetaTypeBackend.cpp
Normal file
14
src/shared/qml/metatype/QmlMetaTypeBackend.cpp
Normal file
@@ -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()
|
||||||
|
{
|
||||||
|
}
|
33
src/shared/qml/metatype/QmlMetaTypeBackend.h
Normal file
33
src/shared/qml/metatype/QmlMetaTypeBackend.h
Normal file
@@ -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
|
232
src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.cpp
Normal file
232
src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.cpp
Normal file
@@ -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);
|
||||||
|
}
|
47
src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.h
Normal file
47
src/shared/qml/metatype/QtDeclarativeMetaTypeBackend.h
Normal file
@@ -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
|
163
src/shared/qml/metatype/exception.cpp
Normal file
163
src/shared/qml/metatype/exception.cpp
Normal file
@@ -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
|
||||||
|
*/
|
||||||
|
}
|
42
src/shared/qml/metatype/exception.h
Normal file
42
src/shared/qml/metatype/exception.h
Normal file
@@ -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
|
35
src/shared/qml/metatype/invalidmetainfoexception.cpp
Normal file
35
src/shared/qml/metatype/invalidmetainfoexception.cpp
Normal file
@@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/shared/qml/metatype/invalidmetainfoexception.h
Normal file
21
src/shared/qml/metatype/invalidmetainfoexception.h
Normal file
@@ -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
|
461
src/shared/qml/metatype/metainfo.cpp
Normal file
461
src/shared/qml/metatype/metainfo.cpp
Normal file
@@ -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
|
83
src/shared/qml/metatype/metainfo.h
Normal file
83
src/shared/qml/metatype/metainfo.h
Normal file
@@ -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
|
695
src/shared/qml/metatype/nodemetainfo.cpp
Normal file
695
src/shared/qml/metatype/nodemetainfo.cpp
Normal file
@@ -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
|
103
src/shared/qml/metatype/nodemetainfo.h
Normal file
103
src/shared/qml/metatype/nodemetainfo.h
Normal file
@@ -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
|
378
src/shared/qml/metatype/propertymetainfo.cpp
Normal file
378
src/shared/qml/metatype/propertymetainfo.cpp
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
84
src/shared/qml/metatype/propertymetainfo.h
Normal file
84
src/shared/qml/metatype/propertymetainfo.h
Normal file
@@ -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
|
42
src/shared/qml/metatype/qmltypesystem.cpp
Normal file
42
src/shared/qml/metatype/qmltypesystem.cpp
Normal file
@@ -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;
|
||||||
|
}
|
34
src/shared/qml/metatype/qmltypesystem.h
Normal file
34
src/shared/qml/metatype/qmltypesystem.h
Normal file
@@ -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
|
@@ -7,11 +7,37 @@ HEADERS += \
|
|||||||
$$PWD/qml_global.h \
|
$$PWD/qml_global.h \
|
||||||
$$PWD/qmlidcollector.h \
|
$$PWD/qmlidcollector.h \
|
||||||
$$PWD/qmldocument.h \
|
$$PWD/qmldocument.h \
|
||||||
$$PWD/qmlsymbol.h
|
$$PWD/qmlpackageinfo.h \
|
||||||
|
$$PWD/qmlsymbol.h \
|
||||||
|
$$PWD/metatype/QmlMetaTypeBackend.h \
|
||||||
|
$$PWD/metatype/qmltypesystem.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/qmlidcollector.cpp \
|
$$PWD/qmlidcollector.cpp \
|
||||||
$$PWD/qmldocument.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
|
||||||
|
}
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "qmljsnodepool_p.h"
|
#include "qmljsnodepool_p.h"
|
||||||
#include "qmljsastfwd_p.h"
|
#include "qmljsastfwd_p.h"
|
||||||
|
|
||||||
|
using namespace Qml;
|
||||||
using namespace QmlEditor;
|
using namespace QmlEditor;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ bool QmlDocument::parse()
|
|||||||
_symbols.append(new QmlSymbolFromFile(_fileName, iter->member));
|
_symbols.append(new QmlSymbolFromFile(_fileName, iter->member));
|
||||||
|
|
||||||
Internal::QmlIdCollector collect;
|
Internal::QmlIdCollector collect;
|
||||||
_ids = collect(this);
|
_ids = collect(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _parsedCorrectly;
|
return _parsedCorrectly;
|
||||||
|
@@ -46,7 +46,7 @@ class QML_EXPORT QmlDocument
|
|||||||
public:
|
public:
|
||||||
typedef QSharedPointer<QmlDocument> Ptr;
|
typedef QSharedPointer<QmlDocument> Ptr;
|
||||||
typedef QList<QmlDocument::Ptr> PtrList;
|
typedef QList<QmlDocument::Ptr> PtrList;
|
||||||
typedef QMap<QString, QmlIdSymbol*> IdTable;
|
typedef QMap<QString, Qml::QmlIdSymbol*> IdTable;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QmlDocument(const QString &fileName);
|
QmlDocument(const QString &fileName);
|
||||||
@@ -73,8 +73,8 @@ public:
|
|||||||
QString path() const { return _path; }
|
QString path() const { return _path; }
|
||||||
QString componentName() const { return _componentName; }
|
QString componentName() const { return _componentName; }
|
||||||
|
|
||||||
QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const;
|
Qml::QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const;
|
||||||
QmlSymbol::List symbols() const
|
Qml::QmlSymbol::List symbols() const
|
||||||
{ return _symbols; }
|
{ return _symbols; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -88,7 +88,7 @@ private:
|
|||||||
QString _source;
|
QString _source;
|
||||||
bool _parsedCorrectly;
|
bool _parsedCorrectly;
|
||||||
IdTable _ids;
|
IdTable _ids;
|
||||||
QmlSymbol::List _symbols;
|
Qml::QmlSymbol::List _symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_EXPORT Snapshot: public QMap<QString, QmlDocument::Ptr>
|
class QML_EXPORT Snapshot: public QMap<QString, QmlDocument::Ptr>
|
||||||
|
@@ -6,16 +6,16 @@
|
|||||||
|
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
using namespace QmlJS::AST;
|
using namespace QmlJS::AST;
|
||||||
using namespace QmlEditor;
|
using namespace Qml;
|
||||||
using namespace QmlEditor::Internal;
|
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();
|
_ids.clear();
|
||||||
_currentSymbol = 0;
|
_currentSymbol = 0;
|
||||||
|
|
||||||
Node::accept(doc->program(), this);
|
Node::accept(doc.program(), this);
|
||||||
|
|
||||||
return _ids;
|
return _ids;
|
||||||
}
|
}
|
||||||
|
@@ -10,13 +10,13 @@
|
|||||||
#include <qml/qmldocument.h>
|
#include <qml/qmldocument.h>
|
||||||
#include <qml/qmlsymbol.h>
|
#include <qml/qmlsymbol.h>
|
||||||
|
|
||||||
namespace QmlEditor {
|
namespace Qml {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class QML_EXPORT QmlIdCollector: protected QmlJS::AST::Visitor
|
class QML_EXPORT QmlIdCollector: protected QmlJS::AST::Visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QMap<QString, QmlIdSymbol*> operator()(QmlDocument *doc);
|
QMap<QString, Qml::QmlIdSymbol*> operator()(QmlEditor::QmlDocument &doc);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool visit(QmlJS::AST::UiArrayBinding *ast);
|
virtual bool visit(QmlJS::AST::UiArrayBinding *ast);
|
||||||
@@ -25,16 +25,16 @@ protected:
|
|||||||
virtual bool visit(QmlJS::AST::UiScriptBinding *ast);
|
virtual bool visit(QmlJS::AST::UiScriptBinding *ast);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node);
|
Qml::QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node);
|
||||||
void addId(const QString &id, QmlJS::AST::UiScriptBinding *ast);
|
void addId(const QString &id, QmlJS::AST::UiScriptBinding *ast);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QmlDocument *_doc;
|
QmlEditor::QmlDocument *_doc;
|
||||||
QMap<QString, QmlIdSymbol*> _ids;
|
QMap<QString, Qml::QmlIdSymbol*> _ids;
|
||||||
QmlSymbolFromFile *_currentSymbol;
|
Qml::QmlSymbolFromFile *_currentSymbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace QmlEditor
|
} // namespace Qml
|
||||||
|
|
||||||
#endif // QMLIDCOLLECTOR_H
|
#endif // QMLIDCOLLECTOR_H
|
||||||
|
10
src/shared/qml/qmlpackageinfo.cpp
Normal file
10
src/shared/qml/qmlpackageinfo.cpp
Normal file
@@ -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)
|
||||||
|
{
|
||||||
|
}
|
32
src/shared/qml/qmlpackageinfo.h
Normal file
32
src/shared/qml/qmlpackageinfo.h
Normal file
@@ -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
|
@@ -2,13 +2,12 @@
|
|||||||
#include "qmljsengine_p.h"
|
#include "qmljsengine_p.h"
|
||||||
#include "qmlsymbol.h"
|
#include "qmlsymbol.h"
|
||||||
|
|
||||||
using namespace QmlEditor;
|
using namespace Qml;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
using namespace QmlJS::AST;
|
using namespace QmlJS::AST;
|
||||||
|
|
||||||
QmlSymbol::~QmlSymbol()
|
QmlSymbol::~QmlSymbol()
|
||||||
{
|
{
|
||||||
qDeleteAll(_members);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QmlSymbol::isBuildInSymbol()
|
bool QmlSymbol::isBuildInSymbol()
|
||||||
@@ -35,15 +34,17 @@ QmlIdSymbol *QmlSymbol::asIdSymbol()
|
|||||||
QmlPropertyDefinitionSymbol *QmlSymbol::asPropertyDefinitionSymbol()
|
QmlPropertyDefinitionSymbol *QmlSymbol::asPropertyDefinitionSymbol()
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
const QmlSymbol::List QmlSymbol::members()
|
|
||||||
{ return _members; }
|
|
||||||
|
|
||||||
QmlBuildInSymbol::~QmlBuildInSymbol()
|
QmlBuildInSymbol::~QmlBuildInSymbol()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QmlBuildInSymbol *QmlBuildInSymbol::asBuildInSymbol()
|
QmlBuildInSymbol *QmlBuildInSymbol::asBuildInSymbol()
|
||||||
{ return this; }
|
{ return this; }
|
||||||
|
|
||||||
|
QmlSymbolWithMembers::~QmlSymbolWithMembers()
|
||||||
|
{ qDeleteAll(_members); }
|
||||||
|
|
||||||
|
const QmlSymbol::List QmlSymbolWithMembers::members()
|
||||||
|
{ return _members; }
|
||||||
|
|
||||||
QmlSymbolFromFile::QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node):
|
QmlSymbolFromFile::QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node):
|
||||||
_fileName(fileName),
|
_fileName(fileName),
|
||||||
|
@@ -1,24 +1,24 @@
|
|||||||
#ifndef QMLSYMBOL_H
|
#ifndef QMLSYMBOL_H
|
||||||
#define QMLSYMBOL_H
|
#define QMLSYMBOL_H
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include <qml/parser/qmljsastfwd_p.h>
|
#include <qml/parser/qmljsastfwd_p.h>
|
||||||
#include <qml/qml_global.h>
|
#include <qml/qml_global.h>
|
||||||
|
|
||||||
namespace QmlEditor {
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Qml {
|
||||||
|
|
||||||
class QML_EXPORT QmlSymbol
|
class QML_EXPORT QmlSymbol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef QList<QmlSymbol*> List;
|
typedef QList<QmlSymbol *> List;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~QmlSymbol();
|
virtual ~QmlSymbol() = 0;
|
||||||
|
|
||||||
virtual const QString name() const = 0;
|
virtual const QString name() const = 0;
|
||||||
virtual const List members();
|
virtual const List members() = 0;
|
||||||
|
|
||||||
bool isBuildInSymbol();
|
bool isBuildInSymbol();
|
||||||
bool isSymbolFromFile();
|
bool isSymbolFromFile();
|
||||||
@@ -29,30 +29,41 @@ public:
|
|||||||
virtual class QmlSymbolFromFile *asSymbolFromFile();
|
virtual class QmlSymbolFromFile *asSymbolFromFile();
|
||||||
virtual class QmlIdSymbol *asIdSymbol();
|
virtual class QmlIdSymbol *asIdSymbol();
|
||||||
virtual class QmlPropertyDefinitionSymbol *asPropertyDefinitionSymbol();
|
virtual class QmlPropertyDefinitionSymbol *asPropertyDefinitionSymbol();
|
||||||
|
|
||||||
protected:
|
|
||||||
List _members;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_EXPORT QmlBuildInSymbol: public QmlSymbol
|
class QML_EXPORT QmlBuildInSymbol: public QmlSymbol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlBuildInSymbol(const QString &name): _name(name) {}
|
virtual ~QmlBuildInSymbol() = 0;
|
||||||
virtual ~QmlBuildInSymbol();
|
|
||||||
|
|
||||||
virtual QmlBuildInSymbol *asBuildInSymbol();
|
virtual QmlBuildInSymbol *asBuildInSymbol();
|
||||||
|
|
||||||
virtual const QString name() const
|
virtual QmlBuildInSymbol *type() const = 0;
|
||||||
{ return _name; }
|
virtual List members(bool includeBaseClassMembers) = 0;
|
||||||
|
|
||||||
void addMember(QmlBuildInSymbol *symbol)
|
|
||||||
{ _members.append(symbol); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString _name;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_EXPORT QmlSymbolFromFile: public QmlSymbol
|
class QML_EXPORT QmlPrimitiveSymbol: public QmlBuildInSymbol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~QmlPrimitiveSymbol() = 0;
|
||||||
|
|
||||||
|
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 QmlSymbolWithMembers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node);
|
QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node);
|
||||||
@@ -125,6 +136,6 @@ private:
|
|||||||
QmlJS::AST::UiPublicMember *propertyNode() const;
|
QmlJS::AST::UiPublicMember *propertyNode() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlEditor
|
} // namespace Qml
|
||||||
|
|
||||||
#endif // QMLSYMBOL_H
|
#endif // QMLSYMBOL_H
|
||||||
|
Reference in New Issue
Block a user