summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/kernel.pri8
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp4
-rw-r--r--src/corelib/kernel/qbasictimer.cpp8
-rw-r--r--src/corelib/kernel/qcore_mac_p.h2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp42
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp262
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry_p.h96
-rw-r--r--src/corelib/kernel/qeventloop.cpp2
-rw-r--r--src/corelib/kernel/qmetaobject.cpp153
-rw-r--r--src/corelib/kernel/qmetaobject.h22
-rw-r--r--src/corelib/kernel/qmetaobject_p.h7
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp49
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder_p.h2
-rw-r--r--src/corelib/kernel/qmetatype.cpp118
-rw-r--r--src/corelib/kernel/qmetatype.h69
-rw-r--r--src/corelib/kernel/qmetatype_p.h2
-rw-r--r--src/corelib/kernel/qmimedata.cpp16
-rw-r--r--src/corelib/kernel/qobject.cpp329
-rw-r--r--src/corelib/kernel/qobject.h5
-rw-r--r--src/corelib/kernel/qobject_impl.h425
-rw-r--r--src/corelib/kernel/qobject_p.h3
-rw-r--r--src/corelib/kernel/qobjectcleanuphandler.cpp2
-rw-r--r--src/corelib/kernel/qobjectdefs.h21
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h485
-rw-r--r--src/corelib/kernel/qpointer.cpp6
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp14
-rw-r--r--src/corelib/kernel/qsignalmapper.cpp10
-rw-r--r--src/corelib/kernel/qsystemsemaphore.cpp6
-rw-r--r--src/corelib/kernel/qtimer.cpp18
-rw-r--r--src/corelib/kernel/qtranslator.cpp2
-rw-r--r--src/corelib/kernel/qvariant.cpp39
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp45
-rw-r--r--src/corelib/kernel/qwineventnotifier.h8
33 files changed, 1522 insertions, 758 deletions
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 4b81087e2f..b645d480d7 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -14,6 +14,7 @@ HEADERS += \
kernel/qobject.h \
kernel/qobject_impl.h \
kernel/qobjectdefs.h \
+ kernel/qobjectdefs_impl.h \
kernel/qsignalmapper.h \
kernel/qsocketnotifier.h \
kernel/qtimer.h \
@@ -136,3 +137,10 @@ vxworks {
kernel/qfunctions_vxworks.h
}
+blackberry {
+ SOURCES += \
+ kernel/qeventdispatcher_blackberry.cpp
+ HEADERS += \
+ kernel/qeventdispatcher_blackberry_p.h
+}
+
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index cf9b0cea4f..2ef98dba0f 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -374,7 +374,7 @@ void QAbstractEventDispatcher::closingDown()
Typedef for a function with the signature
- \snippet doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp 0
+ \snippet code/src_corelib_kernel_qabstracteventdispatcher.cpp 0
Note that the type of the \a message is platform dependent. The
following table shows the \a {message}'s type on Windows, Mac, and
@@ -460,7 +460,7 @@ bool QAbstractEventDispatcher::filterEvent(void *message)
This signal is emitted after the event loop returns from a
function that could block.
- \sa wakeUp() aboutToBlock()
+ \sa wakeUp(), aboutToBlock()
*/
/*! \fn void QAbstractEventDispatcher::aboutToBlock()
diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp
index 621223eb88..76db945c45 100644
--- a/src/corelib/kernel/qbasictimer.cpp
+++ b/src/corelib/kernel/qbasictimer.cpp
@@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE
Returns true if the timer is running and has not been stopped; otherwise
returns false.
- \sa start() stop()
+ \sa start(), stop()
*/
/*!
@@ -112,7 +112,7 @@ QT_BEGIN_NAMESPACE
The given \a object will receive timer events.
- \sa stop() isActive() QObject::timerEvent() Qt::CoarseTimer
+ \sa stop(), isActive(), QObject::timerEvent(), Qt::CoarseTimer
*/
void QBasicTimer::start(int msec, QObject *obj)
{
@@ -139,7 +139,7 @@ void QBasicTimer::start(int msec, QObject *obj)
The given \a object will receive timer events.
- \sa stop() isActive() QObject::timerEvent() Qt::TimerType
+ \sa stop(), isActive(), QObject::timerEvent(), Qt::TimerType
*/
void QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
{
@@ -160,7 +160,7 @@ void QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj)
/*!
Stops the timer.
- \sa start() isActive()
+ \sa start(), isActive()
*/
void QBasicTimer::stop()
{
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 048d746183..3fc1b7f801 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -63,7 +63,7 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
-#ifndef QT_NO_CORESERVICES
+#ifndef Q_OS_IOS
#include <CoreServices/CoreServices.h>
#endif
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 56674bc08e..5d70c4c5d8 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -67,10 +67,14 @@
#include <private/qlocale_p.h>
#if defined(Q_OS_UNIX)
-# if !defined(QT_NO_GLIB)
-# include "qeventdispatcher_glib_p.h"
+# if defined(Q_OS_BLACKBERRY)
+# include "qeventdispatcher_blackberry_p.h"
+# else
+# if !defined(QT_NO_GLIB)
+# include "qeventdispatcher_glib_p.h"
+# endif
+# include "qeventdispatcher_unix_p.h"
# endif
-# include "qeventdispatcher_unix_p.h"
#endif
#ifdef Q_OS_WIN
@@ -328,12 +332,16 @@ void QCoreApplicationPrivate::createEventDispatcher()
{
Q_Q(QCoreApplication);
#if defined(Q_OS_UNIX)
+# if defined(Q_OS_BLACKBERRY)
+ eventDispatcher = new QEventDispatcherBlackberry(q);
+# else
# if !defined(QT_NO_GLIB)
if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
eventDispatcher = new QEventDispatcherGlib(q);
else
# endif
eventDispatcher = new QEventDispatcherUNIX(q);
+# endif
#elif defined(Q_OS_WIN)
eventDispatcher = new QEventDispatcherWin32(q);
#else
@@ -1000,7 +1008,7 @@ void QCoreApplication::exit(int returnCode)
The event is \e not deleted when the event has been sent. The normal
approach is to create the event on the stack, for example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 0
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 0
\sa postEvent(), notify()
*/
@@ -1473,7 +1481,7 @@ void QCoreApplicationPrivate::maybeQuit()
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 1
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 1
\sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
*/
@@ -1521,7 +1529,7 @@ void QCoreApplication::quit()
The function returns true on success and false on failure.
- \sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
+ \sa removeTranslator(), translate(), QTranslator::load(), {Dynamic Translation}
*/
bool QCoreApplication::installTranslator(QTranslator *translationFile)
@@ -1634,7 +1642,7 @@ static void replacePercentN(QString *result, int n)
so will most likely result in crashes or other undesirable
behavior.
- \sa QObject::tr() installTranslator()
+ \sa QObject::tr(), installTranslator()
*/
@@ -1910,7 +1918,7 @@ QStringList QCoreApplication::arguments()
organizationName(). On all other platforms, QSettings uses
organizationName() as the organization.
- \sa organizationDomain applicationName
+ \sa organizationDomain, applicationName
*/
void QCoreApplication::setOrganizationName(const QString &orgName)
@@ -1936,7 +1944,7 @@ QString QCoreApplication::organizationName()
On all other platforms, QSettings uses organizationName() as the
organization.
- \sa organizationName applicationName applicationVersion
+ \sa organizationName, applicationName, applicationVersion
*/
void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
{
@@ -1958,7 +1966,7 @@ QString QCoreApplication::organizationDomain()
If not set, the application name defaults to the executable name (since 5.0).
- \sa organizationName organizationDomain applicationVersion applicationFilePath
+ \sa organizationName, organizationDomain, applicationVersion, applicationFilePath
*/
void QCoreApplication::setApplicationName(const QString &application)
{
@@ -1984,7 +1992,7 @@ Q_CORE_EXPORT QString qt_applicationName_noFallback()
\since 4.4
\brief the version of this application
- \sa applicationName organizationName organizationDomain
+ \sa applicationName, organizationName, organizationDomain
*/
void QCoreApplication::setApplicationVersion(const QString &version)
{
@@ -2018,7 +2026,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
If you want to iterate over the list, you can use the \l foreach
pseudo-keyword:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 2
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 2
\sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
{How to Create Qt Plugins}
@@ -2140,7 +2148,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
A function with the following signature that can be used as an
event filter:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 3
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 3
\sa setEventFilter()
*/
@@ -2275,7 +2283,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
The function specified by \a ptr should take no arguments and should
return nothing. For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 4
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 4
Note that for an application- or module-wide cleanup,
qAddPostRoutine() is often not suitable. For example, if the
@@ -2289,7 +2297,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
parent-child mechanism to call a cleanup function at the right
time:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 5
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 5
By selecting the right parent object, this can often be made to
clean up the module's data at the right moment.
@@ -2303,7 +2311,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
translation functions, \c tr() and \c trUtf8(), with these
signatures:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 6
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 6
This macro is useful if you want to use QObject::tr() or
QObject::trUtf8() in classes that don't inherit from QObject.
@@ -2312,7 +2320,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
class definition (before the first \c{public:} or \c{protected:}).
For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 7
+ \snippet code/src_corelib_kernel_qcoreapplication.cpp 7
The \a context parameter is normally the class name, but it can
be any string.
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
new file mode 100644
index 0000000000..462e359bf3
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeventdispatcher_blackberry_p.h"
+#include "qsocketnotifier.h"
+#include "qdebug.h"
+
+#include <bps/bps.h>
+#include <bps/event.h>
+
+struct bpsIOHandlerData {
+ bpsIOHandlerData()
+ : count(0), readfds(0), writefds(0), exceptfds(0)
+ {
+ }
+
+ int count;
+ fd_set *readfds;
+ fd_set *writefds;
+ fd_set *exceptfds;
+};
+
+static int bpsIOReadyDomain = -1;
+
+static int bpsIOHandler(int fd, int io_events, void *data)
+{
+ // decode callback payload
+ bpsIOHandlerData *ioData = static_cast<bpsIOHandlerData*>(data);
+
+ // check if first file is ready
+ bool firstReady = (ioData->count == 0);
+
+ // update ready state of file
+ if (io_events & BPS_IO_INPUT) {
+ FD_SET(fd, ioData->readfds);
+ ioData->count++;
+ }
+
+ if (io_events & BPS_IO_OUTPUT) {
+ FD_SET(fd, ioData->writefds);
+ ioData->count++;
+ }
+
+ if (io_events & BPS_IO_EXCEPT) {
+ FD_SET(fd, ioData->exceptfds);
+ ioData->count++;
+ }
+
+ // force bps_get_event() to return immediately by posting an event to ourselves;
+ // but this only needs to happen once if multiple files become ready at the same time
+ if (firstReady) {
+ // create IO ready event
+ bps_event_t *event;
+ int result = bps_event_create(&event, bpsIOReadyDomain, 0, NULL, NULL);
+ if (result != BPS_SUCCESS) {
+ qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_event_create() failed");
+ return BPS_FAILURE;
+ }
+
+ // post IO ready event to our thread
+ result = bps_push_event(event);
+ if (result != BPS_SUCCESS) {
+ qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_push_event() failed");
+ bps_event_destroy(event);
+ return BPS_FAILURE;
+ }
+ }
+
+ return BPS_SUCCESS;
+}
+
+QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
+ : ioData(new bpsIOHandlerData)
+{
+ // prepare to use BPS
+ int result = bps_initialize();
+ if (result != BPS_SUCCESS)
+ qFatal("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_initialize() failed");
+
+ // get domain for IO ready events - ignoring race condition here for now
+ if (bpsIOReadyDomain == -1) {
+ bpsIOReadyDomain = bps_register_domain();
+ if (bpsIOReadyDomain == -1)
+ qWarning("QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberry: bps_register_domain() failed");
+ }
+
+ // \TODO Reinstate this when bps is fixed. See comment in select() below.
+ // Register thread_pipe[0] with bps
+ /*
+ int io_events = BPS_IO_INPUT;
+ result = bps_add_fd(thread_pipe[0], io_events, &bpsIOHandler, ioData.data());
+ if (result != BPS_SUCCESS)
+ qWarning() << Q_FUNC_INFO << "bps_add_fd() failed";
+ */
+}
+
+QEventDispatcherBlackberryPrivate::~QEventDispatcherBlackberryPrivate()
+{
+ // we're done using BPS
+ bps_shutdown();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+QEventDispatcherBlackberry::QEventDispatcherBlackberry(QObject *parent)
+ : QEventDispatcherUNIX(*new QEventDispatcherBlackberryPrivate, parent)
+{
+}
+
+QEventDispatcherBlackberry::QEventDispatcherBlackberry(QEventDispatcherBlackberryPrivate &dd, QObject *parent)
+ : QEventDispatcherUNIX(dd, parent)
+{
+}
+
+QEventDispatcherBlackberry::~QEventDispatcherBlackberry()
+{
+}
+
+void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_ASSERT(notifier);
+
+ // Call the base Unix implementation. Needed to allow select() to be called correctly
+ QEventDispatcherUNIX::registerSocketNotifier(notifier);
+
+ // Register the fd with bps
+ int sockfd = notifier->socket();
+ int type = notifier->type();
+
+ int io_events = 0;
+ switch (type) {
+ case QSocketNotifier::Read:
+ io_events |= BPS_IO_INPUT;
+ break;
+ case QSocketNotifier::Write:
+ io_events |= BPS_IO_OUTPUT;
+ break;
+ case QSocketNotifier::Exception:
+ default:
+ io_events |= BPS_IO_EXCEPT;
+ break;
+ }
+
+ Q_D(QEventDispatcherBlackberry);
+ int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
+ if (result != BPS_SUCCESS)
+ qWarning() << Q_FUNC_INFO << "bps_add_fd() failed";
+}
+
+void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier)
+{
+ // Unregister the fd with bps
+ int sockfd = notifier->socket();
+ int result = bps_remove_fd(sockfd);
+ if (result != BPS_SUCCESS)
+ qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed";
+
+ // Allow the base Unix implementation to unregister the fd too
+ QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
+}
+
+int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ timeval *timeout)
+{
+ Q_UNUSED(nfds);
+
+ // prepare file sets for bps callback
+ Q_D(QEventDispatcherBlackberry);
+ d->ioData->count = 0;
+ d->ioData->readfds = readfds;
+ d->ioData->writefds = writefds;
+ d->ioData->exceptfds = exceptfds;
+
+ // \TODO Remove this when bps is fixed
+ //
+ // Work around a bug in BPS with which if we register the thread_pipe[0] fd with bps in the
+ // private class' ctor once only then we get spurious notifications that thread_pipe[0] is
+ // ready for reading. The first time the notification is correct and the pipe is emptied in
+ // the calling doSelect() function. The 2nd notification is an error and the resulting attempt
+ // to read and call to wakeUps.testAndSetRelease(1, 0) fails as there has been no intervening
+ // call to QEventDispatcherUNIX::wakeUp().
+ //
+ // Registering thread_pipe[0] here and unregistering it at the end of this call works around
+ // this issue.
+ int io_events = BPS_IO_INPUT;
+ int result = bps_add_fd(d->thread_pipe[0], io_events, &bpsIOHandler, d->ioData.data());
+ if (result != BPS_SUCCESS)
+ qWarning() << Q_FUNC_INFO << "bps_add_fd() failed";
+
+ // reset all file sets
+ if (readfds)
+ FD_ZERO(readfds);
+
+ if (writefds)
+ FD_ZERO(writefds);
+
+ if (exceptfds)
+ FD_ZERO(exceptfds);
+
+ // convert timeout to milliseconds
+ int timeout_ms = -1;
+ if (timeout)
+ timeout_ms = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
+
+ // wait for event or file to be ready
+ bps_event_t *event = NULL;
+ result = bps_get_event(&event, timeout_ms);
+ if (result != BPS_SUCCESS)
+ qWarning("QEventDispatcherBlackberry::select: bps_get_event() failed");
+
+ // pass all received events through filter - except IO ready events
+ if (event && bps_event_get_domain(event) != bpsIOReadyDomain)
+ filterEvent((void*)event);
+
+ // \TODO Remove this when bps is fixed (see comment above)
+ result = bps_remove_fd(d->thread_pipe[0]);
+ if (result != BPS_SUCCESS)
+ qWarning() << Q_FUNC_INFO << "bps_remove_fd() failed";
+
+ // the number of bits set in the file sets
+ return d->ioData->count;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
new file mode 100644
index 0000000000..b996bc7ee7
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTDISPATCHER_BLACKBERRY_P_H
+#define QEVENTDISPATCHER_BLACKBERRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qeventdispatcher_unix_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEventDispatcherBlackberryPrivate;
+
+class Q_CORE_EXPORT QEventDispatcherBlackberry : public QEventDispatcherUNIX
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QEventDispatcherBlackberry)
+
+public:
+ explicit QEventDispatcherBlackberry(QObject *parent = 0);
+ ~QEventDispatcherBlackberry();
+
+ void registerSocketNotifier(QSocketNotifier *notifier);
+ void unregisterSocketNotifier(QSocketNotifier *notifier);
+
+protected:
+ QEventDispatcherBlackberry(QEventDispatcherBlackberryPrivate &dd, QObject *parent = 0);
+
+ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ timeval *timeout);
+};
+
+struct bpsIOHandlerData;
+
+class Q_CORE_EXPORT QEventDispatcherBlackberryPrivate : public QEventDispatcherUNIXPrivate
+{
+ Q_DECLARE_PUBLIC(QEventDispatcherBlackberry)
+
+public:
+ QEventDispatcherBlackberryPrivate();
+ ~QEventDispatcherBlackberryPrivate();
+
+ QScopedPointer<bpsIOHandlerData> ioData;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_BLACKBERRY_P_H
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index d3a64aae04..deea463061 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -275,7 +275,7 @@ void QEventLoop::exit(int returnCode)
false. The event loop is considered running from the time when
exec() is called until exit() is called.
- \sa exec() exit()
+ \sa exec(), exit()
*/
bool QEventLoop::isRunning() const
{
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index e3b0b15e26..4e05b63c82 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -146,23 +146,17 @@ QT_BEGIN_NAMESPACE
static inline const QMetaObjectPrivate *priv(const uint* data)
{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
-static inline const QByteArrayData &stringData(const QMetaObject *mo, int index)
+static inline const QByteArray stringData(const QMetaObject *mo, int index)
{
Q_ASSERT(priv(mo->d.data)->revision >= 7);
- const QByteArrayData &data = mo->d.stringdata[index];
- Q_ASSERT(data.ref.isStatic());
- Q_ASSERT(data.alloc == 0);
- Q_ASSERT(data.capacityReserved == 0);
- Q_ASSERT(data.size >= 0);
+ const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
+ Q_ASSERT(data.ptr->ref.isStatic());
+ Q_ASSERT(data.ptr->alloc == 0);
+ Q_ASSERT(data.ptr->capacityReserved == 0);
+ Q_ASSERT(data.ptr->size >= 0);
return data;
}
-static inline QByteArray toByteArray(const QByteArrayData &d)
-{
- QByteArrayDataPtr holder = { const_cast<QByteArrayData *>(&d) };
- return QByteArray(holder);
-}
-
static inline const char *rawStringData(const QMetaObject *mo, int index)
{
return stringData(mo, index).data();
@@ -170,13 +164,13 @@ static inline const char *rawStringData(const QMetaObject *mo, int index)
static inline int stringSize(const QMetaObject *mo, int index)
{
- return stringData(mo, index).size;
+ return stringData(mo, index).size();
}
static inline QByteArray typeNameFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
if (typeInfo & IsUnresolvedType) {
- return toByteArray(stringData(mo, typeInfo & TypeNameIndexMask));
+ return stringData(mo, typeInfo & TypeNameIndexMask);
} else {
// ### Use the QMetaType::typeName() that returns QByteArray
const char *t = QMetaType::typeName(typeInfo);
@@ -193,7 +187,7 @@ static inline int typeFromTypeInfo(const QMetaObject *mo, uint typeInfo)
{
if (!(typeInfo & IsUnresolvedType))
return typeInfo;
- return QMetaType::type(toByteArray(stringData(mo, typeInfo & TypeNameIndexMask)));
+ return QMetaType::type(stringData(mo, typeInfo & TypeNameIndexMask));
}
class QMetaMethodPrivate : public QMetaMethod
@@ -294,11 +288,10 @@ QObject *QMetaObject::newInstance(QGenericArgument val0,
*/
int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
{
- const QMetaObjectExtraData *extra = reinterpret_cast<const QMetaObjectExtraData *>(d.extradata);
Q_ASSERT(priv(d.data)->revision >= 6);
- if (!extra || !extra->static_metacall)
+ if (!d.static_metacall)
return 0;
- extra->static_metacall(0, cl, idx, argv);
+ d.static_metacall(0, cl, idx, argv);
return -1;
}
@@ -492,7 +485,7 @@ int QMetaObject::constructorCount() const
Use code like the following to obtain a QStringList containing the methods
specific to a given class:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp methodCount
+ \snippet code/src_corelib_kernel_qmetaobject.cpp methodCount
\sa method(), methodOffset(), indexOfMethod()
*/
@@ -530,7 +523,7 @@ int QMetaObject::enumeratorCount() const
Use code like the following to obtain a QStringList containing the properties
specific to a given class:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp propertyCount
+ \snippet code/src_corelib_kernel_qmetaobject.cpp propertyCount
\sa property(), propertyOffset(), indexOfProperty()
*/
@@ -572,7 +565,7 @@ static bool methodMatch(const QMetaObject *m, int handle,
if (int(m->d.data[handle + 1]) != argc)
return false;
- if (toByteArray(stringData(m, m->d.data[handle])) != name)
+ if (stringData(m, m->d.data[handle]) != name)
return false;
int paramsIndex = m->d.data[handle + 2] + 1;
@@ -659,6 +652,7 @@ int QMetaObject::indexOfMethod(const char *method) const
}
// Parses a string of comma-separated types into QArgumentTypes.
+// No normalization of the type names is performed.
static void argumentTypesFromString(const char *str, const char *end,
QArgumentTypeArray &types)
{
@@ -812,6 +806,35 @@ int QMetaObjectPrivate::indexOfConstructor(const QMetaObject *m, const QByteArra
return -1;
}
+/*! \internal
+ Returns the signal for the given \a metaObject at \a signal_index.
+
+ It it different from QMetaObject::method(); the index should not include
+ non-signal methods.
+
+ The index must correspond to a signal defined in \ a metaObject itself;
+ it should not be an inherited signal.
+*/
+QMetaMethod QMetaObjectPrivate::signal(const QMetaObject *metaObject, int signal_index)
+{
+ QMetaMethod result;
+ if (signal_index < 0)
+ return result;
+ Q_ASSERT(metaObject != 0);
+
+ int signalOffset = 0;
+ for (const QMetaObject *m = metaObject->d.superdata; m; m = m->d.superdata)
+ signalOffset += priv(m->d.data)->signalCount;
+
+ Q_ASSERT(signal_index >= signalOffset);
+ int signal_index_relative = signal_index - signalOffset;
+ if (signal_index_relative < priv(metaObject->d.data)->signalCount) {
+ result.mobj = metaObject;
+ result.handle = priv(metaObject->d.data)->methodData + 5*signal_index_relative;
+ }
+ return result;
+}
+
/*!
\internal
@@ -869,11 +892,9 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co
while (self) {
if (strcmp(rawStringData(self, 0), name) == 0)
return self;
- if (self->d.extradata) {
- const QMetaObject **e;
+ if (self->d.relatedMetaObjects) {
Q_ASSERT(priv(self->d.data)->revision >= 2);
- const QMetaObjectExtraData *extra = (const QMetaObjectExtraData*)(self->d.extradata);
- e = extra->objects;
+ const QMetaObject **e = self->d.relatedMetaObjects;
if (e) {
while (*e) {
if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name))
@@ -1102,7 +1123,7 @@ QMetaProperty QMetaObject::userProperty() const
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 0
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 0
\sa classInfoCount(), classInfoOffset(), indexOfClassInfo()
*/
@@ -1207,7 +1228,7 @@ static char *qNormalizeType(char *d, int &templdepth, QByteArray &result)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 1
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 1
\sa normalizedSignature()
*/
@@ -1312,7 +1333,7 @@ enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
the \l{QPushButton::animateClick()}{animateClick()} slot on a
QPushButton, use the following code:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 2
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 2
With asynchronous method invocations, the parameters must be of
types that are known to Qt's meta-object system, because Qt needs
@@ -1320,7 +1341,7 @@ enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
scenes. If you try to use a queued connection and get the error
message
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 3
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 3
call qRegisterMetaType() to register the data type before you
call invokeMethod().
@@ -1328,7 +1349,7 @@ enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
To synchronously invoke the \c compute(QString, int, double) slot on
some arbitrary object \c obj retrieve its return value:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 4
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 4
If the "compute" slot does not take exactly one QString, one int
and one double in the specified order, the call will fail.
@@ -1483,6 +1504,24 @@ bool QMetaObject::invokeMethod(QObject *obj,
invoked), otherwise returns false.
*/
+/*! \fn bool operator==(const QMetaMethod &m1, const QMetaMethod &m2)
+ \since 5.0
+ \relates QMetaMethod
+ \overload
+
+ Returns true if method \a m1 is equal to method \a m2,
+ otherwise returns false.
+*/
+
+/*! \fn bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
+ \since 5.0
+ \relates QMetaMethod
+ \overload
+
+ Returns true if method \a m1 is not equal to method \a m2,
+ otherwise returns false.
+*/
+
/*!
\fn const QMetaObject *QMetaMethod::enclosingMetaObject() const
\internal
@@ -1522,7 +1561,7 @@ QByteArray QMetaMethodPrivate::signature() const
QByteArray QMetaMethodPrivate::name() const
{
Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- return toByteArray(stringData(mobj, mobj->d.data[handle]));
+ return stringData(mobj, mobj->d.data[handle]);
}
int QMetaMethodPrivate::typesDataIndex() const
@@ -1599,14 +1638,14 @@ QList<QByteArray> QMetaMethodPrivate::parameterNames() const
int argc = parameterCount();
int namesIndex = parametersDataIndex() + argc;
for (int i = 0; i < argc; ++i)
- list += toByteArray(stringData(mobj, mobj->d.data[namesIndex + i]));
+ list += stringData(mobj, mobj->d.data[namesIndex + i]);
return list;
}
QByteArray QMetaMethodPrivate::tag() const
{
Q_ASSERT(priv(mobj->d.data)->revision >= 7);
- return toByteArray(stringData(mobj, mobj->d.data[handle + 3]));
+ return stringData(mobj, mobj->d.data[handle + 3]);
}
/*!
@@ -1848,6 +1887,41 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
}
/*!
+ \fn QMetaMethod QMetaMethod::fromSignal(PointerToMemberFunction signal)
+ \since 5.0
+
+ Returns the meta-method that corresponds to the given \a signal, or an
+ invalid QMetaMethod if \a signal is not a signal of the class.
+
+ Example:
+
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 9
+*/
+
+/*! \internal
+
+ Implementation of the fromSignal() function.
+
+ \a metaObject is the class's meta-object
+ \a signal is a pointer to a pointer to a member signal of the class
+*/
+QMetaMethod QMetaMethod::fromSignalImpl(const QMetaObject *metaObject, void **signal)
+{
+ int i = -1;
+ void *args[] = { &i, signal };
+ QMetaMethod result;
+ for (const QMetaObject *m = metaObject; m; m = m->d.superdata) {
+ m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
+ if (i >= 0) {
+ result.mobj = m;
+ result.handle = priv(m->d.data)->methodData + 5*i;
+ break;
+ }
+ }
+ return result;
+}
+
+/*!
Invokes this method on the object \a object. Returns true if the member could be invoked.
Returns false if there is no such member or the parameters did not match.
@@ -1883,7 +1957,7 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
\l{QPushButton::animateClick()}{animateClick()} slot on a
QPushButton:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 6
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 6
With asynchronous method invocations, the parameters must be of
types that are known to Qt's meta-object system, because Qt needs
@@ -1891,7 +1965,7 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
scenes. If you try to use a queued connection and get the error
message
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 7
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 7
call qRegisterMetaType() to register the data type before you
call QMetaMethod::invoke().
@@ -1899,7 +1973,7 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
To synchronously invoke the \c compute(QString, int, double) slot on
some arbitrary object \c obj retrieve its return value:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 8
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 8
QMetaObject::normalizedSignature() is used here to ensure that the format
of the signature is what invoke() expects. E.g. extra whitespace is
@@ -2012,8 +2086,7 @@ bool QMetaMethod::invoke(QObject *object,
int idx_relative = ((handle - priv(mobj->d.data)->methodData) / 5);
int idx_offset = mobj->methodOffset();
Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6);
- QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.extradata
- ? reinterpret_cast<const QMetaObjectExtraData *>(mobj->d.extradata)->static_metacall : 0;
+ QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall;
if (connectionType == Qt::DirectConnection) {
if (callFunction) {
@@ -2391,7 +2464,7 @@ QByteArray QMetaEnum::valueToKeys(int value) const
v = v & ~k;
if (!keys.isEmpty())
keys += '|';
- keys += toByteArray(stringData(mobj, mobj->d.data[data + 2*i]));
+ keys += stringData(mobj, mobj->d.data[data + 2*i]);
}
}
return keys;
@@ -3058,7 +3131,7 @@ bool QMetaProperty::isEditable(const QObject *object) const
are specified using Q_CLASSINFO() in the source code. The
information can be retrieved using name() and value(). For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp 5
+ \snippet code/src_corelib_kernel_qmetaobject.cpp 5
This mechanism is free for you to use in your Qt applications. Qt
doesn't use it for any of its classes.
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index 095b196dca..1c49506926 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -141,6 +141,20 @@ public:
inline bool isValid() const { return mobj != 0; }
+#ifdef Q_QDOC
+ static QMetaMethod fromSignal(PointerToMemberFunction signal);
+#else
+ template <typename Func>
+ static inline QMetaMethod fromSignal(Func signal)
+ {
+ typedef QtPrivate::FunctionPointer<Func> SignalType;
+ reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(
+ *reinterpret_cast<typename SignalType::Object *>(0));
+ return fromSignalImpl(&SignalType::Object::staticMetaObject,
+ reinterpret_cast<void **>(&signal));
+ }
+#endif
+
private:
#if QT_DEPRECATED_SINCE(5,0)
// signature() has been renamed to methodSignature() in Qt 5.
@@ -148,6 +162,7 @@ private:
// you convert to char*.
char *signature(struct renamedInQt5_warning_checkTheLifeTime * = 0) Q_DECL_EQ_DELETE;
#endif
+ static QMetaMethod fromSignalImpl(const QMetaObject *, void **);
const QMetaObject *mobj;
uint handle;
@@ -155,9 +170,16 @@ private:
friend struct QMetaObject;
friend struct QMetaObjectPrivate;
friend class QObject;
+ friend bool operator==(const QMetaMethod &m1, const QMetaMethod &m2);
+ friend bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2);
};
Q_DECLARE_TYPEINFO(QMetaMethod, Q_MOVABLE_TYPE);
+inline bool operator==(const QMetaMethod &m1, const QMetaMethod &m2)
+{ return m1.mobj == m2.mobj && m1.handle == m2.handle; }
+inline bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2)
+{ return !(m1 == m2); }
+
class Q_CORE_EXPORT QMetaEnum
{
public:
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 3b732b4b93..5877ab18e4 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -110,6 +110,8 @@ enum MetaDataFlags {
TypeNameIndexMask = 0x7FFFFFFF
};
+extern int qMetaTypeTypeInternal(const char *);
+
class QArgumentType
{
public:
@@ -117,7 +119,7 @@ public:
: _type(type)
{}
QArgumentType(const QByteArray &name)
- : _type(QMetaType::type(name.constData())), _name(name)
+ : _type(qMetaTypeTypeInternal(name.constData())), _name(name)
{}
QArgumentType()
: _type(0)
@@ -198,6 +200,7 @@ struct QMetaObjectPrivate
int argc, const QArgumentType *types);
static int indexOfConstructor(const QMetaObject *m, const QByteArray &name,
int argc, const QArgumentType *types);
+ static QMetaMethod signal(const QMetaObject *m, int signal_index);
static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
int methodArgc, const QArgumentType *methodTypes);
static bool checkConnectArgs(const QMetaMethodPrivate *signal,
@@ -211,10 +214,12 @@ struct QMetaObjectPrivate
static void memberIndexes(const QObject *obj, const QMetaMethod &member,
int *signalIndex, int *methodIndex);
static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
+ const QMetaObject *smeta,
const QObject *receiver, int method_index_relative,
const QMetaObject *rmeta = 0,
int type = 0, int *types = 0);
static bool disconnect(const QObject *sender, int signal_index,
+ const QMetaObject *smeta,
const QObject *receiver, int method_index, void **slot,
DisconnectType = DisconnectAll);
static inline bool disconnectHelper(QObjectPrivate::Connection *c,
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index d262d6a61b..16ff58e1ca 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -609,7 +609,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
\a name. Returns an object that can be used to adjust
the other attributes of the enumerator.
- \sa enumerator(), enumeratorCount(), removeEnumerator(),
+ \sa enumerator(), enumeratorCount(), removeEnumerator()
\sa indexOfEnumerator()
*/
QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
@@ -625,7 +625,7 @@ QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
QMetaObject. Returns an object that can be used to adjust the
attributes of the enumerator.
- \sa enumerator(), enumeratorCount(), removeEnumerator(),
+ \sa enumerator(), enumeratorCount(), removeEnumerator()
\sa indexOfEnumerator()
*/
QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype)
@@ -737,13 +737,8 @@ void QMetaObjectBuilder::addMetaObject
}
if ((members & RelatedMetaObjects) != 0) {
- const QMetaObject **objects;
Q_ASSERT(priv(prototype->d.data)->revision >= 2);
- const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
- if (extra)
- objects = extra->objects;
- else
- objects = 0;
+ const QMetaObject **objects = prototype->d.relatedMetaObjects;
if (objects) {
while (*objects != 0) {
addRelatedMetaObject(*objects);
@@ -754,10 +749,8 @@ void QMetaObjectBuilder::addMetaObject
if ((members & StaticMetacall) != 0) {
Q_ASSERT(priv(prototype->d.data)->revision >= 6);
- const QMetaObjectExtraData *extra =
- (const QMetaObjectExtraData *)(prototype->d.extradata);
- if (extra && extra->static_metacall)
- setStaticMetacallFunction(extra->static_metacall);
+ if (prototype->d.static_metacall)
+ setStaticMetacallFunction(prototype->d.static_metacall);
}
}
@@ -1150,7 +1143,7 @@ static int aggregateParameterCount(const QList<QMetaMethodBuilderPrivate> &metho
// Build a QMetaObject in "buf" based on the information in "d".
// If "buf" is null, then return the number of bytes needed to
// build the QMetaObject. Returns -1 if the metaobject if
-// relocatable is set, but the metaobject contains extradata.
+// relocatable is set, but the metaobject contains relatedMetaObjects.
static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
int expectedSize, bool relocatable)
{
@@ -1174,7 +1167,9 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
ALIGN(size, int);
if (buf) {
if (!relocatable) meta->d.superdata = d->superClass;
+ meta->d.relatedMetaObjects = 0;
meta->d.extradata = 0;
+ meta->d.static_metacall = d->staticMetacallFunction;
}
// Populate the QMetaObjectPrivate structure.
@@ -1446,30 +1441,18 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
if (buf)
data[enumIndex] = 0;
- // Create the extradata block if we need one.
- if (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction) {
- ALIGN(size, QMetaObject **);
- ALIGN(size, QMetaObjectBuilder::StaticMetacallFunction);
- QMetaObjectExtraData *extra =
- reinterpret_cast<QMetaObjectExtraData *>(buf + size);
- size += sizeof(QMetaObjectExtraData);
+ // Create the relatedMetaObjects block if we need one.
+ if (d->relatedMetaObjects.size() > 0) {
ALIGN(size, QMetaObject *);
const QMetaObject **objects =
reinterpret_cast<const QMetaObject **>(buf + size);
if (buf) {
- if (d->relatedMetaObjects.size() > 0) {
- extra->objects = objects;
- for (index = 0; index < d->relatedMetaObjects.size(); ++index)
- objects[index] = d->relatedMetaObjects[index];
- objects[index] = 0;
- } else {
- extra->objects = 0;
- }
- extra->static_metacall = d->staticMetacallFunction;
- meta->d.extradata = reinterpret_cast<void *>(extra);
+ meta->d.relatedMetaObjects = objects;
+ for (index = 0; index < d->relatedMetaObjects.size(); ++index)
+ objects[index] = d->relatedMetaObjects[index];
+ objects[index] = 0;
}
- if (d->relatedMetaObjects.size() > 0)
- size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1);
+ size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1);
}
// Align the final size and return it.
@@ -1552,6 +1535,8 @@ void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
output->d.stringdata = reinterpret_cast<const QByteArrayData *>(buf + stringdataOffset);
output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
output->d.extradata = 0;
+ output->d.relatedMetaObjects = 0;
+ output->d.static_metacall = 0;
}
/*!
diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h
index 4d766a9197..7c18298d35 100644
--- a/src/corelib/kernel/qmetaobjectbuilder_p.h
+++ b/src/corelib/kernel/qmetaobjectbuilder_p.h
@@ -165,7 +165,7 @@ public:
int indexOfEnumerator(const QByteArray& name);
int indexOfClassInfo(const QByteArray& name);
- typedef QMetaObjectExtraData::StaticMetacallFunction StaticMetacallFunction;
+ typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 53b22958c3..2756dd5241 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -125,16 +125,16 @@ struct DefinedTypesFilter {
This example shows a typical use case of Q_DECLARE_METATYPE():
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 0
+ \snippet code/src_corelib_kernel_qmetatype.cpp 0
If \c MyStruct is in a namespace, the Q_DECLARE_METATYPE() macro
has to be outside the namespace:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 1
+ \snippet code/src_corelib_kernel_qmetatype.cpp 1
Since \c{MyStruct} is now known to QMetaType, it can be used in QVariant:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 2
+ \snippet code/src_corelib_kernel_qmetatype.cpp 2
\sa qRegisterMetaType()
*/
@@ -220,21 +220,13 @@ struct DefinedTypesFilter {
\value User Base value for user types
\value UnknownType This is an invalid type id. It is returned from QMetaType for types that are not registered
- \omitvalue FirstGuiType
- \omitvalue FirstWidgetsType
- \omitvalue LastCoreType
- \omitvalue LastGuiType
- \omitvalue LastWidgetsType
- \omitvalue QReal
- \omitvalue HighestInternalId
-
Additional types can be registered using Q_DECLARE_METATYPE().
\sa type(), typeName()
*/
/*!
- \enum QMetaType::TypeFlags
+ \enum QMetaType::TypeFlag
The enum describes attributes of a type supported by QMetaType.
@@ -265,7 +257,7 @@ struct DefinedTypesFilter {
The following code allocates and destructs an instance of
\c{MyClass}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 3
+ \snippet code/src_corelib_kernel_qmetatype.cpp 3
If we want the stream operators \c operator<<() and \c
operator>>() to work on QVariant objects that store custom types,
@@ -449,16 +441,37 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
int size, TypeFlags flags, const QMetaObject *metaObject)
{
Q_UNUSED(metaObject);
- QVector<QCustomTypeInfo> *ct = customTypes();
- if (!ct || !typeName || !deleter || !creator || !destructor || !constructor)
- return -1;
-
#ifdef QT_NO_QOBJECT
NS(QByteArray) normalizedTypeName = typeName;
#else
NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
#endif
+ return registerNormalizedType(normalizedTypeName, deleter, creator, destructor, constructor, size, flags, metaObject);
+}
+
+
+/*! \internal
+ \since 5.0
+
+ Registers a user type for marshalling, with \a normalizedTypeName, a \a
+ deleter, a \a creator, a \a destructor, a \a constructor, and
+ a \a size. Returns the type's handle, or -1 if the type could
+ not be registered. Note that normalizedTypeName is not checked for
+ conformance with Qt's normalized format, so it must already
+ conform.
+ */
+int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
+ Creator creator,
+ Destructor destructor,
+ Constructor constructor,
+ int size, TypeFlags flags, const QMetaObject *metaObject)
+{
+ Q_UNUSED(metaObject);
+ QVector<QCustomTypeInfo> *ct = customTypes();
+ if (!ct || normalizedTypeName.isEmpty() || !deleter || !creator || !destructor || !constructor)
+ return -1;
+
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
normalizedTypeName.size());
@@ -521,16 +534,28 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
*/
int QMetaType::registerTypedef(const char* typeName, int aliasId)
{
- QVector<QCustomTypeInfo> *ct = customTypes();
- if (!ct || !typeName)
- return -1;
-
#ifdef QT_NO_QOBJECT
NS(QByteArray) normalizedTypeName = typeName;
#else
NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
#endif
+ return registerNormalizedTypedef(normalizedTypeName, aliasId);
+}
+
+/*! \internal
+ \since 5.0
+
+ Registers a user type for marshalling, as an alias of another type (typedef).
+ Note that normalizedTypeName is not checked for conformance with Qt's normalized format,
+ so it must already conform.
+*/
+int QMetaType::registerNormalizedTypedef(const NS(QByteArray) &normalizedTypeName, int aliasId)
+{
+ QVector<QCustomTypeInfo> *ct = customTypes();
+ if (!ct || normalizedTypeName.isEmpty())
+ return -1;
+
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
normalizedTypeName.size());
@@ -581,26 +606,26 @@ bool QMetaType::isRegistered(int type)
}
/*!
- Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is
- no such type.
+ \internal
- \sa isRegistered(), typeName(), Type
+ Implementation of QMetaType::type().
*/
-int QMetaType::type(const char *typeName)
+template <int tryNormalizedType>
+static inline int qMetaTypeTypeImpl(const char *typeName)
{
int length = qstrlen(typeName);
if (!length)
- return UnknownType;
+ return QMetaType::UnknownType;
int type = qMetaTypeStaticType(typeName, length);
- if (type == UnknownType) {
+ if (type == QMetaType::UnknownType) {
QReadLocker locker(customTypesLock());
type = qMetaTypeCustomType_unlocked(typeName, length);
#ifndef QT_NO_QOBJECT
- if (type == UnknownType) {
+ if ((type == QMetaType::UnknownType) && tryNormalizedType) {
const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
type = qMetaTypeStaticType(normalizedTypeName.constData(),
normalizedTypeName.size());
- if (type == UnknownType) {
+ if (type == QMetaType::UnknownType) {
type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
normalizedTypeName.size());
}
@@ -610,6 +635,29 @@ int QMetaType::type(const char *typeName)
return type;
}
+/*!
+ Returns a handle to the type called \a typeName, or QMetaType::UnknownType if there is
+ no such type.
+
+ \sa isRegistered(), typeName(), Type
+*/
+int QMetaType::type(const char *typeName)
+{
+ return qMetaTypeTypeImpl</*tryNormalizedType=*/true>(typeName);
+}
+
+/*!
+ \a internal
+
+ Similar to QMetaType::type(); the only difference is that this function
+ doesn't attempt to normalize the type name (i.e., the lookup will fail
+ for type names in non-normalized form).
+*/
+int qMetaTypeTypeInternal(const char *typeName)
+{
+ return qMetaTypeTypeImpl</*tryNormalizedType=*/false>(typeName);
+}
+
#ifndef QT_NO_DATASTREAM
/*!
Writes the object pointed to by \a data with the ID \a type to
@@ -1486,12 +1534,12 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type)
This example registers the class \c{MyClass}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 4
+ \snippet code/src_corelib_kernel_qmetatype.cpp 4
This function is useful to register typedefs so they can be used
by QMetaProperty, or in QueuedConnections
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 9
+ \snippet code/src_corelib_kernel_qmetatype.cpp 9
\sa qRegisterMetaTypeStreamOperators(), QMetaType::isRegistered(),
Q_DECLARE_METATYPE()
@@ -1509,11 +1557,11 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type)
QMetaType::save(). These functions are used when streaming a
QVariant.
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 5
+ \snippet code/src_corelib_kernel_qmetatype.cpp 5
The stream operators should have the following signatures:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 6
+ \snippet code/src_corelib_kernel_qmetatype.cpp 6
\sa qRegisterMetaType(), QMetaType::isRegistered(), Q_DECLARE_METATYPE()
*/
@@ -1548,7 +1596,7 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 7
+ \snippet code/src_corelib_kernel_qmetatype.cpp 7
To use the type \c T in QVariant, using Q_DECLARE_METATYPE() is
sufficient. To use the type \c T in queued signal and slot connections,
@@ -1574,7 +1622,7 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type)
Typical usage:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp 8
+ \snippet code/src_corelib_kernel_qmetatype.cpp 8
QMetaType::type() returns the same ID as qMetaTypeId(), but does
a lookup at runtime based on the name of the type.
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 21f4bc7afe..595da53562 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -45,8 +45,11 @@
#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
+#include <QtCore/qvarlengtharray.h>
#include <QtCore/qisenum.h>
-
+#ifndef QT_NO_QOBJECT
+#include <QtCore/qobjectdefs.h>
+#endif
#include <new>
#ifdef Bool
@@ -195,6 +198,8 @@ class Q_CORE_EXPORT QMetaType {
FlagsEx = 0x100
};
public:
+#ifndef Q_QDOC
+ // The code that actually gets compiled.
enum Type {
// these are merged with QVariant
QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID)
@@ -212,6 +217,29 @@ public:
UnknownType = 0,
User = 1024
};
+#else
+ // If we are using QDoc it fakes the Type enum looks like this.
+ enum Type {
+ Void = 0, Bool = 1, Int = 2, UInt = 3, LongLong = 4, ULongLong = 5,
+ Double = 6, Long = 32, Short = 33, Char = 34, ULong = 35, UShort = 36,
+ UChar = 37, Float = 38,
+ VoidStar = 31,
+ QChar = 7, QString = 10, QStringList = 11, QByteArray = 12,
+ QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
+ QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
+ QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27,
+ QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42,
+ QObjectStar = 39, QWidgetStar = 40,
+ QVariantMap = 8, QVariantList = 9, QVariantHash = 28,
+ QFont = 64, QPixmap = 65, QBrush = 66, QColor = 67, QPalette = 68,
+ QImage = 69, QPolygon = 70, QRegion = 71, QBitmap = 72, QCursor = 73,
+ QKeySequence = 74, QPen = 75, QTextLength = 76, QTextFormat = 77,
+ QMatrix = 78, QTransform = 79, QMatrix4x4 = 80, QVector2D = 81,
+ QVector3D = 82, QVector4D = 83, QQuaternion = 84, QPolygonF = 85,
+ QIcon = 120, QSizePolicy = 121,
+ User = 256
+ };
+#endif
enum TypeFlag {
NeedsConstruction = 0x1,
@@ -245,7 +273,15 @@ public:
int size,
QMetaType::TypeFlags flags,
const QMetaObject *metaObject);
+ static int registerNormalizedType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, Deleter deleter,
+ Creator creator,
+ Destructor destructor,
+ Constructor constructor,
+ int size,
+ QMetaType::TypeFlags flags,
+ const QMetaObject *metaObject);
static int registerTypedef(const char *typeName, int aliasId);
+ static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId);
static int type(const char *typeName);
static const char *typeName(int type);
static int sizeOf(int type);
@@ -480,7 +516,7 @@ namespace QtPrivate {
}
template <typename T>
-int qRegisterMetaType(const char *typeName
+int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
#ifndef qdoc
, T * dummy = 0
#endif
@@ -488,10 +524,10 @@ int qRegisterMetaType(const char *typeName
{
const int typedefOf = dummy ? -1 : QtPrivate::QMetaTypeIdHelper<T>::qt_metatype_id();
if (typedefOf != -1)
- return QMetaType::registerTypedef(typeName, typedefOf);
+ return QMetaType::registerNormalizedTypedef(normalizedTypeName, typedefOf);
QMetaType::TypeFlags flags(QtPrivate::QMetaTypeTypeFlags<T>::Flags);
- return QMetaType::registerType(typeName, qMetaTypeDeleteHelper<T>,
+ return QMetaType::registerNormalizedType(normalizedTypeName, qMetaTypeDeleteHelper<T>,
qMetaTypeCreateHelper<T>,
qMetaTypeDestructHelper<T>,
qMetaTypeConstructHelper<T>,
@@ -500,6 +536,21 @@ int qRegisterMetaType(const char *typeName
QtPrivate::MetaObjectForType<T>::value());
}
+template <typename T>
+int qRegisterMetaType(const char *typeName
+#ifndef qdoc
+ , T * dummy = 0
+#endif
+)
+{
+#ifdef QT_NO_QOBJECT
+ QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName;
+#else
+ QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
+#endif
+ return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy);
+}
+
#ifndef QT_NO_DATASTREAM
template <typename T>
void qRegisterMetaTypeStreamOperators(const char *typeName
@@ -548,9 +599,14 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
static int qt_metatype_id()
{
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
- if (!metatype_id.load())
- metatype_id.storeRelease(qRegisterMetaType<T*>(QByteArray(T::staticMetaObject.className() + QByteArrayLiteral("*")).constData(),
+ if (!metatype_id.load()) {
+ const int len = int(strlen(T::staticMetaObject.className()));
+ QVarLengthArray<char, 16> classNameStar;
+ classNameStar.append(T::staticMetaObject.className(), len);
+ classNameStar.append("*\0", 2);
+ metatype_id.storeRelease(qRegisterMetaType<T*>(classNameStar.constData(),
reinterpret_cast<T**>(quintptr(-1))));
+ }
return metatype_id.loadAcquire();
}
};
@@ -687,6 +743,7 @@ inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeI
, m_loadOp(loadOp)
, m_constructor(constructor)
, m_destructor(destructor)
+ , m_extension(0)
, m_size(size)
, m_typeFlags(theTypeFlags)
, m_extensionFlags(extensionFlags)
diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h
index 74229d3f3c..b593489963 100644
--- a/src/corelib/kernel/qmetatype_p.h
+++ b/src/corelib/kernel/qmetatype_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
namespace QModulesPrivate {
enum Names { Core, Gui, Widgets, Unknown, ModulesCount /* ModulesCount has to be at the end */ };
-static inline int moduleForType(const int typeId)
+static inline int moduleForType(const uint typeId)
{
if (typeId <= QMetaType::LastCoreType)
return Core;
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 3a3464e43e..c18ce22247 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -257,7 +257,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
For example, if your write a widget that accepts URL drags, you
would end up writing code like this:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 0
+ \snippet code/src_corelib_kernel_qmimedata.cpp 0
There are three approaches for storing custom data in a QMimeData
object:
@@ -266,7 +266,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
\li Custom data can be stored directly in a QMimeData object as a
QByteArray using setData(). For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 1
+ \snippet code/src_corelib_kernel_qmimedata.cpp 1
\li We can subclass QMimeData and reimplement hasFormat(),
formats(), and retrieveData().
@@ -276,7 +276,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
it, and use a qobject_cast() in the receiver's drop event
handler. For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 2
+ \snippet code/src_corelib_kernel_qmimedata.cpp 2
\endlist
\section1 Platform-Specific MIME Types
@@ -286,11 +286,11 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
indicate that they represent data in non-standard formats.
The formats will take the following form:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 3
+ \snippet code/src_corelib_kernel_qmimedata.cpp 3
The following are examples of custom MIME types:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 4
+ \snippet code/src_corelib_kernel_qmimedata.cpp 4
The \c value declaration of each format describes the way in which the
data is encoded.
@@ -458,7 +458,7 @@ bool QMimeData::hasHtml() const
library, whereas QImage belongs to \l QtGui. To convert the
QVariant to a QImage, simply use qvariant_cast(). For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 5
+ \snippet code/src_corelib_kernel_qmimedata.cpp 5
\sa hasImage()
*/
@@ -475,7 +475,7 @@ QVariant QMimeData::imageData() const
library, whereas QImage belongs to \l QtGui. The conversion
from QImage to QVariant is implicit. For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 6
+ \snippet code/src_corelib_kernel_qmimedata.cpp 6
\sa hasImage(), setData()
*/
@@ -505,7 +505,7 @@ bool QMimeData::hasImage() const
library, whereas QColor belongs to \l QtGui. To convert the
QVariant to a QColor, simply use qvariant_cast(). For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 7
+ \snippet code/src_corelib_kernel_qmimedata.cpp 7
\sa hasColor(), setColorData(), data()
*/
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index fb3e4e396b..49a9beb298 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -184,6 +184,7 @@ void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **) = 0;
+int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QObject *, int) = 0;
QObjectData::~QObjectData() {}
@@ -568,9 +569,9 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
\l uic generates code that invokes this function to enable
auto-connection to be performed between widgets on forms created
- with \QD. More information about using auto-connection with \QD is
+ with \e{Qt Designer}. More information about using auto-connection with \e{Qt Designer} is
given in the \l{Using a Designer UI File in Your Application} section of
- the \QD manual.
+ the \e{Qt Designer} manual.
\section1 Dynamic Properties
@@ -606,7 +607,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
Returns 0 if there is no such child.
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 0
+ \snippet code/src_corelib_kernel_qobject.cpp 0
*/
void *qt_find_obj_child(QObject *parent, const char *type, const QString &name)
@@ -651,8 +652,8 @@ static bool check_parent_thread(QObject *parent,
Constructs an object with parent object \a parent.
The parent of an object may be viewed as the object's owner. For
- instance, a \l{QDialog}{dialog box} is the parent of the \gui OK
- and \gui Cancel buttons it contains.
+ instance, a \l{QDialog}{dialog box} is the parent of the \uicontrol{OK}
+ and \uicontrol{Cancel} buttons it contains.
The destructor of a parent object destroys all child objects.
@@ -881,7 +882,7 @@ QObjectPrivate::Connection::~Connection()
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 1
+ \snippet code/src_corelib_kernel_qobject.cpp 1
\sa staticMetaObject
*/
@@ -905,7 +906,7 @@ QObjectPrivate::Connection::~Connection()
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 2
+ \snippet code/src_corelib_kernel_qobject.cpp 2
\sa metaObject()
*/
@@ -924,7 +925,7 @@ QObjectPrivate::Connection::~Connection()
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 3
+ \snippet code/src_corelib_kernel_qobject.cpp 3
The qobject_cast() function behaves similarly to the standard C++
\c dynamic_cast(), with the advantages that it doesn't require
@@ -950,7 +951,7 @@ QObjectPrivate::Connection::~Connection()
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 4
+ \snippet code/src_corelib_kernel_qobject.cpp 4
If you need to determine whether an object is an instance of a particular
class for the purpose of casting it, consider using qobject_cast<Type *>(object)
@@ -967,7 +968,7 @@ QObjectPrivate::Connection::~Connection()
You can find an object by name (and type) using findChild().
You can find a set of objects with findChildren().
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 5
+ \snippet code/src_corelib_kernel_qobject.cpp 5
By default, this property contains an empty string.
@@ -988,7 +989,7 @@ void QObject::setObjectName(const QString &name)
Q_D(QObject);
if (d->objectName != name) {
d->objectName = name;
- if (d->declarativeData)
+ if (d->declarativeData && d->declarativeData->objectNameChanged)
d->declarativeData->objectNameChanged(d->declarativeData, this);
emit objectNameChanged(d->objectName);
}
@@ -1155,7 +1156,7 @@ void QObject::customEvent(QEvent * /* event */)
true; otherwise return false.
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 6
+ \snippet code/src_corelib_kernel_qobject.cpp 6
Notice in the example above that unhandled events are passed to
the base class's eventFilter() function, since the base class
@@ -1225,7 +1226,7 @@ QThread *QObject::thread() const
QApplication::thread() to retrieve the thread in which the
application lives. For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 7
+ \snippet code/src_corelib_kernel_qobject.cpp 7
If \a targetThread is zero, all event processing for this object
and its children stops.
@@ -1390,7 +1391,7 @@ void QObjectPrivate::_q_reregisterTimers(void *pointer)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 8
+ \snippet code/src_corelib_kernel_qobject.cpp 8
Note that QTimer's accuracy depends on the underlying operating system and
hardware. The \a timerType argument allows you to customize the accuracy of
@@ -1472,7 +1473,7 @@ void QObject::killTimer(int id)
The QObjectList class is defined in the \c{<QObject>} header
file as the following:
- \quotefromfile src/corelib/kernel/qobject.h
+ \quotefromfile kernel/qobject.h
\skipto /typedef .*QObjectList/
\printuntil QObjectList
@@ -1507,21 +1508,21 @@ void QObject::killTimer(int id)
named \c{"button1"}, even if the button isn't a direct child of
the parent:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 10
+ \snippet code/src_corelib_kernel_qobject.cpp 10
This example returns a \l{QListWidget} child of \c{parentWidget}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11
+ \snippet code/src_corelib_kernel_qobject.cpp 11
This example returns a child \l{QPushButton} of \c{parentWidget}
(its direct parent) named \c{"button1"}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 41
+ \snippet code/src_corelib_kernel_qobject.cpp 41
This example returns a \l{QListWidget} child of \c{parentWidget},
its direct parent:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 42
+ \snippet code/src_corelib_kernel_qobject.cpp 42
\sa findChildren()
*/
@@ -1538,15 +1539,15 @@ void QObject::killTimer(int id)
The following example shows how to find a list of child \l{QWidget}s of
the specified \c{parentWidget} named \c{widgetname}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 12
+ \snippet code/src_corelib_kernel_qobject.cpp 12
This example returns all \c{QPushButton}s that are children of \c{parentWidget}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13
+ \snippet code/src_corelib_kernel_qobject.cpp 13
This example returns all \c{QPushButton}s that are immediate children of \c{parentWidget}:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 43
+ \snippet code/src_corelib_kernel_qobject.cpp 43
\sa findChild()
*/
@@ -1653,10 +1654,11 @@ void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
if (!parent || !list)
return;
const QObjectList &children = parent->children();
+ QRegExp reCopy = re;
QObject *obj;
for (int i = 0; i < children.size(); ++i) {
obj = children.at(i);
- if (mo.cast(obj) && re.indexIn(obj->objectName()) != -1)
+ if (mo.cast(obj) && reCopy.indexIn(obj->objectName()) != -1)
list->append(obj);
if (options & Qt::FindChildrenRecursively)
@@ -1791,7 +1793,7 @@ void QObjectPrivate::setParent_helper(QObject *o)
\fn void QObject::installEventFilter(QObject *filterObj)
Installs an event filter \a filterObj on this object. For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 14
+ \snippet code/src_corelib_kernel_qobject.cpp 14
An event filter is an object that receives all events that are
sent to this object. The filter can either stop the event or
@@ -1806,11 +1808,11 @@ void QObjectPrivate::setParent_helper(QObject *o)
Here's a \c KeyPressEater class that eats the key presses of its
monitored objects:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 15
+ \snippet code/src_corelib_kernel_qobject.cpp 15
And here's how to install it on two widgets:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 16
+ \snippet code/src_corelib_kernel_qobject.cpp 16
The QShortcut class, for example, uses this technique to intercept
shortcut key presses.
@@ -1925,7 +1927,7 @@ void QObject::deleteLater()
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
+ \snippet code/src_corelib_kernel_qobject.cpp 17
\dots
See \l{Writing Source Code for Translation} for a detailed description of
@@ -1959,7 +1961,7 @@ void QObject::deleteLater()
escape sequences for specifying non-ASCII characters in string
literals to trUtf8(). For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 20
+ \snippet code/src_corelib_kernel_qobject.cpp 20
\sa tr(), QApplication::translate(), {Internationalization with Qt}
*/
@@ -2153,15 +2155,14 @@ int QObject::senderSignalIndex() const
When calling this function, you can use the \c SIGNAL() macro to
pass a specific signal:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 21
-
- As the code snippet above illustrates, you can use this function
- to avoid emitting a signal that nobody listens to.
+ \snippet code/src_corelib_kernel_qobject.cpp 21
\warning This function violates the object-oriented principle of
modularity. However, it might be useful when you need to perform
expensive initialization only if something is connected to a
signal.
+
+ \sa isSignalConnected()
*/
int QObject::receivers(const char *signal) const
@@ -2181,10 +2182,17 @@ int QObject::receivers(const char *signal) const
#ifndef QT_NO_DEBUG
err_method_notfound(this, signal-1, "receivers");
#endif
- return false;
+ return 0;
}
- Q_D(const QObject);
+ if (d->declarativeData && QAbstractDeclarativeData::receivers) {
+ receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this,
+ metaObject()->indexOfMethod(signal));
+ }
+
+ if (!d->isSignalConnected(signal_index))
+ return receivers;
+
QMutexLocker locker(signalSlotLock(this));
if (d->connectionLists) {
if (signal_index < d->connectionLists->count()) {
@@ -2201,6 +2209,60 @@ int QObject::receivers(const char *signal) const
}
/*!
+ \since 5.0
+ Returns true if the \a signal is connected to at least one receiver,
+ otherwise returns false.
+
+ \a signal must be a signal member of this object, otherwise the behaviour
+ is undefined.
+
+ \snippet code/src_corelib_kernel_qobject.cpp 21
+
+ As the code snippet above illustrates, you can use this function
+ to avoid emitting a signal that nobody listens to.
+
+ \warning This function violates the object-oriented principle of
+ modularity. However, it might be useful when you need to perform
+ expensive initialization only if something is connected to a
+ signal.
+*/
+bool QObject::isSignalConnected(const QMetaMethod &signal) const
+{
+ Q_D(const QObject);
+ if (!signal.mobj)
+ return false;
+
+ Q_ASSERT_X(signal.mobj->cast(this) && signal.methodType() == QMetaMethod::Signal,
+ "QObject::isSignalConnected" , "the parametter must be a signal member of the object");
+ uint signalIndex = (signal.handle - QMetaObjectPrivate::get(signal.mobj)->methodData)/5;
+
+ if (signal.mobj->d.data[signal.handle + 4] & MethodCloned)
+ signalIndex = QMetaObjectPrivate::originalClone(signal.mobj, signalIndex);
+
+ int signalOffset;
+ int methodOffset;
+ computeOffsets(signal.mobj, &signalOffset, &methodOffset);
+ signalIndex += signalOffset;
+
+ if (signalIndex < sizeof(d->connectedSignals) * 8)
+ return d->isSignalConnected(signalIndex);
+
+ QMutexLocker locker(signalSlotLock(this));
+ if (d->connectionLists) {
+ if (signalIndex < uint(d->connectionLists->count())) {
+ const QObjectPrivate::Connection *c =
+ d->connectionLists->at(signalIndex).first;
+ while (c) {
+ if (c->receiver)
+ return true;
+ c = c->nextConnectionList;
+ }
+ }
+ }
+ return false;
+}
+
+/*!
\internal
This helper function calculates signal and method index for the given
@@ -2278,18 +2340,18 @@ static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaM
You must use the \c SIGNAL() and \c SLOT() macros when specifying
the \a signal and the \a method, for example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 22
+ \snippet code/src_corelib_kernel_qobject.cpp 22
This example ensures that the label always displays the current
scroll bar value. Note that the signal and slots parameters must not
contain any variable names, only the type. E.g. the following would
not work and return false:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 23
+ \snippet code/src_corelib_kernel_qobject.cpp 23
A signal can also be connected to another signal:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 24
+ \snippet code/src_corelib_kernel_qobject.cpp 24
In this example, the \c MyWidget constructor relays a signal from
a private member variable, and makes it available under a name
@@ -2326,7 +2388,7 @@ static inline void check_and_warn_compat(const QMetaObject *sender, const QMetaM
scenes. If you try to use a queued connection and get the error
message
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 25
+ \snippet code/src_corelib_kernel_qobject.cpp 25
call qRegisterMetaType() to register the data type before you
establish the connection.
@@ -2376,7 +2438,6 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
int signalOffset, methodOffset;
computeOffsets(smeta, &signalOffset, &methodOffset);
- int signal_absolute_index = signal_index + methodOffset;
signal_index += signalOffset;
QByteArray tmp_method_name;
@@ -2445,12 +2506,12 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
}
#ifndef QT_NO_DEBUG
- QMetaMethod smethod = smeta->method(signal_absolute_index);
+ QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
QMetaMethod rmethod = rmeta->method(method_index_relative + rmeta->methodOffset());
check_and_warn_compat(smeta, smethod, rmeta, rmethod);
#endif
QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
- sender, signal_index, receiver, method_index_relative, rmeta ,type, types));
+ sender, signal_index, smeta, receiver, method_index_relative, rmeta ,type, types));
if (handle)
const_cast<QObject*>(sender)->connectNotify(signal - 1);
return handle;
@@ -2538,7 +2599,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
check_and_warn_compat(smeta, signal, rmeta, method);
#endif
QMetaObject::Connection handle = QMetaObject::Connection(QMetaObjectPrivate::connect(
- sender, signal_index, receiver, method_index, 0, type, types));
+ sender, signal_index, signal.enclosingMetaObject(), receiver, method_index, 0, type, types));
if (handle)
const_cast<QObject*>(sender)->connectNotify(signalSignature.constData());
return handle;
@@ -2575,27 +2636,27 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\list 1
\li Disconnect everything connected to an object's signals:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
+ \snippet code/src_corelib_kernel_qobject.cpp 26
equivalent to the non-static overloaded function
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 27
+ \snippet code/src_corelib_kernel_qobject.cpp 27
\li Disconnect everything connected to a specific signal:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 28
+ \snippet code/src_corelib_kernel_qobject.cpp 28
equivalent to the non-static overloaded function
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 29
+ \snippet code/src_corelib_kernel_qobject.cpp 29
\li Disconnect a specific receiver:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
+ \snippet code/src_corelib_kernel_qobject.cpp 30
equivalent to the non-static overloaded function
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 31
+ \snippet code/src_corelib_kernel_qobject.cpp 31
\endlist
@@ -2697,7 +2758,7 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
}
if (!method) {
- res |= QMetaObjectPrivate::disconnect(sender, signal_index, receiver, -1, 0);
+ res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, -1, 0);
} else {
const QMetaObject *rmeta = receiver->metaObject();
do {
@@ -2708,7 +2769,7 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
rmeta = rmeta->superClass();
if (method_index < 0)
break;
- res |= QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index, 0);
+ res |= QMetaObjectPrivate::disconnect(sender, signal_index, smeta, receiver, method_index, 0);
method_found = true;
} while ((rmeta = rmeta->superClass()));
}
@@ -2721,8 +2782,11 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
err_method_notfound(receiver, method_arg, "disconnect");
err_info_about_objects("disconnect", sender, receiver);
}
- if (res)
+ if (res) {
+ if (!signal)
+ const_cast<QObject*>(sender)->disconnectNotify(QMetaMethod());
const_cast<QObject*>(sender)->disconnectNotify(signal ? (signal - 1) : 0);
+ }
return res;
}
@@ -2807,9 +2871,16 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
return false;
}
- if (!QMetaObjectPrivate::disconnect(sender, signal_index, receiver, method_index, 0))
+ if (!QMetaObjectPrivate::disconnect(sender, signal_index, signal.mobj, receiver, method_index, 0))
return false;
+ if (!signal.isValid()) {
+ // The signal is a wildcard, meaning all signals were disconnected.
+ // QMetaObjectPrivate::disconnect() doesn't call disconnectNotify()
+ // per connection in this case. Call it once now, with an invalid
+ // QMetaMethod as argument, as documented.
+ const_cast<QObject*>(sender)->disconnectNotify(signal);
+ }
const_cast<QObject*>(sender)->disconnectNotify(method.mobj ? signalSignature.constData() : 0);
return true;
}
@@ -2840,18 +2911,30 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
/*!
\fn void QObject::connectNotify(const char *signal)
+ \obsolete
+*/
+void QObject::connectNotify(const char *)
+{
+}
+
+/*!
+ \fn void QObject::disconnectNotify(const char *signal)
+ \obsolete
+*/
+void QObject::disconnectNotify(const char *)
+{
+}
+
+/*!
+ \since 5.0
This virtual function is called when something has been connected
to \a signal in this object.
- If you want to compare \a signal with a specific signal, use
- QLatin1String and the \c SIGNAL() macro as follows:
-
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 32
+ If you want to compare \a signal with a specific signal, you can
+ use QMetaMethod::fromSignal() as follows:
- If the signal contains multiple parameters or parameters that
- contain spaces, call QMetaObject::normalizedSignature() on
- the result of the \c SIGNAL() macro.
+ \snippet code/src_corelib_kernel_qobject.cpp 32
\warning This function violates the object-oriented principle of
modularity. However, it might be useful when you need to perform
@@ -2861,12 +2944,13 @@ bool QObject::disconnect(const QObject *sender, const QMetaMethod &signal,
\sa connect(), disconnectNotify()
*/
-void QObject::connectNotify(const char *)
+void QObject::connectNotify(const QMetaMethod &signal)
{
+ Q_UNUSED(signal);
}
/*!
- \fn void QObject::disconnectNotify(const char *signal)
+ \since 5.0
This virtual function is called when something has been
disconnected from \a signal in this object.
@@ -2874,6 +2958,11 @@ void QObject::connectNotify(const char *)
See connectNotify() for an example of how to compare
\a signal with a specific signal.
+ If all signals were disconnected from this object (e.g., the
+ signal argument to disconnect() was 0), disconnectNotify()
+ is only called once, and the \a signal will be an invalid
+ QMetaMethod (QMetaMethod::isValid() returns false).
+
\warning This function violates the object-oriented principle of
modularity. However, it might be useful for optimizing access to
expensive resources.
@@ -2881,17 +2970,19 @@ void QObject::connectNotify(const char *)
\sa disconnect(), connectNotify()
*/
-void QObject::disconnectNotify(const char *)
+void QObject::disconnectNotify(const QMetaMethod &signal)
{
+ Q_UNUSED(signal);
}
/* \internal
convert a signal index from the method range to the signal range
*/
-static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_index)
+static int methodIndexToSignalIndex(const QMetaObject **base, int signal_index)
{
if (signal_index < 0)
return signal_index;
+ const QMetaObject *metaObject = *base;
while (metaObject && metaObject->methodOffset() > signal_index)
metaObject = metaObject->superClass();
@@ -2902,6 +2993,7 @@ static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_in
signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
else
signal_index = signal_index - methodOffset + signalOffset;
+ *base = metaObject;
}
return signal_index;
}
@@ -2916,8 +3008,9 @@ static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_in
QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index, int type, int *types)
{
- signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
- return Connection(QMetaObjectPrivate::connect(sender, signal_index,
+ const QMetaObject *smeta = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&smeta, signal_index);
+ return Connection(QMetaObjectPrivate::connect(sender, signal_index, smeta,
receiver, method_index,
0, //FIXME, we could speed this connection up by computing the relative index
type, types));
@@ -2930,7 +3023,8 @@ QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_i
the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection
*/
-QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
+QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
+ int signal_index, const QMetaObject *smeta,
const QObject *receiver, int method_index,
const QMetaObject *rmeta, int type, int *types)
{
@@ -2940,8 +3034,7 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, i
int method_offset = rmeta ? rmeta->methodOffset() : 0;
Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
QObjectPrivate::StaticMetaCallFunction callFunction =
- (rmeta && rmeta->d.extradata)
- ? reinterpret_cast<const QMetaObjectExtraData *>(rmeta->d.extradata)->static_metacall : 0;
+ rmeta ? rmeta->d.static_metacall : 0;
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
@@ -2975,6 +3068,12 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, i
c->callFunction = callFunction;
QObjectPrivate::get(s)->addConnection(signal_index, c.data());
+
+ locker.unlock();
+ QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
+ if (smethod.isValid())
+ s->connectNotify(smethod);
+
return c.take();
}
@@ -2983,8 +3082,9 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, i
bool QMetaObject::disconnect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index)
{
- signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
- return QMetaObjectPrivate::disconnect(sender, signal_index,
+ const QMetaObject *smeta = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&smeta, signal_index);
+ return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
receiver, method_index, 0);
}
@@ -2997,8 +3097,9 @@ one of these connections will be removed.
bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
const QObject *receiver, int method_index)
{
- signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
- return QMetaObjectPrivate::disconnect(sender, signal_index,
+ const QMetaObject *smeta = sender->metaObject();
+ signal_index = methodIndexToSignalIndex(&smeta, signal_index);
+ return QMetaObjectPrivate::disconnect(sender, signal_index, smeta,
receiver, method_index, 0,
QMetaObjectPrivate::DisconnectOne);
}
@@ -3047,7 +3148,8 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
/*! \internal
Same as the QMetaObject::disconnect, but \a signal_index must be the result of QObjectPrivate::signalIndex
*/
-bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
+bool QMetaObjectPrivate::disconnect(const QObject *sender,
+ int signal_index, const QMetaObject *smeta,
const QObject *receiver, int method_index, void **slot,
DisconnectType disconnectType)
{
@@ -3070,9 +3172,9 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
bool success = false;
if (signal_index < 0) {
// remove from all connection lists
- for (signal_index = -1; signal_index < connectionLists->count(); ++signal_index) {
+ for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) {
QObjectPrivate::Connection *c =
- (*connectionLists)[signal_index].first;
+ (*connectionLists)[sig_index].first;
if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
success = true;
connectionLists->dirty = true;
@@ -3092,6 +3194,13 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
if (connectionLists->orphaned && !connectionLists->inUse)
delete connectionLists;
+ locker.unlock();
+ if (success) {
+ QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
+ if (smethod.isValid())
+ s->disconnectNotify(smethod);
+ }
+
return success;
}
@@ -3101,13 +3210,13 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, int signal_index,
Searches recursively for all child objects of the given \a object, and connects
matching signals from them to slots of \a object that follow the following form:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 33
+ \snippet code/src_corelib_kernel_qobject.cpp 33
Let's assume our object has a child object of type QPushButton with
the \l{QObject::objectName}{object name} \c{button1}. The slot to catch the
button's \c{clicked()} signal would be:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 34
+ \snippet code/src_corelib_kernel_qobject.cpp 34
\sa QObject::setObjectName()
*/
@@ -3131,7 +3240,8 @@ void QMetaObject::connectSlotsByName(QObject *o)
int len = objName.length();
if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != '_')
continue;
- int sigIndex = co->d_func()->signalIndex(slot + len + 4);
+ const QMetaObject *smeta;
+ int sigIndex = co->d_func()->signalIndex(slot + len + 4, &smeta);
if (sigIndex < 0) { // search for compatible signals
const QMetaObject *smo = co->metaObject();
int slotlen = qstrlen(slot + len + 4) - 1;
@@ -3141,8 +3251,9 @@ void QMetaObject::connectSlotsByName(QObject *o)
continue;
if (!qstrncmp(method.methodSignature().constData(), slot + len + 4, slotlen)) {
+ smeta = method.enclosingMetaObject();
int signalOffset, methodOffset;
- computeOffsets(method.enclosingMetaObject(), &signalOffset, &methodOffset);
+ computeOffsets(smeta, &signalOffset, &methodOffset);
sigIndex = k + - methodOffset + signalOffset;
break;
}
@@ -3150,7 +3261,8 @@ void QMetaObject::connectSlotsByName(QObject *o)
}
if (sigIndex < 0)
continue;
- if (Connection(QMetaObjectPrivate::connect(co, sigIndex, o, i))) {
+
+ if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
foundIt = true;
break;
}
@@ -3381,8 +3493,11 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
+
+ If \a meta is not 0, it is set to the meta-object where the signal was found.
*/
-int QObjectPrivate::signalIndex(const char *signalName) const
+int QObjectPrivate::signalIndex(const char *signalName,
+ const QMetaObject **meta) const
{
Q_Q(const QObject);
const QMetaObject *base = q->metaObject();
@@ -3396,6 +3511,8 @@ int QObjectPrivate::signalIndex(const char *signalName) const
relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
int signalOffset, methodOffset;
computeOffsets(base, &signalOffset, &methodOffset);
+ if (meta)
+ *meta = base;
return relative_index + signalOffset;
}
@@ -3722,7 +3839,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 35
+ \snippet code/src_corelib_kernel_qobject.cpp 35
\sa QMetaObject::classInfo()
*/
@@ -3736,9 +3853,9 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
Example:
- \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
+ \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
\dots
- \snippet examples/tools/plugandpaintplugins/basictools/basictoolsplugin.h 3
+ \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 3
See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint
Basic Tools} example for details.
@@ -3755,7 +3872,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
they have additional features accessible through the \l
{Meta-Object System}.
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 36
+ \snippet code/src_corelib_kernel_qobject.cpp 36
The property name and type and the \c READ function are required.
The type can be any type supported by QVariant, or it can be a
@@ -3765,7 +3882,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 37
+ \snippet code/src_corelib_kernel_qobject.cpp 37
For more details about how to use this macro, and a more detailed
example of its use, see the discussion on \l {Qt's Property System}.
@@ -3782,7 +3899,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 38
+ \snippet code/src_corelib_kernel_qobject.cpp 38
If you want to register an enum that is declared in another class,
the enum must be fully qualified with the name of the class
@@ -3804,12 +3921,12 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
For example, in QLibrary, the \l{QLibrary::LoadHints}{LoadHints} flag is
declared in the following way:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 39a
+ \snippet code/src_corelib_kernel_qobject.cpp 39a
The declaration of the flags themselves is performed in the public section
of the QLibrary class itself, using the \l Q_DECLARE_FLAGS() macro:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 39b
+ \snippet code/src_corelib_kernel_qobject.cpp 39b
\note This macro takes care of registering individual flag values
with the meta-object system, so it is unnecessary to use Q_ENUMS()
@@ -3828,10 +3945,10 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
For example:
- \snippet doc/src/snippets/signalsandslots/signalsandslots.h 1
+ \snippet signalsandslots/signalsandslots.h 1
\codeline
- \snippet doc/src/snippets/signalsandslots/signalsandslots.h 2
- \snippet doc/src/snippets/signalsandslots/signalsandslots.h 3
+ \snippet signalsandslots/signalsandslots.h 2
+ \snippet signalsandslots/signalsandslots.h 3
\note This macro requires the class to be a subclass of QObject. Use
Q_GADGET instead of Q_OBJECT to enable the meta object system's support
@@ -3927,7 +4044,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) {
be invoked via the meta-object system. The macro is written before
the return type, as shown in the following example:
- \snippet snippets/qmetaobject-invokable/window.h Window class with invokable method
+ \snippet qmetaobject-invokable/window.h Window class with invokable method
The \c invokableMethod() function is marked up using Q_INVOKABLE, causing
it to be registered with the meta-object system and enabling it to be
@@ -3968,7 +4085,7 @@ void qDeleteInEventHandler(QObject *o)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 44
+ \snippet code/src_corelib_kernel_qobject.cpp 44
This example ensures that the label always displays the current
line edit text.
@@ -4003,7 +4120,7 @@ void qDeleteInEventHandler(QObject *o)
scenes. If you try to use a queued connection and get the error
message
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 25
+ \snippet code/src_corelib_kernel_qobject.cpp 25
make sure to declare the argument type with Q_DECLARE_METATYPE
*/
@@ -4029,11 +4146,11 @@ void qDeleteInEventHandler(QObject *o)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 45
+ \snippet code/src_corelib_kernel_qobject.cpp 45
If your compiler support C++11 lambda expressions, you can use them:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 46
+ \snippet code/src_corelib_kernel_qobject.cpp 46
The connection will automatically disconnect if the sender is destroyed.
*/
@@ -4120,9 +4237,13 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
QMetaObject::Connection ret(c.take());
locker.unlock();
+ QMetaMethod method = QMetaObjectPrivate::signal(senderMetaObject, signal_index);
+ Q_ASSERT(method.isValid());
+ s->connectNotify(method);
+
// reconstruct the signature to call connectNotify
const char *sig;
- QByteArray tmp_sig = senderMetaObject->method(signal_index - signalOffset + methodOffset).methodSignature();
+ QByteArray tmp_sig = method.methodSignature();
sig = tmp_sig.constData();
QVarLengthArray<char> signalSignature(qstrlen(sig) + 2);
signalSignature.data()[0] = char(QSIGNAL_CODE + '0');
@@ -4159,6 +4280,8 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
if (c->next)
c->next->prev = c->prev;
c->receiver = 0;
+ // disconnectNotify() not called (the signal index is unknown).
+
return true;
}
@@ -4178,19 +4301,19 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
\list 1
\li Disconnect everything connected to an object's signals:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
+ \snippet code/src_corelib_kernel_qobject.cpp 26
\li Disconnect everything connected to a specific signal:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 47
+ \snippet code/src_corelib_kernel_qobject.cpp 47
\li Disconnect a specific receiver:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
+ \snippet code/src_corelib_kernel_qobject.cpp 30
\li Disconnect a connection from one specific signal to a specific slot:
- \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 48
+ \snippet code/src_corelib_kernel_qobject.cpp 48
\endlist
@@ -4242,7 +4365,7 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
signal_index += signalOffset;
}
- return QMetaObjectPrivate::disconnect(sender, signal_index, receiver, -1, slot);
+ return QMetaObjectPrivate::disconnect(sender, signal_index, senderMetaObject, receiver, -1, slot);
}
/*! \class QMetaObject::Connection
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 11b1a19e0b..5e969d67f6 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -365,11 +365,15 @@ protected:
QObject *sender() const;
int senderSignalIndex() const;
int receivers(const char* signal) const;
+ bool isSignalConnected(const QMetaMethod &signal) const;
virtual void timerEvent(QTimerEvent *);
virtual void childEvent(QChildEvent *);
virtual void customEvent(QEvent *);
+ virtual void connectNotify(const QMetaMethod &signal);
+ virtual void disconnectNotify(const QMetaMethod &signal);
+ // Deprecated; to be removed before Qt 5.0
virtual void connectNotify(const char *signal);
virtual void disconnectNotify(const char *signal);
@@ -382,6 +386,7 @@ protected:
static const QMetaObject staticQtMetaObject;
friend struct QMetaObject;
+ friend struct QMetaObjectPrivate;
friend class QMetaCallEvent;
friend class QApplication;
friend class QApplicationPrivate;
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 419fcc1dd4..e016002afa 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -51,431 +51,6 @@ QT_BEGIN_NAMESPACE
namespace QtPrivate {
- template <typename T> struct RemoveRef { typedef T Type; };
- template <typename T> struct RemoveRef<T&> { typedef T Type; };
- template <typename T> struct RemoveConstRef { typedef T Type; };
- template <typename T> struct RemoveConstRef<const T&> { typedef T Type; };
-
- /*
- The following List classes are used to help to handle the list of arguments.
- It follow the same principles as the lisp lists.
- List_Left<L,N> take a list and a number as a parametter and returns (via the Value typedef,
- the list composed of the first N element of the list
- */
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template <typename Head, typename Tail> struct List { typedef Head Car; typedef Tail Cdr; };
- template <typename L, int N> struct List_Left { typedef List<typename L::Car, typename List_Left<typename L::Cdr, N - 1>::Value > Value; };
- template <typename L> struct List_Left<L,0> { typedef void Value; };
-#else
- // With variadic template, lists are represented using a variadic template argument instead of the lisp way
- template <typename...> struct List {};
- template <typename Head, typename... Tail> struct List<Head, Tail...> { typedef Head Car; typedef List<Tail...> Cdr; };
- template <typename, typename> struct List_Append;
- template <typename... L1, typename...L2> struct List_Append<List<L1...>, List<L2...>> { typedef List<L1..., L2...> Value; };
- template <typename L, int N> struct List_Left {
- typedef typename List_Append<List<typename L::Car>,typename List_Left<typename L::Cdr, N - 1>::Value>::Value Value;
- };
- template <typename L> struct List_Left<L, 0> { typedef List<> Value; };
-#endif
- // List_Select<L,N> returns (via typedef Value) the Nth element of the list L
- template <typename L, int N> struct List_Select { typedef typename List_Select<typename L::Cdr, N - 1>::Value Value; };
- template <typename L> struct List_Select<L,0> { typedef typename L::Car Value; };
-
- /*
- trick to set the return value of a slot that works even if the signal or the slot returns void
- to be used like function(), ApplyReturnValue<ReturnType>(&return_value)
- if function() returns a value, the operator,(T, ApplyReturnValue<ReturnType>) is called, but if it
- returns void, the builtin one is used without an error.
- */
- template <typename T>
- struct ApplyReturnValue {
- void *data;
- ApplyReturnValue(void *data_) : data(data_) {}
- };
- template<typename T, typename U>
- void operator,(const T &value, const ApplyReturnValue<U> &container) {
- if (container.data)
- *reinterpret_cast<U*>(container.data) = value;
- }
-#ifdef Q_COMPILER_RVALUE_REFS
- template<typename T, typename U>
- void operator,(T &&value, const ApplyReturnValue<U> &container) {
- if (container.data)
- *reinterpret_cast<U*>(container.data) = value;
- }
-#endif
- template<typename T>
- void operator,(T, const ApplyReturnValue<void> &) {}
-
-
- /*
- The FunctionPointer<Func> struct is a type trait for function pointer.
- - ArgumentCount is the number of argument, or -1 if it is unknown
- - the Object typedef is the Object of a pointer to member function
- - the Arguments typedef is the list of argument (in a QtPrivate::List)
- - the Function typedef is an alias to the template parametter Func
- - the call<Args, R>(f,o,args) method is used to call that slot
- Args is the list of argument of the signal
- R is the return type of the signal
- f is the function pointer
- o is the receiver object
- and args is the array of pointer to arguments, as used in qt_metacall
-
- The Functor<Func,N> struct is the helper to call a functor of N argument.
- its call function is the same as the FunctionPointer::call function.
- */
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
- template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) ()>
- {
- typedef Obj Object;
- typedef void Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) ();
- enum {ArgumentCount = 0};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
- };
- template<class Obj, typename Ret, typename Arg1> struct FunctionPointer<Ret (Obj::*) (Arg1)>
- {
- typedef Obj Object;
- typedef List<Arg1, void> Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1);
- enum {ArgumentCount = 1};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, void> > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
- struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
- {
- typedef Obj Object;
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6};
- template <typename Args, typename R>
- static void call(Function f, Obj *o, void **arg) {
- (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-
- template<typename Ret> struct FunctionPointer<Ret (*) ()>
- {
- typedef void Arguments;
- typedef Ret (*Function) ();
- typedef Ret ReturnType;
- enum {ArgumentCount = 0};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Ret, typename Arg1> struct FunctionPointer<Ret (*) (Arg1)>
- {
- typedef List<Arg1, void> Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1);
- enum {ArgumentCount = 1};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg)
- { f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (*) (Arg1, Arg2)>
- {
- typedef List<Arg1, List<Arg2, void> > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2);
- enum {ArgumentCount = 2};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3);
- enum {ArgumentCount = 3};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4);
- enum {ArgumentCount = 4};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3,
- List<Arg4, List<Arg5, void > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
- enum {ArgumentCount = 5};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
- {
- typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
- enum {ArgumentCount = 6};
- template <typename Args, typename R>
- static void call(Function f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-
- template<typename F, int N> struct Functor;
- template<typename Function> struct Functor<Function, 0>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
- };
- template<typename Function> struct Functor<Function, 1>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 2>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 3>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 4>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 5>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
- }
- };
- template<typename Function> struct Functor<Function, 6>
- {
- template <typename Args, typename R>
- static void call(Function &f, void *, void **arg) {
- f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
- *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
- }
- };
-#else
- template <int...> struct IndexesList {};
- template <typename IndexList, int Right> struct IndexesAppend;
- template <int... Left, int Right> struct IndexesAppend<IndexesList<Left...>, Right>
- { typedef IndexesList<Left..., Right> Value; };
- template <int N> struct Indexes
- { typedef typename IndexesAppend<typename Indexes<N - 1>::Value, N - 1>::Value Value; };
- template <> struct Indexes<0> { typedef IndexesList<> Value; };
- template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
-
- template <typename, typename, typename, typename> struct FunctorCall;
- template <int... I, typename... SignalArgs, typename R, typename Function>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, Function> {
- static void call(Function f, void **arg) {
- f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
- }
- };
- template <int... I, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
- struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
- static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) {
- (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
- }
- };
-
- template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...)>
- {
- typedef Obj Object;
- typedef List<Args...> Arguments;
- typedef Ret ReturnType;
- typedef Ret (Obj::*Function) (Args...);
- enum {ArgumentCount = sizeof...(Args)};
- template <typename SignalArgs, typename R>
- static void call(Function f, Obj *o, void **arg) {
- FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
- }
- };
-
- template<typename Ret, typename... Args> struct FunctionPointer<Ret (*) (Args...)>
- {
- typedef List<Args...> Arguments;
- typedef Ret ReturnType;
- typedef Ret (*Function) (Args...);
- enum {ArgumentCount = sizeof...(Args)};
- template <typename SignalArgs, typename R>
- static void call(Function f, void *, void **arg) {
- FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, arg);
- }
- };
-
- template<typename Function, int N> struct Functor
- {
- template <typename SignalArgs, typename R>
- static void call(Function &f, void *, void **arg) {
- FunctorCall<typename Indexes<N>::Value, SignalArgs, R, Function>::call(f, arg);
- }
- };
-#endif
-
- /*
- Logic that check if the arguments of the slot matches the argument of the signal.
- To be used like this:
- Q_STATIC_ASSERT(CheckCompatibleArguments<FunctionPointer<Signal>::Arguments, FunctionPointer<Slot>::Arguments>::value)
- */
- template<typename A1, typename A2> struct AreArgumentsCompatible {
- static int test(A2);
- static char test(...);
- static A1 dummy();
- enum { value = sizeof(test(dummy())) == sizeof(int) };
- };
- template<typename A1, typename A2> struct AreArgumentsCompatible<A1, A2&> { enum { value = false }; };
- template<typename A> struct AreArgumentsCompatible<A&, A&> { enum { value = true }; };
- // void as a return value
- template<typename A> struct AreArgumentsCompatible<void, A> { enum { value = true }; };
- template<typename A> struct AreArgumentsCompatible<A, void> { enum { value = true }; };
- template<> struct AreArgumentsCompatible<void, void> { enum { value = true }; };
-
-#ifndef Q_COMPILER_VARIADIC_TEMPLATES
- template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
- template <> struct CheckCompatibleArguments<void, void> { enum { value = true }; };
- template <typename List1> struct CheckCompatibleArguments<List1, void> { enum { value = true }; };
- template <typename Arg1, typename Arg2, typename Tail1, typename Tail2> struct CheckCompatibleArguments<List<Arg1, Tail1>, List<Arg2, Tail2> >
- {
- enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
- && CheckCompatibleArguments<Tail1, Tail2>::value };
- };
-#else
- template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
- template <> struct CheckCompatibleArguments<List<>, List<>> { enum { value = true }; };
- template <typename List1> struct CheckCompatibleArguments<List1, List<>> { enum { value = true }; };
- template <typename Arg1, typename Arg2, typename... Tail1, typename... Tail2>
- struct CheckCompatibleArguments<List<Arg1, Tail1...>, List<Arg2, Tail2...>>
- {
- enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
- && CheckCompatibleArguments<List<Tail1...>, List<Tail2...>>::value };
- };
-
-#endif
-
/*
Logic to statically generate the array of qMetaTypeId
ConnectionTypes<FunctionPointer<Signal>::Arguments>::types() returns an array
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index c8edadce9d..a31e091ae8 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -91,6 +91,7 @@ public:
static void (*parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *);
static void (*objectNameChanged)(QAbstractDeclarativeData *, QObject *);
static void (*signalEmitted)(QAbstractDeclarativeData *, QObject *, int, void **);
+ static int (*receivers)(QAbstractDeclarativeData *, const QObject *, int);
};
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
@@ -175,7 +176,7 @@ public:
return o->d_func();
}
- int signalIndex(const char *signalName) const;
+ int signalIndex(const char *signalName, const QMetaObject **meta = 0) const;
inline bool isSignalConnected(uint signalIdx) const;
public:
diff --git a/src/corelib/kernel/qobjectcleanuphandler.cpp b/src/corelib/kernel/qobjectcleanuphandler.cpp
index 166a90a74f..f165ec96ca 100644
--- a/src/corelib/kernel/qobjectcleanuphandler.cpp
+++ b/src/corelib/kernel/qobjectcleanuphandler.cpp
@@ -121,7 +121,7 @@ void QObjectCleanupHandler::remove(QObject *object)
Returns true if this cleanup handler is empty or if all objects in
this cleanup handler have been destroyed; otherwise return false.
- \sa add() remove() clear()
+ \sa add(), remove(), clear()
*/
bool QObjectCleanupHandler::isEmpty() const
{
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 9bcb8b9211..cc442457b0 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -44,6 +44,8 @@
#include <QtCore/qnamespace.h>
+#include <QtCore/qobjectdefs_impl.h>
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -55,7 +57,7 @@ struct QByteArrayData;
class QString;
#ifndef Q_MOC_OUTPUT_REVISION
-#define Q_MOC_OUTPUT_REVISION 65
+#define Q_MOC_OUTPUT_REVISION 66
#endif
// The following macros are our "extensions" to C++
@@ -158,7 +160,6 @@ public: \
QT_TR_FUNCTIONS \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
private: \
- Q_DECL_HIDDEN static const QMetaObjectExtraData staticMetaObjectExtraData; \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
/* tmake ignore Q_OBJECT */
@@ -451,7 +452,10 @@ struct Q_CORE_EXPORT QMetaObject
const QMetaObject *superdata;
const QByteArrayData *stringdata;
const uint *data;
- const void *extradata;
+ typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
+ StaticMetacallFunction static_metacall;
+ const QMetaObject **relatedMetaObjects;
+ void *extradata; //reserved for future use
} d;
};
@@ -479,17 +483,6 @@ public:
#endif
};
-typedef const QMetaObject& (*QMetaObjectAccessor)();
-
-struct QMetaObjectExtraData
-{
- const QMetaObject **objects;
-
- typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **); //from revision 6
- //typedef int (*StaticMetaCall)(QMetaObject::Call, int, void **); //used from revison 2 until revison 5
- StaticMetacallFunction static_metacall;
-};
-
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
new file mode 100644
index 0000000000..5efe08b3e5
--- /dev/null
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -0,0 +1,485 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q_QDOC
+
+#ifndef QOBJECTDEFS_H
+#error Do not include qobjectdefs_impl.h directly
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+
+namespace QtPrivate {
+ template <typename T> struct RemoveRef { typedef T Type; };
+ template <typename T> struct RemoveRef<T&> { typedef T Type; };
+ template <typename T> struct RemoveConstRef { typedef T Type; };
+ template <typename T> struct RemoveConstRef<const T&> { typedef T Type; };
+
+ /*
+ The following List classes are used to help to handle the list of arguments.
+ It follow the same principles as the lisp lists.
+ List_Left<L,N> take a list and a number as a parametter and returns (via the Value typedef,
+ the list composed of the first N element of the list
+ */
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
+ template <typename Head, typename Tail> struct List { typedef Head Car; typedef Tail Cdr; };
+ template <typename L, int N> struct List_Left { typedef List<typename L::Car, typename List_Left<typename L::Cdr, N - 1>::Value > Value; };
+ template <typename L> struct List_Left<L,0> { typedef void Value; };
+#else
+ // With variadic template, lists are represented using a variadic template argument instead of the lisp way
+ template <typename...> struct List {};
+ template <typename Head, typename... Tail> struct List<Head, Tail...> { typedef Head Car; typedef List<Tail...> Cdr; };
+ template <typename, typename> struct List_Append;
+ template <typename... L1, typename...L2> struct List_Append<List<L1...>, List<L2...>> { typedef List<L1..., L2...> Value; };
+ template <typename L, int N> struct List_Left {
+ typedef typename List_Append<List<typename L::Car>,typename List_Left<typename L::Cdr, N - 1>::Value>::Value Value;
+ };
+ template <typename L> struct List_Left<L, 0> { typedef List<> Value; };
+#endif
+ // List_Select<L,N> returns (via typedef Value) the Nth element of the list L
+ template <typename L, int N> struct List_Select { typedef typename List_Select<typename L::Cdr, N - 1>::Value Value; };
+ template <typename L> struct List_Select<L,0> { typedef typename L::Car Value; };
+
+ /*
+ trick to set the return value of a slot that works even if the signal or the slot returns void
+ to be used like function(), ApplyReturnValue<ReturnType>(&return_value)
+ if function() returns a value, the operator,(T, ApplyReturnValue<ReturnType>) is called, but if it
+ returns void, the builtin one is used without an error.
+ */
+ template <typename T>
+ struct ApplyReturnValue {
+ void *data;
+ ApplyReturnValue(void *data_) : data(data_) {}
+ };
+ template<typename T, typename U>
+ void operator,(const T &value, const ApplyReturnValue<U> &container) {
+ if (container.data)
+ *reinterpret_cast<U*>(container.data) = value;
+ }
+#ifdef Q_COMPILER_RVALUE_REFS
+ template<typename T, typename U>
+ void operator,(T &&value, const ApplyReturnValue<U> &container) {
+ if (container.data)
+ *reinterpret_cast<U*>(container.data) = value;
+ }
+#endif
+ template<typename T>
+ void operator,(T, const ApplyReturnValue<void> &) {}
+
+
+ /*
+ The FunctionPointer<Func> struct is a type trait for function pointer.
+ - ArgumentCount is the number of argument, or -1 if it is unknown
+ - the Object typedef is the Object of a pointer to member function
+ - the Arguments typedef is the list of argument (in a QtPrivate::List)
+ - the Function typedef is an alias to the template parametter Func
+ - the call<Args, R>(f,o,args) method is used to call that slot
+ Args is the list of argument of the signal
+ R is the return type of the signal
+ f is the function pointer
+ o is the receiver object
+ and args is the array of pointer to arguments, as used in qt_metacall
+
+ The Functor<Func,N> struct is the helper to call a functor of N argument.
+ its call function is the same as the FunctionPointer::call function.
+ */
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
+ template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
+ template<class Obj, typename Ret> struct FunctionPointer<Ret (Obj::*) ()>
+ {
+ typedef Obj Object;
+ typedef void Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) ();
+ enum {ArgumentCount = 0};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) { (o->*f)(), ApplyReturnValue<R>(arg[0]); }
+ };
+ template<class Obj, typename Ret, typename Arg1> struct FunctionPointer<Ret (Obj::*) (Arg1)>
+ {
+ typedef Obj Object;
+ typedef List<Arg1, void> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Arg1);
+ enum {ArgumentCount = 1};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ (o->*f)((*reinterpret_cast<typename RemoveRef<typename Args::Car>::Type *>(arg[1]))), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<class Obj, typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2)>
+ {
+ typedef Obj Object;
+ typedef List<Arg1, List<Arg2, void> > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Arg1, Arg2);
+ enum {ArgumentCount = 2};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3)>
+ {
+ typedef Obj Object;
+ typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3);
+ enum {ArgumentCount = 3};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4)>
+ {
+ typedef Obj Object;
+ typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4);
+ enum {ArgumentCount = 4};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
+ {
+ typedef Obj Object;
+ typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, void> > > > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
+ enum {ArgumentCount = 5};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<class Obj, typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
+ struct FunctionPointer<Ret (Obj::*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
+ {
+ typedef Obj Object;
+ typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
+ enum {ArgumentCount = 6};
+ template <typename Args, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ (o->*f)( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+
+ template<typename Ret> struct FunctionPointer<Ret (*) ()>
+ {
+ typedef void Arguments;
+ typedef Ret (*Function) ();
+ typedef Ret ReturnType;
+ enum {ArgumentCount = 0};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
+ };
+ template<typename Ret, typename Arg1> struct FunctionPointer<Ret (*) (Arg1)>
+ {
+ typedef List<Arg1, void> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Arg1);
+ enum {ArgumentCount = 1};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg)
+ { f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]); }
+ };
+ template<typename Ret, typename Arg1, typename Arg2> struct FunctionPointer<Ret (*) (Arg1, Arg2)>
+ {
+ typedef List<Arg1, List<Arg2, void> > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Arg1, Arg2);
+ enum {ArgumentCount = 2};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg) {
+ f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]); }
+ };
+ template<typename Ret, typename Arg1, typename Arg2, typename Arg3> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3)>
+ {
+ typedef List<Arg1, List<Arg2, List<Arg3, void> > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Arg1, Arg2, Arg3);
+ enum {ArgumentCount = 3};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4)>
+ {
+ typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, void> > > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4);
+ enum {ArgumentCount = 4};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5)>
+ {
+ typedef List<Arg1, List<Arg2, List<Arg3,
+ List<Arg4, List<Arg5, void > > > > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5);
+ enum {ArgumentCount = 5};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Ret, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6> struct FunctionPointer<Ret (*) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)>
+ {
+ typedef List<Arg1, List<Arg2, List<Arg3, List<Arg4, List<Arg5, List<Arg6, void> > > > > > Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
+ enum {ArgumentCount = 6};
+ template <typename Args, typename R>
+ static void call(Function f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+
+ template<typename F, int N> struct Functor;
+ template<typename Function> struct Functor<Function, 0>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) { f(), ApplyReturnValue<R>(arg[0]); }
+ };
+ template<typename Function> struct Functor<Function, 1>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) {
+ f(*reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Function> struct Functor<Function, 2>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Function> struct Functor<Function, 3>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Function> struct Functor<Function, 4>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Function> struct Functor<Function, 5>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template<typename Function> struct Functor<Function, 6>
+ {
+ template <typename Args, typename R>
+ static void call(Function &f, void *, void **arg) {
+ f( *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 0>::Value>::Type *>(arg[1]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 1>::Value>::Type *>(arg[2]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 2>::Value>::Type *>(arg[3]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 3>::Value>::Type *>(arg[4]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 4>::Value>::Type *>(arg[5]),
+ *reinterpret_cast<typename RemoveRef<typename List_Select<Args, 5>::Value>::Type *>(arg[6])), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+#else
+ template <int...> struct IndexesList {};
+ template <typename IndexList, int Right> struct IndexesAppend;
+ template <int... Left, int Right> struct IndexesAppend<IndexesList<Left...>, Right>
+ { typedef IndexesList<Left..., Right> Value; };
+ template <int N> struct Indexes
+ { typedef typename IndexesAppend<typename Indexes<N - 1>::Value, N - 1>::Value Value; };
+ template <> struct Indexes<0> { typedef IndexesList<> Value; };
+ template<typename Func> struct FunctionPointer { enum {ArgumentCount = -1}; };
+
+ template <typename, typename, typename, typename> struct FunctorCall;
+ template <int... I, typename... SignalArgs, typename R, typename Function>
+ struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, Function> {
+ static void call(Function f, void **arg) {
+ f((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template <int... I, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<I...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...)> {
+ static void call(SlotRet (Obj::*f)(SlotArgs...), Obj *o, void **arg) {
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[I+1]))...), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+
+ template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...)>
+ {
+ typedef Obj Object;
+ typedef List<Args...> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Args...);
+ enum {ArgumentCount = sizeof...(Args)};
+ template <typename SignalArgs, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
+ }
+ };
+
+ template<typename Ret, typename... Args> struct FunctionPointer<Ret (*) (Args...)>
+ {
+ typedef List<Args...> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Args...);
+ enum {ArgumentCount = sizeof...(Args)};
+ template <typename SignalArgs, typename R>
+ static void call(Function f, void *, void **arg) {
+ FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, arg);
+ }
+ };
+
+ template<typename Function, int N> struct Functor
+ {
+ template <typename SignalArgs, typename R>
+ static void call(Function &f, void *, void **arg) {
+ FunctorCall<typename Indexes<N>::Value, SignalArgs, R, Function>::call(f, arg);
+ }
+ };
+#endif
+
+ /*
+ Logic that check if the arguments of the slot matches the argument of the signal.
+ To be used like this:
+ Q_STATIC_ASSERT(CheckCompatibleArguments<FunctionPointer<Signal>::Arguments, FunctionPointer<Slot>::Arguments>::value)
+ */
+ template<typename A1, typename A2> struct AreArgumentsCompatible {
+ static int test(A2);
+ static char test(...);
+ static A1 dummy();
+ enum { value = sizeof(test(dummy())) == sizeof(int) };
+ };
+ template<typename A1, typename A2> struct AreArgumentsCompatible<A1, A2&> { enum { value = false }; };
+ template<typename A> struct AreArgumentsCompatible<A&, A&> { enum { value = true }; };
+ // void as a return value
+ template<typename A> struct AreArgumentsCompatible<void, A> { enum { value = true }; };
+ template<typename A> struct AreArgumentsCompatible<A, void> { enum { value = true }; };
+ template<> struct AreArgumentsCompatible<void, void> { enum { value = true }; };
+
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
+ template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
+ template <> struct CheckCompatibleArguments<void, void> { enum { value = true }; };
+ template <typename List1> struct CheckCompatibleArguments<List1, void> { enum { value = true }; };
+ template <typename Arg1, typename Arg2, typename Tail1, typename Tail2> struct CheckCompatibleArguments<List<Arg1, Tail1>, List<Arg2, Tail2> >
+ {
+ enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
+ && CheckCompatibleArguments<Tail1, Tail2>::value };
+ };
+#else
+ template <typename List1, typename List2> struct CheckCompatibleArguments { enum { value = false }; };
+ template <> struct CheckCompatibleArguments<List<>, List<>> { enum { value = true }; };
+ template <typename List1> struct CheckCompatibleArguments<List1, List<>> { enum { value = true }; };
+ template <typename Arg1, typename Arg2, typename... Tail1, typename... Tail2>
+ struct CheckCompatibleArguments<List<Arg1, Tail1...>, List<Arg2, Tail2...>>
+ {
+ enum { value = AreArgumentsCompatible<typename RemoveConstRef<Arg1>::Type, typename RemoveConstRef<Arg2>::Type>::value
+ && CheckCompatibleArguments<List<Tail1...>, List<Tail2...>>::value };
+ };
+
+#endif
+}
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp
index e0e14e5b79..cd88baf9bf 100644
--- a/src/corelib/kernel/qpointer.cpp
+++ b/src/corelib/kernel/qpointer.cpp
@@ -74,10 +74,10 @@
Example:
- \snippet doc/src/snippets/pointer/pointer.cpp 0
+ \snippet pointer/pointer.cpp 0
\dots
- \snippet doc/src/snippets/pointer/pointer.cpp 1
- \snippet doc/src/snippets/pointer/pointer.cpp 2
+ \snippet pointer/pointer.cpp 1
+ \snippet pointer/pointer.cpp 2
If the QLabel is deleted in the meantime, the \c label variable
will hold 0 instead of an invalid address, and the last line will
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index d8578a8059..50c24ba169 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -174,7 +174,7 @@ QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
the shared memory segment, the detach() operation destroys the
shared memory segment.
- \sa detach() isAttached()
+ \sa detach(), isAttached()
*/
QSharedMemory::~QSharedMemory()
{
@@ -193,7 +193,7 @@ QSharedMemory::~QSharedMemory()
segment, it will \l {detach()} {detach} from it before setting the new key.
This function does not do an attach().
- \sa key() nativeKey() isAttached()
+ \sa key(), nativeKey(), isAttached()
*/
void QSharedMemory::setKey(const QString &key)
{
@@ -225,7 +225,7 @@ void QSharedMemory::setKey(const QString &key)
The application will not be portable if you set a native key.
- \sa nativeKey() key() isAttached()
+ \sa nativeKey(), key(), isAttached()
*/
void QSharedMemory::setNativeKey(const QString &key)
{
@@ -288,7 +288,7 @@ bool QSharedMemoryPrivate::initKey()
You can find the native, platform specific, key used by the operating system
by calling nativeKey().
- \sa setKey() setNativeKey()
+ \sa setKey(), setNativeKey()
*/
QString QSharedMemory::key() const
{
@@ -306,7 +306,7 @@ QString QSharedMemory::key() const
You can use the native key to access shared memory segments that have not
been created by Qt, or to grant shared memory access to non-Qt applications.
- \sa setKey() setNativeKey()
+ \sa setKey(), setNativeKey()
*/
QString QSharedMemory::nativeKey() const
{
@@ -363,7 +363,7 @@ bool QSharedMemory::create(int size, AccessMode mode)
Returns the size of the attached shared memory segment. If no shared
memory segment is attached, 0 is returned.
- \sa create() attach()
+ \sa create(), attach()
*/
int QSharedMemory::size() const
{
@@ -472,7 +472,7 @@ void *QSharedMemory::data()
the shared memory, and remember to release the lock with unlock()
after you are done.
- \sa attach() create()
+ \sa attach(), create()
*/
const void* QSharedMemory::constData() const
{
diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp
index 27340020d8..c668047bd2 100644
--- a/src/corelib/kernel/qsignalmapper.cpp
+++ b/src/corelib/kernel/qsignalmapper.cpp
@@ -91,14 +91,14 @@ public:
signal, \c clicked(), which is emitted with the text of the button
that was clicked:
- \snippet doc/src/snippets/qsignalmapper/buttonwidget.h 0
- \snippet doc/src/snippets/qsignalmapper/buttonwidget.h 1
+ \snippet qsignalmapper/buttonwidget.h 0
+ \snippet qsignalmapper/buttonwidget.h 1
The only function that we need to implement is the constructor:
- \snippet doc/src/snippets/qsignalmapper/buttonwidget.cpp 0
- \snippet doc/src/snippets/qsignalmapper/buttonwidget.cpp 1
- \snippet doc/src/snippets/qsignalmapper/buttonwidget.cpp 2
+ \snippet qsignalmapper/buttonwidget.cpp 0
+ \snippet qsignalmapper/buttonwidget.cpp 1
+ \snippet qsignalmapper/buttonwidget.cpp 2
A list of texts is passed to the constructor. A signal mapper is
constructed and for each text in the list a QPushButton is
diff --git a/src/corelib/kernel/qsystemsemaphore.cpp b/src/corelib/kernel/qsystemsemaphore.cpp
index 0558f3cb59..70e75b54b9 100644
--- a/src/corelib/kernel/qsystemsemaphore.cpp
+++ b/src/corelib/kernel/qsystemsemaphore.cpp
@@ -79,7 +79,7 @@ QT_BEGIN_NAMESPACE
can use to use the same semaphore.
Example: Create a system semaphore
- \snippet doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp 0
+ \snippet code/src_corelib_kernel_qsystemsemaphore.cpp 0
A typical application of system semaphores is for controlling access
to a circular buffer shared by a producer process and a consumer
@@ -283,13 +283,13 @@ bool QSystemSemaphore::acquire()
Example: Create a system semaphore having five resources; acquire
them all and then release them all.
- \snippet doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp 1
+ \snippet code/src_corelib_kernel_qsystemsemaphore.cpp 1
This function can also "create" resources. For example, immediately
following the sequence of statements above, suppose we add the
statement:
- \snippet doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp 2
+ \snippet code/src_corelib_kernel_qsystemsemaphore.cpp 2
Ten new resources are now guarded by the semaphore, in addition to
the five that already existed. You would not normally use this
diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp
index 2131188439..23e1826006 100644
--- a/src/corelib/kernel/qtimer.cpp
+++ b/src/corelib/kernel/qtimer.cpp
@@ -61,9 +61,9 @@ QT_BEGIN_NAMESPACE
Example for a one second (1000 millisecond) timer (from the
\l{widgets/analogclock}{Analog Clock} example):
- \snippet examples/widgets/analogclock/analogclock.cpp 4
- \snippet examples/widgets/analogclock/analogclock.cpp 5
- \snippet examples/widgets/analogclock/analogclock.cpp 6
+ \snippet widgets/analogclock/analogclock.cpp 4
+ \snippet widgets/analogclock/analogclock.cpp 5
+ \snippet widgets/analogclock/analogclock.cpp 6
From then on, the \c update() slot is called every second.
@@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE
QTimer::singleShot() function to call a slot after a specified
interval:
- \snippet doc/src/snippets/timers/timers.cpp 3
+ \snippet timers/timers.cpp 3
In multithreaded applications, you can use QTimer in any thread
that has an event loop. To start an event loop from a non-GUI
@@ -87,9 +87,9 @@ QT_BEGIN_NAMESPACE
been processed. This can be used to do heavy work while providing
a snappy user interface:
- \snippet doc/src/snippets/timers/timers.cpp 4
- \snippet doc/src/snippets/timers/timers.cpp 5
- \snippet doc/src/snippets/timers/timers.cpp 6
+ \snippet timers/timers.cpp 4
+ \snippet timers/timers.cpp 5
+ \snippet timers/timers.cpp 6
\c processOneThing() will from then on be called repeatedly. It
should be written in such a way that it always returns quickly
@@ -304,7 +304,7 @@ QT_END_INCLUDE_NAMESPACE
create a local QTimer object.
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qtimer.cpp 0
+ \snippet code/src_corelib_kernel_qtimer.cpp 0
This sample program automatically terminates after 10 minutes
(600,000 milliseconds).
@@ -343,7 +343,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, QObject *receiver, co
if (msec == 0) {
// special code shortpath for 0-timers
const char* bracketPosition = strchr(member, '(');
- if (!bracketPosition || !(member[0] >= '0' && member[0] <= '3')) {
+ if (!bracketPosition || !(member[0] >= '0' && member[0] <= '2')) {
qWarning("QTimer::singleShot: Invalid slot specification");
return;
}
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 892883bacd..c34a3acb70 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -338,7 +338,7 @@ public:
it via QObject::tr(). Here's the \c main() function from the
\l{linguist/hellotr}{Hello tr()} example:
- \snippet examples/linguist/hellotr/main.cpp 2
+ \snippet linguist/hellotr/main.cpp 2
Note that the translator must be created \e before the
application's widgets.
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 10b86bcb48..7ccc5e500e 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -87,7 +87,7 @@ class HandlersManager
{
static const QVariant::Handler *Handlers[QModulesPrivate::ModulesCount];
public:
- const QVariant::Handler *operator[] (const int typeId) const
+ const QVariant::Handler *operator[] (const uint typeId) const
{
return Handlers[QModulesPrivate::moduleForType(typeId)];
}
@@ -776,6 +776,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
const QMetaType type(d->type);
const uint size = type.sizeOf();
if (!size) {
+ qWarning("Trying to construct an instance of an invalid type, type id: %i", d->type);
d->type = QVariant::Invalid;
return;
}
@@ -839,6 +840,9 @@ static void customStreamDebug(QDebug dbg, const QVariant &variant) {
QMetaType::TypeFlags flags = QMetaType::typeFlags(variant.userType());
if (flags & QMetaType::PointerToQObject)
dbg.nospace() << variant.value<QObject*>();
+#else
+ Q_UNUSED(dbg);
+ Q_UNUSED(variant);
#endif
}
#endif
@@ -909,7 +913,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
Here is some example code to demonstrate the use of QVariant:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 0
+ \snippet code/src_corelib_kernel_qvariant.cpp 0
You can even store QList<QVariant> and QMap<QString, QVariant>
values in a variant, so you can easily construct arbitrarily
@@ -921,7 +925,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
have a defined type with no value set. However, note that QVariant
types can only be cast when they have had a value set.
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 1
+ \snippet code/src_corelib_kernel_qvariant.cpp 1
QVariant can be extended to support other types than those
mentioned in the \l Type enum. See the \l QMetaType documentation
@@ -935,13 +939,13 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
toColor() function. Instead, you can use the QVariant::value() or
the qvariant_cast() template function. For example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 2
+ \snippet code/src_corelib_kernel_qvariant.cpp 2
The inverse conversion (e.g., from QColor to QVariant) is
automatic for all data types supported by QVariant, including
GUI-related types:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 3
+ \snippet code/src_corelib_kernel_qvariant.cpp 3
\section1 Using canConvert() and convert() Consecutively
@@ -1677,13 +1681,15 @@ void QVariant::load(QDataStream &s)
return;
}
}
- create(static_cast<int>(typeId), 0);
+ create(typeId, 0);
d.is_null = is_null;
if (!isValid()) {
+ if (s.version() < QDataStream::Qt_5_0) {
// Since we wrote something, we should read something
- QString x;
- s >> x;
+ QString x;
+ s >> x;
+ }
d.is_null = true;
return;
}
@@ -1745,7 +1751,8 @@ void QVariant::save(QDataStream &s) const
}
if (!isValid()) {
- s << QString();
+ if (s.version() < QDataStream::Qt_5_0)
+ s << QString();
return;
}
@@ -2172,7 +2179,6 @@ inline T qNumVariantToHelper(const QVariant::Private &d,
\b{Warning:} If the value is convertible to a \l LongLong but is too
large to be represented in an int, the resulting arithmetic overflow will
not be reflected in \a ok. A simple workaround is to use QString::toInt().
- Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
\sa canConvert(), convert()
*/
@@ -2192,7 +2198,6 @@ int QVariant::toInt(bool *ok) const
\b{Warning:} If the value is convertible to a \l ULongLong but is too
large to be represented in an unsigned int, the resulting arithmetic overflow will
not be reflected in \a ok. A simple workaround is to use QString::toUInt().
- Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
\sa canConvert(), convert()
*/
@@ -2527,7 +2532,7 @@ bool QVariant::convert(int targetTypeId)
}
/*!
- \fn convert(const int type, void *ptr) const
+ \fn bool QVariant::convert(const int type, void *ptr) const
\internal
Created for qvariant_cast() usage
*/
@@ -2671,7 +2676,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 4
+ \snippet code/src_corelib_kernel_qvariant.cpp 4
\sa value(), fromValue(), canConvert()
*/
@@ -2688,7 +2693,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 5
+ \snippet code/src_corelib_kernel_qvariant.cpp 5
\sa setValue(), fromValue(), canConvert()
*/
@@ -2700,7 +2705,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 6
+ \snippet code/src_corelib_kernel_qvariant.cpp 6
\sa convert()
*/
@@ -2712,7 +2717,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
Example:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 7
+ \snippet code/src_corelib_kernel_qvariant.cpp 7
\note If you are working with custom types, you should use
the Q_DECLARE_METATYPE() macro to register your custom type.
@@ -2737,7 +2742,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
For example, a QObject pointer can be stored in a variant with the
following code:
- \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 8
+ \snippet code/src_corelib_kernel_qvariant.cpp 8
\sa QVariant::fromValue()
*/
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 8af1ab2161..b48bd0c8cc 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -48,6 +48,19 @@
QT_BEGIN_NAMESPACE
+class QWinEventNotifierPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWinEventNotifier)
+public:
+ QWinEventNotifierPrivate()
+ : handleToEvent(0), enabled(false) {}
+ QWinEventNotifierPrivate(HANDLE h, bool e)
+ : handleToEvent(h), enabled(e) {}
+
+ HANDLE handleToEvent;
+ bool enabled;
+};
+
/*!
\class QWinEventNotifier
\since 5.0
@@ -103,7 +116,7 @@ QT_BEGIN_NAMESPACE
*/
QWinEventNotifier::QWinEventNotifier(QObject *parent)
- : QObject(parent), handleToEvent(0), enabled(false)
+ : QObject(*new QWinEventNotifierPrivate, parent)
{}
/*!
@@ -118,14 +131,14 @@ QWinEventNotifier::QWinEventNotifier(QObject *parent)
*/
QWinEventNotifier::QWinEventNotifier(HANDLE hEvent, QObject *parent)
- : QObject(parent), handleToEvent(hEvent), enabled(false)
+ : QObject(*new QWinEventNotifierPrivate(hEvent, false), parent)
{
- Q_D(QObject);
+ Q_D(QWinEventNotifier);
QEventDispatcherWin32 *eventDispatcher = qobject_cast<QEventDispatcherWin32 *>(d->threadData->eventDispatcher);
Q_ASSERT_X(eventDispatcher, "QWinEventNotifier::QWinEventNotifier()",
"Cannot create a win event notifier without a QEventDispatcherWin32");
eventDispatcher->registerEventNotifier(this);
- enabled = true;
+ d->enabled = true;
}
/*!
@@ -149,8 +162,9 @@ QWinEventNotifier::~QWinEventNotifier()
void QWinEventNotifier::setHandle(HANDLE hEvent)
{
+ Q_D(QWinEventNotifier);
setEnabled(false);
- handleToEvent = hEvent;
+ d->handleToEvent = hEvent;
}
/*!
@@ -161,7 +175,8 @@ void QWinEventNotifier::setHandle(HANDLE hEvent)
HANDLE QWinEventNotifier::handle() const
{
- return handleToEvent;
+ Q_D(const QWinEventNotifier);
+ return d->handleToEvent;
}
/*!
@@ -172,7 +187,8 @@ HANDLE QWinEventNotifier::handle() const
bool QWinEventNotifier::isEnabled() const
{
- return enabled;
+ Q_D(const QWinEventNotifier);
+ return d->enabled;
}
/*!
@@ -184,16 +200,16 @@ bool QWinEventNotifier::isEnabled() const
void QWinEventNotifier::setEnabled(bool enable)
{
- if (enabled == enable) // no change
+ Q_D(QWinEventNotifier);
+ if (d->enabled == enable) // no change
return;
- enabled = enable;
+ d->enabled = enable;
- Q_D(QObject);
QEventDispatcherWin32 *eventDispatcher = qobject_cast<QEventDispatcherWin32 *>(d->threadData->eventDispatcher);
if (!eventDispatcher) // perhaps application is shutting down
return;
- if (enabled)
+ if (enable)
eventDispatcher->registerEventNotifier(this);
else
eventDispatcher->unregisterEventNotifier(this);
@@ -205,16 +221,17 @@ void QWinEventNotifier::setEnabled(bool enable)
bool QWinEventNotifier::event(QEvent * e)
{
+ Q_D(QWinEventNotifier);
if (e->type() == QEvent::ThreadChange) {
- if (enabled) {
+ if (d->enabled) {
QMetaObject::invokeMethod(this, "setEnabled", Qt::QueuedConnection,
- Q_ARG(bool, enabled));
+ Q_ARG(bool, true));
setEnabled(false);
}
}
QObject::event(e); // will activate filters
if (e->type() == QEvent::WinEventAct) {
- emit activated(handleToEvent);
+ emit activated(d->handleToEvent);
return true;
}
return false;
diff --git a/src/corelib/kernel/qwineventnotifier.h b/src/corelib/kernel/qwineventnotifier.h
index b364c68e05..36ec415124 100644
--- a/src/corelib/kernel/qwineventnotifier.h
+++ b/src/corelib/kernel/qwineventnotifier.h
@@ -54,11 +54,11 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-
+class QWinEventNotifierPrivate;
class Q_CORE_EXPORT QWinEventNotifier : public QObject
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QObject)
+ Q_DECLARE_PRIVATE(QWinEventNotifier)
public:
explicit QWinEventNotifier(QObject *parent = 0);
@@ -78,10 +78,6 @@ Q_SIGNALS:
protected:
bool event(QEvent * e);
-
-private:
- HANDLE handleToEvent;
- bool enabled;
};
QT_END_NAMESPACE