aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlglobal_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlglobal_p.h')
-rw-r--r--src/qml/qml/qqmlglobal_p.h96
1 files changed, 85 insertions, 11 deletions
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 6e233c9fae..3ed7286ed9 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -44,6 +44,7 @@
#include <private/qtqmlglobal_p.h>
#include <QtCore/QObject>
+#include <private/qqmlpropertycache_p.h>
QT_BEGIN_HEADER
@@ -63,32 +64,105 @@ QT_BEGIN_NAMESPACE
return status == Yes; \
}
-#define FAST_CONNECT(Sender, Signal, Receiver, Method) \
+/*!
+ Connect \a Signal of \a Sender to \a Method of \a Receiver. \a Signal must be
+ of type \a SenderType and \a Receiver of type \a ReceiverType.
+
+ Unlike QObject::connect(), this method caches the lookup of the signal and method
+ indexes. It also does not require lazy QMetaObjects to be built so should be
+ preferred in all QML code that might interact with QML built objects.
+
+ \code
+ QQuickTextControl *control;
+ QQuickTextEdit *textEdit;
+ qmlobject_connect(control, QQuickTextControl, SIGNAL(updateRequest(QRectF)),
+ textEdit, QQuickTextEdit, SLOT(updateDocument()));
+ \endcode
+*/
+#define qmlobject_connect(Sender, SenderType, Signal, Receiver, ReceiverType, Method) \
{ \
- QObject *sender = (Sender); \
- QObject *receiver = (Receiver); \
+ SenderType *sender = (Sender); \
+ ReceiverType *receiver = (Receiver); \
const char *signal = (Signal); \
const char *method = (Method); \
static int signalIdx = -1; \
static int methodIdx = -1; \
if (signalIdx < 0) { \
- if (((int)(*signal) - '0') == QSIGNAL_CODE) \
- signalIdx = sender->metaObject()->indexOfSignal(signal+1); \
- else \
- qWarning("FAST_CONNECT: Invalid signal %s. Please make sure you are using the SIGNAL macro.", signal); \
+ Q_ASSERT(((int)(*signal) - '0') == QSIGNAL_CODE); \
+ signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \
} \
if (methodIdx < 0) { \
int code = ((int)(*method) - '0'); \
+ Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \
if (code == QSLOT_CODE) \
- methodIdx = receiver->metaObject()->indexOfSlot(method+1); \
- else if (code == QSIGNAL_CODE) \
- methodIdx = receiver->metaObject()->indexOfSignal(method+1); \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \
else \
- qWarning("FAST_CONNECT: Invalid method %s. Please make sure you are using the SIGNAL or SLOT macro.", method); \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSignal(method+1); \
} \
+ Q_ASSERT(signalIdx != -1 && methodIdx != -1); \
QMetaObject::connect(sender, signalIdx, receiver, methodIdx, Qt::DirectConnection); \
}
+/*!
+ Disconnect \a Signal of \a Sender from \a Method of \a Receiver. \a Signal must be
+ of type \a SenderType and \a Receiver of type \a ReceiverType.
+
+ Unlike QObject::disconnect(), this method caches the lookup of the signal and method
+ indexes. It also does not require lazy QMetaObjects to be built so should be
+ preferred in all QML code that might interact with QML built objects.
+
+ \code
+ QQuickTextControl *control;
+ QQuickTextEdit *textEdit;
+ qmlobject_disconnect(control, QQuickTextControl, SIGNAL(updateRequest(QRectF)),
+ textEdit, QQuickTextEdit, SLOT(updateDocument()));
+ \endcode
+*/
+#define qmlobject_disconnect(Sender, SenderType, Signal, Receiver, ReceiverType, Method) \
+{ \
+ SenderType *sender = (Sender); \
+ ReceiverType *receiver = (Receiver); \
+ const char *signal = (Signal); \
+ const char *method = (Method); \
+ static int signalIdx = -1; \
+ static int methodIdx = -1; \
+ if (signalIdx < 0) { \
+ Q_ASSERT(((int)(*signal) - '0') == QSIGNAL_CODE); \
+ signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \
+ } \
+ if (methodIdx < 0) { \
+ int code = ((int)(*method) - '0'); \
+ Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \
+ if (code == QSLOT_CODE) \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \
+ else \
+ methodIdx = ReceiverType::staticMetaObject.indexOfSignal(method+1); \
+ } \
+ Q_ASSERT(signalIdx != -1 && methodIdx != -1); \
+ QMetaObject::disconnect(sender, signalIdx, receiver, methodIdx); \
+}
+
+/*!
+ This method is identical to qobject_cast<T>() except that it does not require lazy
+ QMetaObjects to be built, so should be preferred in all QML code that might interact
+ with QML built objects.
+
+ \code
+ QObject *object;
+ if (QQuickTextEdit *textEdit = qmlobject_cast<QQuickTextEdit *>(object)) {
+ // ...Do something...
+ }
+ \endcode
+*/
+template<class T>
+T qmlobject_cast(QObject *object)
+{
+ if (QQmlMetaObject::canConvert(object, &reinterpret_cast<T>(object)->staticMetaObject))
+ return static_cast<T>(object);
+ else
+ return 0;
+}
+
bool Q_QML_PRIVATE_EXPORT QQml_isSignalConnected(QObject*, int, int);
#define IS_SIGNAL_CONNECTED(Sender, Signal) \