aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r--src/qml/qml/qqmlmetatype.cpp74
1 files changed, 71 insertions, 3 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index c1147b025b..b3a16b034c 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -108,6 +108,11 @@ struct QQmlMetaTypeData
QBitArray lists;
QList<QQmlPrivate::AutoParentFunction> parentFunctions;
+
+ QSet<QString> protectedNamespaces;
+
+ QString typeRegistrationNamespace;
+ QStringList typeRegistrationFailures;
};
class QQmlTypeModulePrivate
@@ -128,7 +133,7 @@ public:
};
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)
{
@@ -193,7 +198,7 @@ public:
// Avoid multiple fromUtf8(), copies and hashing of the module name.
// This is only called when metaTypeDataLock is locked.
-static QHashedString moduletoUtf8(const char *module)
+static QHashedString moduleFromUtf8(const char *module)
{
if (!module)
return QHashedString();
@@ -241,7 +246,7 @@ QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface)
QQmlType::QQmlType(int index, const QQmlPrivate::RegisterType &type)
: d(new QQmlTypePrivate)
{
- d->m_module = moduletoUtf8(type.uri);
+ d->m_module = moduleFromUtf8(type.uri);
d->m_elementName = QString::fromUtf8(type.elementName);
d->m_version_maj = type.versionMajor;
@@ -902,6 +907,29 @@ int registerType(const QQmlPrivate::RegisterType &type)
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
+
+ if (type.uri && type.elementName) {
+ QString nameSpace = moduleFromUtf8(type.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 element '%1' into unregistered namespace '%2'"));
+ data->typeRegistrationFailures.append(failure.arg(QString::fromUtf8(type.elementName)).arg(nameSpace));
+ return -1;
+ }
+ } 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 element '%1' into protected namespace '%2'"));
+ data->typeRegistrationFailures.append(failure.arg(QString::fromUtf8(type.elementName)).arg(nameSpace));
+ return -1;
+ }
+ }
+ }
+
int index = data->types.count();
QQmlType *dtype = new QQmlType(index, type);
@@ -985,6 +1013,46 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *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.
*/