/****************************************************************************
**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
QList<QQmlType *> types;
typedef QHash<int, QQmlType *> Ids;
Ids idToType;
- typedef QHash<QString, QQmlType *> Names;
+ typedef QHash<QHashedStringRef,QQmlType *> Names;
Names nameToType;
typedef QHash<const QMetaObject *, QQmlType *> MetaObjects;
MetaObjects metaObjectToType;
struct VersionedUri {
VersionedUri()
: majorVersion(0) {}
- VersionedUri(const QString &uri, int majorVersion)
+ VersionedUri(const QHashedString &uri, int majorVersion)
: uri(uri), majorVersion(majorVersion) {}
bool operator==(const VersionedUri &other) const {
return other.majorVersion == majorVersion && other.uri == uri;
}
- QString uri;
+ QHashedString uri;
int majorVersion;
};
typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules;
TypeModules uriToModule;
- struct ModuleApiList {
- ModuleApiList() : sorted(true) {}
- QList<QQmlMetaType::ModuleApi> moduleApis;
- bool sorted;
- };
- typedef QHash<QString, ModuleApiList> ModuleApis;
- ModuleApis moduleApis;
- int moduleApiCount;
-
QBitArray objects;
QBitArray interfaces;
QBitArray lists;
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
+
+ QSet<QString> protectedNamespaces;
+
+ QString typeRegistrationNamespace;
+ QStringList typeRegistrationFailures;
};
class QQmlTypeModulePrivate
};
Q_GLOBAL_STATIC(QQmlMetaTypeData, metaTypeData)
-Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
+Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, metaTypeDataLock, (QReadWriteLock::Recursive))
static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
{
- return qHash(v.uri) ^ qHash(v.majorVersion);
+ return v.uri.hash() ^ qHash(v.majorVersion);
}
QQmlMetaTypeData::QQmlMetaTypeData()
-: moduleApiCount(0)
{
}
{
for (int i = 0; i < types.count(); ++i)
delete types.at(i);
+
+ TypeModules::const_iterator i = uriToModule.constBegin();
+ for (; i != uriToModule.constEnd(); ++i)
+ delete *i;
}
class QQmlTypePrivate
{
public:
QQmlTypePrivate();
+ ~QQmlTypePrivate();
void init() const;
void initEnums() const;
+ void insertEnums(const QMetaObject *metaObject) const;
bool m_isInterface : 1;
const char *m_iid;
- QString m_module;
+ QHashedString m_module;
QString m_name;
QString m_elementName;
int m_version_maj;
mutable bool m_haveSuperType:1;
mutable QList<QQmlProxyMetaObject::ProxyData> m_metaObjects;
mutable QStringHash<int> m_enums;
+ QQmlType::SingletonInstanceInfo *m_singletonInstanceInfo;
static QHash<const QMetaObject *, int> m_attachedPropertyIds;
};
+// Avoid multiple fromUtf8(), copies and hashing of the module name.
+// This is only called when metaTypeDataLock is locked.
+static QHashedString moduleFromUtf8(const char *module)
+{
+ if (!module)
+ return QHashedString();
+
+ static const char *lastModule = 0;
+ static QHashedString lastModuleStr;
+
+ // Separate plugins may have different strings at the same address
+ QHashedCStringRef currentModule(module, ::strlen(module));
+ if ((lastModule != module) || (lastModuleStr.hash() != currentModule.hash())) {
+ lastModuleStr = QString::fromUtf8(module);
+ lastModuleStr.hash();
+ lastModule = module;
+ }
+
+ return lastModuleStr;
+}
+
+void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
+{
+ if (scriptCallback && scriptApi(e).isUndefined()) {
+ setScriptApi(e, scriptCallback(e, e));
+ } else if (qobjectCallback && !qobjectApi(e)) {
+ setQObjectApi(e, qobjectCallback(e, e));
+ }
+}
+
+void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e)
+{
+ // cleans up the engine-specific singleton instances if they exist.
+ scriptApis.remove(e);
+ QObject *o = qobjectApis.take(e);
+ delete o;
+}
+
+void QQmlType::SingletonInstanceInfo::setQObjectApi(QQmlEngine *e, QObject *o)
+{
+ qobjectApis.insert(e, o);
+}
+
+QObject *QQmlType::SingletonInstanceInfo::qobjectApi(QQmlEngine *e) const
+{
+ return qobjectApis.value(e);
+}
+
+void QQmlType::SingletonInstanceInfo::setScriptApi(QQmlEngine *e, QJSValue v)
+{
+ scriptApis.insert(e, v);
+}
+
+QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const
+{
+ return scriptApis.value(e);
+}
+
QHash<const QMetaObject *, int> QQmlTypePrivate::m_attachedPropertyIds;
QQmlTypePrivate::QQmlTypePrivate()
m_superType(0), m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0),
m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1),
m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0),
- m_isSetup(false), m_isEnumSetup(false), m_haveSuperType(false)
+ m_isSetup(false), m_isEnumSetup(false), m_haveSuperType(false), m_singletonInstanceInfo(0)
{
}
+QQmlTypePrivate::~QQmlTypePrivate()
+{
+ delete m_singletonInstanceInfo;
+}
QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
: d(new QQmlTypePrivate)
d->m_version_min = 0;
}
-QQmlType::QQmlType(int index, const QQmlPrivate::RegisterType &type)
+QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type)
: d(new QQmlTypePrivate)
{
- QString name = QString::fromUtf8(type.uri);
- if (type.uri) name += QLatin1Char('/');
- name += QString::fromUtf8(type.elementName);
+ d->m_elementName = elementName;
+ d->m_module = moduleFromUtf8(type.uri);
+
+ d->m_version_maj = type.versionMajor;
+ d->m_version_min = type.versionMinor;
+
+ if (type.qobjectApi) {
+ if (type.version >= 1) // static metaobject added in version 1
+ d->m_baseMetaObject = type.instanceMetaObject;
+ if (type.version >= 2) // typeId added in version 2
+ d->m_typeId = type.typeId;
+ if (type.version >= 2) // revisions added in version 2
+ d->m_revision = type.revision;
+ }
+
+ d->m_newFunc = 0;
+ d->m_index = index;
+
+ d->m_singletonInstanceInfo = new SingletonInstanceInfo;
+ d->m_singletonInstanceInfo->scriptCallback = type.scriptApi;
+ d->m_singletonInstanceInfo->qobjectCallback = type.qobjectApi;
+ d->m_singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
+ d->m_singletonInstanceInfo->instanceMetaObject = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0;
+}
+
+QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterType &type)
+: d(new QQmlTypePrivate)
+{
+ d->m_elementName = elementName;
+ d->m_module = moduleFromUtf8(type.uri);
- d->m_module = QString::fromUtf8(type.uri);
- d->m_name = name;
d->m_version_maj = type.versionMajor;
d->m_version_min = type.versionMinor;
if (type.version >= 1) // revisions added in version 1
delete d;
}
-QString QQmlType::module() const
+const QHashedString &QQmlType::module() const
{
return d->m_module;
}
return vmajor == d->m_version_maj && vminor >= d->m_version_min;
}
-bool QQmlType::availableInVersion(const QString &module, int vmajor, int vminor) const
+bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const
{
Q_ASSERT(vmajor >= 0 && vminor >= 0);
return module == d->m_module && vmajor == d->m_version_maj && vminor >= d->m_version_min;
// returns the nearest _registered_ super class
QQmlType *QQmlType::superType() const
{
- if (!d->m_haveSuperType) {
+ if (!d->m_haveSuperType && d->m_baseMetaObject) {
const QMetaObject *mo = d->m_baseMetaObject->superClass();
while (mo && !d->m_superType) {
d->m_superType = QQmlMetaType::qmlType(mo, d->m_module, d->m_version_maj, d->m_version_min);
if (m_isSetup)
return;
+ const QMetaObject *mo = m_baseMetaObject;
+ if (!mo) {
+ // singleton type without metaobject information
+ return;
+ }
+
// Setup extended meta object
// XXX - very inefficient
- const QMetaObject *mo = m_baseMetaObject;
if (m_extFunc) {
QMetaObjectBuilder builder;
clone(builder, m_extMetaObject, m_extMetaObject, m_extMetaObject);
QWriteLocker lock(metaTypeDataLock());
if (m_isEnumSetup) return;
- const QMetaObject *metaObject = m_baseMetaObject;
- for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
+ if (m_baseMetaObject) // could be singleton type without metaobject
+ insertEnums(m_baseMetaObject);
- QMetaEnum e = metaObject->enumerator(ii);
+ m_isEnumSetup = true;
+}
- for (int jj = 0; jj < e.keyCount(); ++jj)
- m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
+{
+ // Add any enum values defined by 'related' classes
+ if (metaObject->d.relatedMetaObjects) {
+ const QMetaObject **related = metaObject->d.relatedMetaObjects;
+ if (related) {
+ while (*related)
+ insertEnums(*related++);
+ }
}
- m_isEnumSetup = true;
+ // Add any enum values defined by this class, overwriting any inherited values
+ for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ for (int jj = 0; jj < e.keyCount(); ++jj)
+ m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+ }
}
QByteArray QQmlType::typeName() const
{
+ if (d->m_singletonInstanceInfo)
+ return d->m_singletonInstanceInfo->typeName.toUtf8();
if (d->m_baseMetaObject)
return d->m_baseMetaObject->className();
else
const QString &QQmlType::elementName() const
{
- if (d->m_elementName.isEmpty()) {
- QString n = qmlTypeName();
- int idx = n.lastIndexOf(QLatin1Char('/'));
- d->m_elementName = n.mid(idx + 1);
- }
return d->m_elementName;
}
const QString &QQmlType::qmlTypeName() const
{
+ if (d->m_name.isEmpty()) {
+ if (!d->m_module.isEmpty())
+ d->m_name = static_cast<QString>(d->m_module) + QLatin1Char('/') + d->m_elementName;
+ else
+ d->m_name = d->m_elementName;
+ }
+
return d->m_name;
}
*memory = ((char *)rv) + d->m_allocationSize;
}
+QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const
+{
+ return d->m_singletonInstanceInfo;
+}
+
QQmlCustomParser *QQmlType::customParser() const
{
return d->m_customParser;
return !d->m_metaObjects.isEmpty();
}
+bool QQmlType::isSingleton() const
+{
+ return d->m_singletonInstanceInfo != 0;
+}
+
bool QQmlType::isInterface() const
{
return d->m_isInterface;
return d->m_index;
}
-int QQmlType::enumValue(const QHashedStringRef &name) const
+int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const
{
+ Q_ASSERT(ok);
+ *ok = true;
+
d->initEnums();
int *rv = d->m_enums.value(name);
- return rv?*rv:-1;
+ if (rv)
+ return *rv;
+
+ *ok = false;
+ return -1;
}
-int QQmlType::enumValue(const QHashedV8String &name) const
+int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const
{
+ Q_ASSERT(ok);
+ *ok = true;
+
d->initEnums();
int *rv = d->m_enums.value(name);
- return rv?*rv:-1;
+ if (rv)
+ return *rv;
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::enumValue(const QHashedV8String &name, bool *ok) const
+{
+ Q_ASSERT(ok);
+ *ok = true;
+
+ d->initEnums();
+
+ int *rv = d->m_enums.value(name);
+ if (rv)
+ return *rv;
+
+ *ok = false;
+ return -1;
}
QQmlTypeModule::QQmlTypeModule()
void QQmlTypeModulePrivate::add(QQmlType *type)
{
- types << type;
-
minMinorVersion = qMin(minMinorVersion, type->minorVersion());
maxMinorVersion = qMax(maxMinorVersion, type->minorVersion());
list.append(type);
}
-QList<QQmlType *> QQmlTypeModule::types()
-{
- QList<QQmlType *> rv;
- QReadLocker lock(metaTypeDataLock());
- rv = d->types;
- return rv;
-}
-
-QList<QQmlType *> QQmlTypeModule::type(const QString &name)
-{
- QReadLocker lock(metaTypeDataLock());
- QList<QQmlType *> rv;
- for (int ii = 0; ii < d->types.count(); ++ii) {
- if (d->types.at(ii)->elementName() == name)
- rv << d->types.at(ii);
- }
- return rv;
-}
-
QQmlType *QQmlTypeModule::type(const QHashedStringRef &name, int minor)
{
QReadLocker lock(metaTypeDataLock());
return 0;
}
+QList<QQmlType*> QQmlTypeModule::singletonTypes(int minor) const
+{
+ QReadLocker lock(metaTypeDataLock());
+
+ QList<QQmlType *> retn;
+ for (int ii = 0; ii < d->types.count(); ++ii) {
+ QQmlType *curr = d->types.at(ii);
+ if (curr->isSingleton() && curr->minorVersion() <= minor)
+ retn.append(curr);
+ }
+
+ return retn;
+}
+
QQmlTypeModuleVersion::QQmlTypeModuleVersion()
: m_module(0), m_minor(0)
data->idToType.insert(type->typeId(), type);
data->idToType.insert(type->qListTypeId(), type);
// XXX No insertMulti, so no multi-version interfaces?
- if (!type->qmlTypeName().isEmpty())
- data->nameToType.insert(type->qmlTypeName(), type);
+ if (!type->elementName().isEmpty())
+ data->nameToType.insert(type->elementName(), type);
if (data->interfaces.size() <= interface.typeId)
data->interfaces.resize(interface.typeId + 16);
return index;
}
-int registerType(const QQmlPrivate::RegisterType &type)
+QString registrationTypeString(QQmlType::RegistrationType typeType)
+{
+ QString typeStr;
+ if (typeType == QQmlType::CppType)
+ typeStr = QStringLiteral("element");
+ else if (typeType == QQmlType::SingletonType)
+ typeStr = QStringLiteral("singleton type");
+ return typeStr;
+}
+
+// NOTE: caller must hold a QWriteLocker on "data"
+bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *data, const char *uri, const QString &typeName)
{
- if (type.elementName) {
- for (int ii = 0; type.elementName[ii]; ++ii) {
- if (!isalnum(type.elementName[ii])) {
- qWarning("qmlRegisterType(): Invalid QML element name \"%s\"", type.elementName);
- return -1;
+ if (!typeName.isEmpty()) {
+ int typeNameLen = typeName.length();
+ for (int ii = 0; ii < typeNameLen; ++ii) {
+ if (!typeName.at(ii).isLetterOrNumber()) {
+ QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\""));
+ data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName));
+ return false;
}
}
}
+ if (uri && !typeName.isEmpty()) {
+ QString nameSpace = moduleFromUtf8(uri);
+
+ if (!data->typeRegistrationNamespace.isEmpty()) {
+ // We can only install types into the registered namespace
+ if (nameSpace != data->typeRegistrationNamespace) {
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install %1 '%2' into unregistered namespace '%3'"));
+ data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
+ return false;
+ }
+ } else if (data->typeRegistrationNamespace != nameSpace) {
+ // Is the target namespace protected against further registrations?
+ if (data->protectedNamespaces.contains(nameSpace)) {
+ QString failure(QCoreApplication::translate("qmlRegisterType",
+ "Cannot install %1 '%2' into protected namespace '%3'"));
+ data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+int registerType(const QQmlPrivate::RegisterType &type)
+{
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
+ QString elementName = QString::fromUtf8(type.elementName);
+ if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName))
+ return -1;
+
int index = data->types.count();
- QQmlType *dtype = new QQmlType(index, type);
+ QQmlType *dtype = new QQmlType(index, elementName, type);
data->types.append(dtype);
data->idToType.insert(dtype->typeId(), dtype);
if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
- if (!dtype->qmlTypeName().isEmpty())
- data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
+ if (!dtype->elementName().isEmpty())
+ data->nameToType.insertMulti(dtype->elementName(), dtype);
data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
data->objects.setBit(type.typeId, true);
if (type.listId) data->lists.setBit(type.listId, true);
- if (type.uri) {
- QString mod = QString::fromUtf8(type.uri);
+ if (!dtype->module().isEmpty()) {
+ const QHashedString &mod = dtype->module();
QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor);
QQmlTypeModule *module = data->uriToModule.value(versionedUri);
return index;
}
-int registerModuleApi(const QQmlPrivate::RegisterModuleApi &api)
+int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type)
{
QWriteLocker lock(metaTypeDataLock());
-
QQmlMetaTypeData *data = metaTypeData();
- QString uri = QString::fromUtf8(api.uri);
- QQmlMetaType::ModuleApi import;
- import.major = api.versionMajor;
- import.minor = api.versionMinor;
- import.script = api.scriptApi;
- import.qobject = api.qobjectApi;
- import.instanceMetaObject = (api.qobjectApi && api.version >= 1) ? api.instanceMetaObject : 0; // BC with version 0.
-
- if (import.qobject && !import.instanceMetaObject) // BC - check import.iMO rather than api.iMO.
- qWarning() << "qmlRegisterModuleApi(): sub-optimal: use the templated version of this function instead!";
-
- int index = data->moduleApiCount++;
-
- QQmlMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
- if (iter == data->moduleApis.end()) {
- QQmlMetaTypeData::ModuleApiList apis;
- apis.moduleApis << import;
- data->moduleApis.insert(uri, apis);
- } else {
- iter->moduleApis << import;
- iter->sorted = false;
+ QString typeName = QString::fromUtf8(type.typeName);
+ if (!checkRegistration(QQmlType::SingletonType, data, type.uri, typeName))
+ return -1;
+
+ int index = data->types.count();
+
+ QQmlType *dtype = new QQmlType(index, typeName, type);
+
+ data->types.append(dtype);
+ data->idToType.insert(dtype->typeId(), dtype);
+
+ if (!dtype->elementName().isEmpty())
+ data->nameToType.insertMulti(dtype->elementName(), dtype);
+
+ if (dtype->baseMetaObject())
+ data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
+
+ if (type.typeId) {
+ if (data->objects.size() <= type.typeId)
+ data->objects.resize(type.typeId + 16);
+ data->objects.setBit(type.typeId, true);
+ }
+
+ if (!dtype->module().isEmpty()) {
+ const QHashedString &mod = dtype->module();
+
+ QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor);
+ QQmlTypeModule *module = data->uriToModule.value(versionedUri);
+ if (!module) {
+ module = new QQmlTypeModule;
+ module->d->uri = versionedUri;
+ data->uriToModule.insert(versionedUri, module);
+ }
+ module->d->add(dtype);
}
return index;
return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
} else if (type == AutoParentRegistration) {
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
- } else if (type == ModuleApiRegistration) {
- return registerModuleApi(*reinterpret_cast<RegisterModuleApi *>(data));
+ } else if (type == SingletonRegistration) {
+ return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
}
return -1;
}
+bool QQmlMetaType::namespaceContainsRegistrations(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ // Has any type previously been installed to this namespace?
+ QHashedString nameSpace(uri);
+ foreach (const QQmlType *type, data->types)
+ if (type->module() == nameSpace)
+ return true;
+
+ return false;
+}
+
+void QQmlMetaType::protectNamespace(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ data->protectedNamespaces.insert(uri);
+}
+
+void QQmlMetaType::setTypeRegistrationNamespace(const QString &uri)
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ data->typeRegistrationNamespace = uri;
+ data->typeRegistrationFailures.clear();
+}
+
+QStringList QQmlMetaType::typeRegistrationFailures()
+{
+ QQmlMetaTypeData *data = metaTypeData();
+
+ return data->typeRegistrationFailures;
+}
+
+QReadWriteLock *QQmlMetaType::typeRegistrationLock()
+{
+ return metaTypeDataLock();
+}
+
/*
Returns true if a module \a uri of any version is installed.
*/
if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor)
return true;
- // then, check ModuleApis
- foreach (const QQmlMetaType::ModuleApi &mApi, data->moduleApis.value(module).moduleApis) {
- if (mApi.major == versionMajor && mApi.minor == versionMinor) // XXX is this correct?
- return true;
- }
-
return false;
}
return data->parentFunctions;
}
-static bool operator<(const QQmlMetaType::ModuleApi &lhs, const QQmlMetaType::ModuleApi &rhs)
-{
- return lhs.major < rhs.major || (lhs.major == rhs.major && lhs.minor < rhs.minor);
-}
-
-QQmlMetaType::ModuleApi
-QQmlMetaType::moduleApi(const QString &uri, int versionMajor, int versionMinor)
-{
- QReadLocker lock(metaTypeDataLock());
- QQmlMetaTypeData *data = metaTypeData();
-
- QQmlMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
- if (iter == data->moduleApis.end())
- return ModuleApi();
-
- if (iter->sorted == false) {
- qSort(iter->moduleApis.begin(), iter->moduleApis.end());
- iter->sorted = true;
- }
-
- for (int ii = iter->moduleApis.count() - 1; ii >= 0; --ii) {
- const ModuleApi &import = iter->moduleApis.at(ii);
- if (import.major == versionMajor && import.minor <= versionMinor)
- return import;
- }
-
- return ModuleApi();
-}
-
-QHash<QString, QList<QQmlMetaType::ModuleApi> > QQmlMetaType::moduleApis()
-{
- QReadLocker lock(metaTypeDataLock());
- QQmlMetaTypeData *data = metaTypeData();
-
- QHash<QString, QList<ModuleApi> > moduleApis;
- QHashIterator<QString, QQmlMetaTypeData::ModuleApiList> it(data->moduleApis);
- while (it.hasNext()) {
- it.next();
- moduleApis[it.key()] = it.value().moduleApis;
- }
-
- return moduleApis;
-}
-
QObject *QQmlMetaType::toQObject(const QVariant &v, bool *ok)
{
if (!isQObject(v.userType())) {
}
/*!
- Returns the type (if any) of URI-qualified named \a name in version specified
+ Returns the type (if any) of URI-qualified named \a qualifiedName and version specified
+ by \a version_major and \a version_minor.
+*/
+QQmlType *QQmlMetaType::qmlType(const QString &qualifiedName, int version_major, int version_minor)
+{
+ int slash = qualifiedName.indexOf(QLatin1Char('/'));
+ if (slash <= 0)
+ return 0;
+
+ QHashedStringRef module(qualifiedName.constData(), slash);
+ QHashedStringRef name(qualifiedName.constData() + slash + 1, qualifiedName.length() - slash - 1);
+
+ return qmlType(name, module, version_major, version_minor);
+}
+
+/*!
+ Returns the type (if any) of \a name in \a module and version specified
by \a version_major and \a version_minor.
*/
-QQmlType *QQmlMetaType::qmlType(const QString &name, int version_major, int version_minor)
+QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.find(name);
- while (it != data->nameToType.end()) {
+ while (it != data->nameToType.end() && it.key() == name) {
// XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty
- if (it.key() == name && (version_major<0 || (*it)->availableInVersion(version_major,version_minor)))
+ if (version_major < 0 || (*it)->availableInVersion(module, version_major,version_minor))
return (*it);
++it;
}
by \a version_major and \a version_minor in module specified by \a uri. Returns null if no
type is registered.
*/
-QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QString &module, int version_major, int version_minor)
+QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor)
{
Q_ASSERT(version_major >= 0 && version_minor >= 0);
QReadLocker lock(metaTypeDataLock());
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- return data->nameToType.keys();
+ QList<QString> names;
+ QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.begin();
+ while (it != data->nameToType.end()) {
+ names += (*it)->qmlTypeName();
+ ++it;
+ }
+
+ return names;
}
/*!
return data->nameToType.values();
}
+/*!
+ Returns the list of registered QML singleton types.
+*/
+QList<QQmlType*> QQmlMetaType::qmlSingletonTypes()
+{
+ QReadLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ QList<QQmlType*> alltypes = data->nameToType.values();
+ QList<QQmlType*> retn;
+ foreach (QQmlType* t, alltypes) {
+ if (t->isSingleton()) {
+ retn.append(t);
+ }
+ }
+
+ return retn;
+}
+
int QQmlMetaType::QQuickAnchorLineMetaTypeId()
{
static int id = 0;