Added metainfo classes from Bauhaus for use in the QML editor.

This commit is contained in:
Erik Verbruggen
2009-12-07 16:57:31 +01:00
parent 5a0b7f8ec8
commit 96e5cae4c8
38 changed files with 2689 additions and 178 deletions

View File

@@ -42,14 +42,16 @@
using namespace QmlEditor;
using namespace QmlEditor::Internal;
QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent)
QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent)
: TextEditor::ICompletionCollector(parent),
m_modelManager(modelManager),
m_editor(0),
m_startPosition(0),
m_caseSensitivity(Qt::CaseSensitive)
m_caseSensitivity(Qt::CaseSensitive),
m_typeSystem(typeSystem)
{
Q_ASSERT(modelManager);
Q_ASSERT(typeSystem);
}
QmlCodeCompletion::~QmlCodeCompletion()
@@ -119,13 +121,13 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
cursor.setPosition(pos);
expressionUnderCursor(cursor, qmlDocument);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot());
QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot(), m_typeSystem);
QmlResolveExpression resolver(context);
// qDebug()<<"*** expression under cursor:"<<expressionUnderCursor.expressionNode();
QList<QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());
QList<Qml::QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());
// qDebug()<<"***"<<symbols.size()<<"visible symbols";
foreach (QmlSymbol *symbol, symbols) {
foreach (Qml::QmlSymbol *symbol, symbols) {
QString word;
if (symbol->isIdSymbol()) {

View File

@@ -1,6 +1,7 @@
#ifndef QMLCODECOMPLETION_H
#define QMLCODECOMPLETION_H
#include <qml/metatype/qmltypesystem.h>
#include <texteditor/icompletioncollector.h>
namespace TextEditor {
@@ -18,7 +19,7 @@ class QmlCodeCompletion: public TextEditor::ICompletionCollector
Q_OBJECT
public:
QmlCodeCompletion(QmlModelManagerInterface *modelManager, QObject *parent = 0);
QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent = 0);
virtual ~QmlCodeCompletion();
Qt::CaseSensitivity caseSensitivity() const;
@@ -38,6 +39,7 @@ private:
int m_startPosition;
QList<TextEditor::CompletionItem> m_completions;
Qt::CaseSensitivity m_caseSensitivity;
Qml::MetaType::QmlTypeSystem *m_typeSystem;
};

View File

@@ -37,6 +37,7 @@
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsastvisitor_p.h>
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
@@ -68,6 +69,7 @@ enum {
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 250
};
using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
using namespace SharedTools;
@@ -378,7 +380,8 @@ ScriptEditorEditable::ScriptEditorEditable(ScriptEditor *editor)
ScriptEditor::ScriptEditor(QWidget *parent) :
TextEditor::BaseTextEditor(parent),
m_methodCombo(0),
m_modelManager(0)
m_modelManager(0),
m_typeSystem(0)
{
setParenthesesMatchingEnabled(true);
setMarksVisible(true);
@@ -397,6 +400,7 @@ ScriptEditor::ScriptEditor(QWidget *parent) :
baseTextDocument()->setSyntaxHighlighter(new QmlHighlighter);
m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>();
m_typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
if (m_modelManager) {
connect(m_modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)),
@@ -768,7 +772,7 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
QmlExpressionUnderCursor expressionUnderCursor;
expressionUnderCursor(expressionCursor, doc);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot, m_typeSystem);
QmlResolveExpression resolver(context);
QmlSymbol *symbol = resolver.typeOf(expressionUnderCursor.expressionNode());

View File

@@ -43,6 +43,12 @@ namespace Core {
class ICore;
}
namespace Qml {
namespace MetaType {
class QmlTypeSystem;
}
}
namespace QmlEditor {
class QmlModelManagerInterface;
@@ -146,6 +152,7 @@ private:
QList<QmlJS::DiagnosticMessage> m_diagnosticMessages;
QmlDocument::Ptr m_document;
QmlModelManagerInterface *m_modelManager;
Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
} // namespace Internal

View File

@@ -94,6 +94,8 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
m_modelManager = new QmlModelManager(this);
addAutoReleasedObject(m_modelManager);
Qml::MetaType::QmlTypeSystem *typeSystem = new Qml::MetaType::QmlTypeSystem;
addAutoReleasedObject(typeSystem);
QList<int> context;
context<< core->uniqueIDManager()->uniqueIdentifier(QmlEditor::Constants::C_QMLEDITOR);
@@ -122,7 +124,7 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION);
contextMenu->addAction(cmd);
m_completion = new QmlCodeCompletion(m_modelManager);
m_completion = new QmlCodeCompletion(m_modelManager, typeSystem);
addAutoReleasedObject(m_completion);
addAutoReleasedObject(new QmlHoverHandler());

View File

@@ -9,6 +9,7 @@
#include <QDebug>
using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
@@ -118,7 +119,7 @@ namespace QmlEditor {
virtual bool visit(UiObjectBinding *ast)
{
if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) {
if (ast->initializer && ast->initializer->lbraceToken.offset < _pos && _pos <= ast->initializer->rbraceToken.end()) {
push(ast);
Node::accept(ast->initializer, this);
}
@@ -128,7 +129,7 @@ namespace QmlEditor {
virtual bool visit(UiObjectDefinition *ast)
{
if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) {
if (ast->initializer && ast->initializer->lbraceToken.offset < _pos && _pos <= ast->initializer->rbraceToken.end()) {
push(ast);
Node::accept(ast->initializer, this);
}

View File

@@ -26,7 +26,7 @@ public:
void operator()(const QTextCursor &cursor, const QmlDocument::Ptr &doc);
QStack<QmlSymbol *> expressionScopes() const
QStack<Qml::QmlSymbol *> expressionScopes() const
{ return _expressionScopes; }
QmlJS::AST::Node *expressionNode() const
@@ -45,7 +45,7 @@ private:
QmlJS::AST::UiObjectMember *tryBinding(const QString &text);
private:
QStack<QmlSymbol *> _expressionScopes;
QStack<Qml::QmlSymbol *> _expressionScopes;
QmlJS::AST::Node *_expressionNode;
int _expressionOffset;
int _expressionLength;

View File

@@ -52,6 +52,7 @@
#include <QtHelp/QHelpEngineCore>
using namespace Core;
using namespace Qml;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
@@ -186,7 +187,9 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
QmlExpressionUnderCursor expressionUnderCursor;
expressionUnderCursor(tc, doc);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot());
Qml::MetaType::QmlTypeSystem *typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot(), typeSystem);
QmlResolveExpression resolver(context);
QmlSymbol *resolvedSymbol = resolver.typeOf(expressionUnderCursor.expressionNode());

View File

@@ -2,11 +2,14 @@
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
#include <QDebug>
using namespace Qml;
using namespace Qml::MetaType;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace QmlJS;
@@ -14,11 +17,14 @@ using namespace QmlJS::AST;
QmlLookupContext::QmlLookupContext(const QStack<QmlSymbol *> &scopes,
const QmlDocument::Ptr &doc,
const Snapshot &snapshot):
const Snapshot &snapshot,
QmlTypeSystem *typeSystem):
_scopes(scopes),
_doc(doc),
_snapshot(snapshot)
_snapshot(snapshot),
m_typeSystem(typeSystem)
{
Q_ASSERT(typeSystem != 0);
}
static inline int findFirstQmlObjectScope(const QStack<QmlSymbol*> &scopes, int startIdx)
@@ -114,104 +120,12 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fil
return resolveBuildinType(name);
}
// FIXME: use a REAL mete-type system here!
static QSet<QString> qmlMetaTypes = QSet<QString>()
<< QLatin1String("AnchorChanges")
<< QLatin1String("AnimatedImage")
<< QLatin1String("Animation")
<< QLatin1String("Behavior")
<< QLatin1String("Binding")
<< QLatin1String("BorderImage")
<< QLatin1String("ColorAnimation")
<< QLatin1String("Column")
<< QLatin1String("Component")
<< QLatin1String("Connection")
<< QLatin1String("DateTimeFormatter")
<< QLatin1String("EaseFollow")
<< QLatin1String("Flickable")
<< QLatin1String("Flipable")
<< QLatin1String("FocusPanel")
<< QLatin1String("FocusScope")
<< QLatin1String("FolderListModel")
<< QLatin1String("FontLoader")
<< QLatin1String("Gradient")
<< QLatin1String("GradientStop")
<< QLatin1String("GraphicsObjectContainer")
<< QLatin1String("Grid")
<< QLatin1String("GridView")
<< QLatin1String("Image")
<< QLatin1String("Item")
<< QLatin1String("KeyEvent")
<< QLatin1String("Keys")
<< QLatin1String("LayoutItem")
<< QLatin1String("ListModel")
<< QLatin1String("ListView")
<< QLatin1String("Loader")
<< QLatin1String("MouseEvent")
<< QLatin1String("MouseRegion")
<< QLatin1String("NumberAnimation")
<< QLatin1String("NumberFormatter")
<< QLatin1String("ParallelAnimation")
<< QLatin1String("ParentAction")
<< QLatin1String("ParentChange")
<< QLatin1String("ParticleMotionGravity")
<< QLatin1String("ParticleMotionLinear")
<< QLatin1String("ParticleMotionWander")
<< QLatin1String("Particles")
<< QLatin1String("Path")
<< QLatin1String("PathAttribute")
<< QLatin1String("PathCubic")
<< QLatin1String("PathElement")
<< QLatin1String("PathLine")
<< QLatin1String("PathPercent")
<< QLatin1String("PathQuad")
<< QLatin1String("PathView")
<< QLatin1String("PauseAnimation")
<< QLatin1String("PropertyAction")
<< QLatin1String("PropertyAnimation")
<< QLatin1String("PropertyChanges")
<< QLatin1String("Rectangle")
<< QLatin1String("Repeater")
<< QLatin1String("Rotation")
<< QLatin1String("Row")
<< QLatin1String("Scale")
<< QLatin1String("Script")
<< QLatin1String("ScriptAction")
<< QLatin1String("SequentialAnimation")
<< QLatin1String("SpringFollow")
<< QLatin1String("SqlBind")
<< QLatin1String("SqlConnection")
<< QLatin1String("SqlQuery")
<< QLatin1String("State")
<< QLatin1String("StateChangeScript")
<< QLatin1String("SystemPalette")
<< QLatin1String("Text")
<< QLatin1String("TextEdit")
<< QLatin1String("TextInput")
<< QLatin1String("Timer")
<< QLatin1String("Transform")
<< QLatin1String("Transition")
<< QLatin1String("VisualItemModel")
<< QLatin1String("WebView")
<< QLatin1String("XmlListModel")
<< QLatin1String("XmlRole");
QmlSymbol *QmlLookupContext::resolveBuildinType(const QString &name)
{
// FIXME: use a REAL mete-type system here!
if (name == "Rectangle") {
QmlBuildInSymbol *rectSymbol = new QmlBuildInSymbol(name);
rectSymbol->addMember(new QmlBuildInSymbol("x"));
rectSymbol->addMember(new QmlBuildInSymbol("y"));
rectSymbol->addMember(new QmlBuildInSymbol("height"));
rectSymbol->addMember(new QmlBuildInSymbol("width"));
return rectSymbol;
} else if (qmlMetaTypes.contains(name)) {
return new QmlBuildInSymbol(name);
} else {
return 0;
}
QList<Qml::PackageInfo> packages;
// FIXME:
packages.append(PackageInfo("Qt", 4, 6));
return m_typeSystem->resolve(name, packages);
}
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName)
@@ -270,7 +184,11 @@ QList<QmlSymbol*> QmlLookupContext::visibleSymbolsInScope()
if (!_scopes.isEmpty()) {
QmlSymbol *scope = _scopes.top();
// add members defined in this symbol:
result.append(scope->members());
// add the members of the type of this scope (= object):
result.append(expandType(scope));
}
return result;
@@ -301,9 +219,27 @@ QList<QmlSymbol*> QmlLookupContext::visibleTypes()
}
}
// TODO: handle Qt imports, hack for now:
foreach (const QString &name, qmlMetaTypes)
result.append(resolveBuildinType(name));
result.append(m_typeSystem->availableTypes("Qt", 4, 6));
return result;
}
QList<QmlSymbol*> QmlLookupContext::expandType(Qml::QmlSymbol *symbol)
{
if (symbol == 0) {
return QList<QmlSymbol*>();
} else if (QmlBuildInSymbol *buildInSymbol = symbol->asBuildInSymbol()) {
return buildInSymbol->members(true);
} else if (QmlSymbolFromFile *symbolFromFile = symbol->asSymbolFromFile()){
QList<QmlSymbol*> result;
if (QmlSymbol *superTypeSymbol = resolveType(symbolFromFile->name(), symbolFromFile->fileName())) {
result.append(superTypeSymbol->members());
result.append(expandType(superTypeSymbol));
}
return result;
} else {
return QList<QmlSymbol*>();
}
}

