summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Alpert <aalpert@rim.com>2012-12-03 08:50:11 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-05 19:21:01 +0100
commit9995a2910d8a5f0317fe3adeb54f838b99ab31a8 (patch)
treed35ae22a28bed65d143e5a8920d3024c0cc164c8 /src
parentdc96bfd00152e25f007511f64bff7c413f657886 (diff)
Add a method that allows registration of files to types
There is currently no way in C++ to duplicate the functionality of a qmldir file in mapping QML files to versioned types in a module. This functionality would be useful both in cases where a separate qmldir file would be overkill, and for cases where the type mapping should be generated dynamically. Change-Id: I28d7898122c5556fcd7cf3476795bcf4bb288eab Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qdeclarative.h14
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp3
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp75
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h11
5 files changed, 106 insertions, 1 deletions
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 4f7dcb2b..68fae370 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -49,6 +49,7 @@
#include <QtDeclarative/qdeclarativelist.h>
#include <QtCore/qbytearray.h>
+#include <QtCore/qurl.h>
#include <QtCore/qmetaobject.h>
QT_BEGIN_HEADER
@@ -390,6 +391,19 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
}
+inline int Q_DECLARATIVE_EXPORT qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+{
+ QDeclarativePrivate::RegisterComponent type = {
+ url,
+ uri,
+ qmlName,
+ versionMajor,
+ versionMinor
+ };
+
+ return QDeclarativePrivate::qmlregister(QDeclarativePrivate::ComponentRegistration, &type);
+}
+
class QDeclarativeContext;
class QDeclarativeEngine;
Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *);
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index db062e47..14e69728 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -518,6 +518,9 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
if (QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin))
versionFound = true;
+ //Load any type->file mappings registered for this uri
+ qmldircomponents << QDeclarativeMetaType::qmlComponents(uri.toUtf8(), vmaj, vmin);
+
if (!versionFound && qmldircomponents.isEmpty()) {
if (errorString) {
bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1);
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index d7eacaf4..09390646 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -54,6 +54,8 @@
#include <QtCore/qmetaobject.h>
#include <QtCore/qbitarray.h>
#include <QtCore/qreadwritelock.h>
+#include <qfileinfo.h>
+#include <qdir.h>
#include <qmetatype.h>
#include <qobjectdefs.h>
#include <qdatetime.h>
@@ -122,6 +124,15 @@ struct QDeclarativeMetaTypeData
Q_GLOBAL_STATIC(QDeclarativeMetaTypeData, metaTypeData)
Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
+struct QDeclarativeRegisteredComponentData
+{
+ ~QDeclarativeRegisteredComponentData() {} ;
+ QMap<QByteArray, QDeclarativeDirComponents*> registeredComponents;
+};
+
+Q_GLOBAL_STATIC(QDeclarativeRegisteredComponentData, registeredComponentData)
+Q_GLOBAL_STATIC(QReadWriteLock, registeredComponentDataLock)
+
QDeclarativeMetaTypeData::~QDeclarativeMetaTypeData()
{
for (int i = 0; i < types.count(); ++i)
@@ -667,6 +678,45 @@ int registerType(const QDeclarativePrivate::RegisterType &type)
return index;
}
+int registerComponent(const QDeclarativePrivate::RegisterComponent& data)
+{
+ if (data.typeName) {
+ for (int ii = 0; data.typeName[ii]; ++ii) {
+ if (!isalnum(data.typeName[ii])) {
+ qWarning("qmlRegisterType(): Invalid QML type name \"%s\"", data.typeName);
+ return 0;
+ }
+ }
+ } else {
+ qWarning("qmlRegisterType(): No QML type name for \"%s\"", data.url.toString().toLatin1().constData());
+ return 0;
+ }
+
+ QWriteLocker lock(registeredComponentDataLock());
+ QString path;
+ // Relative paths are relative to application working directory
+ if (data.url.isRelative() || data.url.scheme() == QLatin1String("file")) // Workaround QTBUG-11929
+ path = QUrl::fromLocalFile(QDir::currentPath()+QLatin1String("/")).resolved(data.url).toString();
+ else
+ path = data.url.toString();
+ QDeclarativeRegisteredComponentData *d = registeredComponentData();
+ QDeclarativeDirParser::Component comp(
+ QString::fromUtf8(data.typeName),
+ path,
+ data.majorVersion,
+ data.minorVersion
+ );
+
+ QDeclarativeDirComponents* comps = d->registeredComponents.value(QByteArray(data.uri), 0);
+ if (!comps)
+ d->registeredComponents.insert(QByteArray(data.uri), comps = new QDeclarativeDirComponents);
+
+ // Types added later should take precedence, like registerType
+ comps->prepend(comp);
+
+ return 1;
+}
+
/*
This method is "over generalized" to allow us to (potentially) register more types of things in
the future without adding exported symbols.
@@ -679,6 +729,8 @@ int QDeclarativePrivate::qmlregister(RegistrationType type, void *data)
return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
} else if (type == AutoParentRegistration) {
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
+ } else if (type == ComponentRegistration) {
+ return registerComponent(*reinterpret_cast<RegisterComponent *>(data));
}
return -1;
}
@@ -984,6 +1036,29 @@ QDeclarativeType *QDeclarativeMetaType::qmlType(int userType)
}
/*!
+ Returns the component(s) that have been registered for the module specified by \a uri and the version specified
+ by \a version_major and \a version_minor. Returns an empty list if no such components were registered.
+*/
+QDeclarativeDirComponents QDeclarativeMetaType::qmlComponents(const QByteArray &module, int version_major, int version_minor)
+{
+ QReadLocker lock(registeredComponentDataLock());
+ QDeclarativeRegisteredComponentData *data = registeredComponentData();
+
+ QDeclarativeDirComponents* comps = data->registeredComponents.value(module, 0);
+ if (!comps)
+ return QDeclarativeDirComponents();
+ QDeclarativeDirComponents ret = *comps;
+ for (int i = ret.count() - 1; i >= 0; i--) {
+ QDeclarativeDirParser::Component &c = ret[i];
+ if (version_major >= 0 && (c.majorVersion != version_major || c.minorVersion > version_minor))
+ ret.removeAt(i);
+ }
+
+ return ret;
+}
+
+
+/*!
Returns the list of registered QML type names.
*/
QList<QByteArray> QDeclarativeMetaType::qmlTypeNames()
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index d751f049..a1699558 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -59,6 +59,7 @@
#include <QtCore/qvariant.h>
#include <QtCore/qbitarray.h>
#include <private/qtdeclarativeglobal_p.h>
+#include <private/qdeclarativedirparser_p.h>
QT_BEGIN_NAMESPACE
@@ -80,6 +81,8 @@ public:
static QDeclarativeType *qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor);
static QDeclarativeType *qmlType(int);
+ static QDeclarativeDirComponents qmlComponents(const QByteArray& module, int version_major, int version_minor); //### Is this the right place?
+
static QMetaProperty defaultProperty(const QMetaObject *);
static QMetaProperty defaultProperty(QObject *);
static QMetaMethod defaultMethod(const QMetaObject *);
@@ -161,6 +164,7 @@ private:
friend struct QDeclarativeMetaTypeData;
friend int registerType(const QDeclarativePrivate::RegisterType &);
friend int registerInterface(const QDeclarativePrivate::RegisterInterface &);
+ friend int registerComponent(const QDeclarativePrivate::RegisterComponent &);
QDeclarativeType(int, const QDeclarativePrivate::RegisterInterface &);
QDeclarativeType(int, const QDeclarativePrivate::RegisterType &);
~QDeclarativeType();
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index db2b0661..b88ff79f 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -233,10 +233,19 @@ namespace QDeclarativePrivate
AutoParentFunction function;
};
+ struct RegisterComponent {
+ const QUrl &url;
+ const char *uri;
+ const char *typeName;
+ int majorVersion;
+ int minorVersion;
+ };
+
enum RegistrationType {
TypeRegistration = 0,
InterfaceRegistration = 1,
- AutoParentRegistration = 2
+ AutoParentRegistration = 2,
+ ComponentRegistration = 3
};
int Q_DECLARATIVE_EXPORT qmlregister(RegistrationType, void *);