View File

@@ -1,6 +1,7 @@
#ifndef QMLLOOKUPCONTEXT_H
#define QMLLOOKUPCONTEXT_H
#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsastvisitor_p.h>
#include <qml/qmldocument.h>
#include <qml/qmlsymbol.h>
@@ -13,33 +14,37 @@ namespace Internal {
class QmlLookupContext
{
public:
QmlLookupContext(const QStack<QmlSymbol *> &scopes,
QmlLookupContext(const QStack<Qml::QmlSymbol *> &scopes,
const QmlDocument::Ptr &doc,
const Snapshot &snapshot);
const Snapshot &snapshot,
Qml::MetaType::QmlTypeSystem *typeSystem);
QmlSymbol *resolve(const QString &name);
QmlSymbol *resolveType(const QString &name)
Qml::QmlSymbol *resolve(const QString &name);
Qml::QmlSymbol *resolveType(const QString &name)
{ return resolveType(name, _doc->fileName()); }
QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
Qml::QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
{ return resolveType(toString(name), _doc->fileName()); }
QmlDocument::Ptr document() const
{ return _doc; }
QList<QmlSymbol*> visibleSymbolsInScope();
QList<QmlSymbol*> visibleTypes();
QList<Qml::QmlSymbol*> visibleSymbolsInScope();
QList<Qml::QmlSymbol*> visibleTypes();
QList<Qml::QmlSymbol*> expandType(Qml::QmlSymbol *symbol);
private:
QmlSymbol *resolveType(const QString &name, const QString &fileName);
QmlSymbol *resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName);
QmlSymbol *resolveBuildinType(const QString &name);
Qml::QmlSymbol *resolveType(const QString &name, const QString &fileName);
Qml::QmlSymbol *resolveProperty(const QString &name, Qml::QmlSymbol *scope, const QString &fileName);
Qml::QmlSymbol *resolveBuildinType(const QString &name);
static QString toString(QmlJS::AST::UiQualifiedId *id);
private:
QStack<QmlSymbol *> _scopes;
QStack<Qml::QmlSymbol *> _scopes;
QmlDocument::Ptr _doc;
Snapshot _snapshot;
Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
} // namespace Internal

View File

@@ -37,6 +37,7 @@
#include <QSharedPointer>
#include <qml/qmldocument.h>
#include <qml/metatype/qmltypesystem.h>
namespace QmlEditor {

View File

@@ -3,6 +3,7 @@
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
using namespace Qml;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace QmlJS;
@@ -16,8 +17,7 @@ QmlResolveExpression::QmlResolveExpression(const QmlLookupContext &context)
QmlSymbol *QmlResolveExpression::typeOf(Node *node)
{
QmlSymbol *previousValue = switchValue(0);
if (node)
node->accept(this);
Node::accept(node, this);
return switchValue(previousValue);
}

View File

@@ -14,13 +14,13 @@ class QmlResolveExpression: protected QmlJS::AST::Visitor
public:
QmlResolveExpression(const QmlLookupContext &context);
QmlSymbol *typeOf(QmlJS::AST::Node *node);
QList<QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
Qml::QmlSymbol *typeOf(QmlJS::AST::Node *node);
QList<Qml::QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
protected:
using QmlJS::AST::Visitor::visit;
QmlSymbol *switchValue(QmlSymbol *symbol);
Qml::QmlSymbol *switchValue(Qml::QmlSymbol *symbol);
virtual bool visit(QmlJS::AST::FieldMemberExpression *ast);
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
@@ -28,7 +28,7 @@ protected:
private:
QmlLookupContext _context;
QmlSymbol *_value;
Qml::QmlSymbol *_value;
};
} // namespace Internal

View 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()
{
}

View 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

View 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);
}

View 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

View 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
*/
}

View 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

View 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";
}
}

View 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

View 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

View 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

View 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

View 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

View 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();
}
}
}

View 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

View 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;
}

View 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

View File

@@ -7,11 +7,37 @@ HEADERS += \
$$PWD/qml_global.h \
$$PWD/qmlidcollector.h \
$$PWD/qmldocument.h \
$$PWD/qmlsymbol.h
$$PWD/qmlpackageinfo.h \
$$PWD/qmlsymbol.h \
$$PWD/metatype/QmlMetaTypeBackend.h \
$$PWD/metatype/qmltypesystem.h
SOURCES += \
$$PWD/qmlidcollector.cpp \
$$PWD/qmldocument.cpp \
$$PWD/qmlsymbol.cpp
$$PWD/qmlsymbol.cpp \
$$PWD/qmlpackageinfo.cpp \
$$PWD/metatype/QmlMetaTypeBackend.cpp \
$$PWD/metatype/qmltypesystem.cpp
contains(QT_CONFIG, declarative) {
QT += declarative
DEFINES += BUILD_DECLARATIVE_BACKEND
HEADERS += \
$$PWD/metatype/metainfo.h \
$$PWD/metatype/nodemetainfo.h \
$$PWD/metatype/propertymetainfo.h \
$$PWD/metatype/QtDeclarativeMetaTypeBackend.h \
$$PWD/metatype/invalidmetainfoexception.h \
$$PWD/metatype/exception.h
SOURCES += \
$$PWD/metatype/metainfo.cpp \
$$PWD/metatype/nodemetainfo.cpp \
$$PWD/metatype/propertymetainfo.cpp \
$$PWD/metatype/QtDeclarativeMetaTypeBackend.cpp \
$$PWD/metatype/invalidmetainfoexception.cpp \
$$PWD/metatype/exception.cpp
}

View File

@@ -35,6 +35,7 @@
#include "qmljsnodepool_p.h"
#include "qmljsastfwd_p.h"
using namespace Qml;
using namespace QmlEditor;
using namespace QmlJS;
@@ -115,7 +116,7 @@ bool QmlDocument::parse()
_symbols.append(new QmlSymbolFromFile(_fileName, iter->member));
Internal::QmlIdCollector collect;
_ids = collect(this);
_ids = collect(*this);
}
return _parsedCorrectly;

View File

@@ -46,7 +46,7 @@ class QML_EXPORT QmlDocument
public:
typedef QSharedPointer<QmlDocument> Ptr;
typedef QList<QmlDocument::Ptr> PtrList;
typedef QMap<QString, QmlIdSymbol*> IdTable;
typedef QMap<QString, Qml::QmlIdSymbol*> IdTable;
protected:
QmlDocument(const QString &fileName);
@@ -73,8 +73,8 @@ public:
QString path() const { return _path; }
QString componentName() const { return _componentName; }
QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const;
QmlSymbol::List symbols() const
Qml::QmlSymbolFromFile *findSymbol(QmlJS::AST::Node *node) const;
Qml::QmlSymbol::List symbols() const
{ return _symbols; }
private:
@@ -88,7 +88,7 @@ private:
QString _source;
bool _parsedCorrectly;
IdTable _ids;
QmlSymbol::List _symbols;
Qml::QmlSymbol::List _symbols;
};
class QML_EXPORT Snapshot: public QMap<QString, QmlDocument::Ptr>

View File

@@ -6,16 +6,16 @@
using namespace QmlJS;
using namespace QmlJS::AST;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace Qml;
using namespace Qml::Internal;
QMap<QString, QmlIdSymbol*> QmlIdCollector::operator()(QmlDocument *doc)
QMap<QString, QmlIdSymbol*> QmlIdCollector::operator()(QmlEditor::QmlDocument &doc)
{
_doc = doc;
_doc = &doc;
_ids.clear();
_currentSymbol = 0;
Node::accept(doc->program(), this);
Node::accept(doc.program(), this);
return _ids;
}

View File

@@ -10,13 +10,13 @@
#include <qml/qmldocument.h>
#include <qml/qmlsymbol.h>
namespace QmlEditor {
namespace Qml {
namespace Internal {
class QML_EXPORT QmlIdCollector: protected QmlJS::AST::Visitor
{
public:
QMap<QString, QmlIdSymbol*> operator()(QmlDocument *doc);
QMap<QString, Qml::QmlIdSymbol*> operator()(QmlEditor::QmlDocument &doc);
protected:
virtual bool visit(QmlJS::AST::UiArrayBinding *ast);
@@ -25,16 +25,16 @@ protected:
virtual bool visit(QmlJS::AST::UiScriptBinding *ast);
private:
QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node);
Qml::QmlSymbolFromFile *switchSymbol(QmlJS::AST::UiObjectMember *node);
void addId(const QString &id, QmlJS::AST::UiScriptBinding *ast);
private:
QmlDocument *_doc;
QMap<QString, QmlIdSymbol*> _ids;
QmlSymbolFromFile *_currentSymbol;
QmlEditor::QmlDocument *_doc;
QMap<QString, Qml::QmlIdSymbol*> _ids;
Qml::QmlSymbolFromFile *_currentSymbol;
};
} // namespace Internal
} // namespace QmlEditor
} // namespace Qml
#endif // QMLIDCOLLECTOR_H

View 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)
{
}

View 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

View File

@@ -2,13 +2,12 @@
#include "qmljsengine_p.h"
#include "qmlsymbol.h"
using namespace QmlEditor;
using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
QmlSymbol::~QmlSymbol()
{
qDeleteAll(_members);
}
bool QmlSymbol::isBuildInSymbol()
@@ -35,15 +34,17 @@ QmlIdSymbol *QmlSymbol::asIdSymbol()
QmlPropertyDefinitionSymbol *QmlSymbol::asPropertyDefinitionSymbol()
{ return 0; }
const QmlSymbol::List QmlSymbol::members()
{ return _members; }
QmlBuildInSymbol::~QmlBuildInSymbol()
{}
QmlBuildInSymbol *QmlBuildInSymbol::asBuildInSymbol()
{ return this; }
QmlSymbolWithMembers::~QmlSymbolWithMembers()
{ qDeleteAll(_members); }
const QmlSymbol::List QmlSymbolWithMembers::members()
{ return _members; }
QmlSymbolFromFile::QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node):
_fileName(fileName),

View File

@@ -1,24 +1,24 @@
#ifndef QMLSYMBOL_H
#define QMLSYMBOL_H
#include <QList>
#include <QString>
#include <qml/parser/qmljsastfwd_p.h>
#include <qml/qml_global.h>
namespace QmlEditor {
#include <QList>
#include <QString>
namespace Qml {
class QML_EXPORT QmlSymbol
{
public:
typedef QList<QmlSymbol*> List;
typedef QList<QmlSymbol *> List;
public:
virtual ~QmlSymbol();
virtual ~QmlSymbol() = 0;
virtual const QString name() const = 0;
virtual const List members();
virtual const List members() = 0;
bool isBuildInSymbol();
bool isSymbolFromFile();
@@ -29,30 +29,41 @@ public:
virtual class QmlSymbolFromFile *asSymbolFromFile();
virtual class QmlIdSymbol *asIdSymbol();
virtual class QmlPropertyDefinitionSymbol *asPropertyDefinitionSymbol();
protected:
List _members;
};
class QML_EXPORT QmlBuildInSymbol: public QmlSymbol
{
public:
QmlBuildInSymbol(const QString &name): _name(name) {}
virtual ~QmlBuildInSymbol();
virtual ~QmlBuildInSymbol() = 0;
virtual QmlBuildInSymbol *asBuildInSymbol();
virtual const QString name() const
{ return _name; }
void addMember(QmlBuildInSymbol *symbol)
{ _members.append(symbol); }
private:
QString _name;
virtual QmlBuildInSymbol *type() const = 0;
virtual List members(bool includeBaseClassMembers) = 0;
};
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:
QmlSymbolFromFile(const QString &fileName, QmlJS::AST::UiObjectMember *node);
@@ -125,6 +136,6 @@ private:
QmlJS::AST::UiPublicMember *propertyNode() const;
};
} // namespace QmlEditor
} // namespace Qml
#endif // QMLSYMBOL_H