summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-08-04 08:33:52 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-08-04 09:02:17 (GMT)
commit4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1 (patch)
treeb34985c5716d98f01b9f36fd4a98f2ac9710099f /src/corelib/kernel
parenta0df97c03f26a38af17a42fb44ad6910536c8857 (diff)
parent2076f150995e541308b1d8da936b3e12ab68b886 (diff)
downloadQt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.zip
Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.gz
Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: config.tests/unix/openssl/openssl.pri demos/embedded/embedded.pro examples/itemviews/chart/chart.pro examples/network/network.pro examples/painting/painterpaths/painterpaths.pro examples/threads/mandelbrot/mandelbrot.pro qmake/project.cpp src/3rdparty/libtiff/libtiff/tif_config.h src/corelib/arch/arch.pri src/corelib/global/qglobal.cpp src/corelib/kernel/kernel.pri src/corelib/kernel/qcore_unix_p.h src/corelib/kernel/qobject.cpp src/corelib/thread/qthread_unix.cpp src/corelib/tools/qsharedpointer_impl.h src/corelib/tools/tools.pri src/gui/kernel/qaction.h src/gui/kernel/qapplication.cpp src/gui/painting/qregion.h src/gui/widgets/qlineedit.cpp src/gui/widgets/qlineedit_p.h src/network/socket/qnativesocketengine_unix.cpp tests/auto/qdir/tst_qdir.cpp tests/auto/qdiriterator/tst_qdiriterator.cpp tests/auto/qhttp/qhttp.pro tests/auto/qline/qline.pro tests/auto/qnetworkreply/tst_qnetworkreply.cpp tests/auto/qresourceengine/qresourceengine.pro tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qstring/qstring.pro tests/auto/qtcpsocket/qtcpsocket.pro tests/auto/qtcpsocket/tst_qtcpsocket.cpp
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/kernel.pri12
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp48
-rw-r--r--src/corelib/kernel/qabstractitemmodel.h4
-rw-r--r--src/corelib/kernel/qabstractitemmodel_p.h5
-rw-r--r--src/corelib/kernel/qcore_unix.cpp11
-rw-r--r--src/corelib/kernel/qcore_unix_p.h63
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp8
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp68
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h61
-rw-r--r--src/corelib/kernel/qfunctions_p.h2
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.cpp202
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.h153
-rw-r--r--src/corelib/kernel/qguard_p.h157
-rw-r--r--src/corelib/kernel/qmetaobject.cpp107
-rw-r--r--src/corelib/kernel/qmetaobject.h4
-rw-r--r--src/corelib/kernel/qobject.cpp142
-rw-r--r--src/corelib/kernel/qobject.h11
-rw-r--r--src/corelib/kernel/qobject_p.h45
-rw-r--r--src/corelib/kernel/qobjectdefs.h5
19 files changed, 982 insertions, 126 deletions
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 4b7baef..124b2b3 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -32,7 +32,8 @@ HEADERS += \
kernel/qsharedmemory_p.h \
kernel/qsystemsemaphore.h \
kernel/qsystemsemaphore_p.h \
- kernel/qfunctions_p.h
+ kernel/qfunctions_p.h \
+ kernel/qguard_p.h
SOURCES += \
kernel/qabstracteventdispatcher.cpp \
@@ -54,7 +55,7 @@ SOURCES += \
kernel/qcoreglobaldata.cpp \
kernel/qsharedmemory.cpp \
kernel/qsystemsemaphore.cpp \
- kernel/qpointer.cpp
+ kernel/qpointer.cpp
win32 {
SOURCES += \
@@ -128,3 +129,10 @@ symbian {
kernel/qcore_symbian_p.h
}
+vxworks {
+ SOURCES += \
+ kernel/qfunctions_vxworks.cpp
+ HEADERS += \
+ kernel/qfunctions_vxworks.h
+}
+
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 3d9263e..bc95c60 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -467,6 +467,27 @@ QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
return qEmptyModel();
}
+namespace {
+ struct DefaultRoleNames : public QHash<int, QByteArray>
+ {
+ DefaultRoleNames() {
+ (*this)[Qt::DisplayRole] = "display";
+ (*this)[Qt::DecorationRole] = "decoration";
+ (*this)[Qt::EditRole] = "edit";
+ (*this)[Qt::ToolTipRole] = "toolTip";
+ (*this)[Qt::StatusTipRole] = "statusTip";
+ (*this)[Qt::WhatsThisRole] = "whatsThis";
+ }
+ };
+}
+
+Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames)
+
+const QHash<int,QByteArray> &QAbstractItemModelPrivate::defaultRoleNames()
+{
+ return *qDefaultRoleNames();
+}
+
/*!
\internal
return true if \a value contains a numerical type
@@ -1863,6 +1884,33 @@ QSize QAbstractItemModel::span(const QModelIndex &) const
}
/*!
+ Sets the model's role names to \a roleNames.
+
+ This function is provided to allow mapping of role identifiers to
+ role property names in Declarative UI. This function must be called
+ before the model is used. Modifying the role names after the model
+ has been set may result in undefined behaviour.
+
+ \sa roleNames()
+*/
+void QAbstractItemModel::setRoleNames(const QHash<int,QByteArray> &roleNames)
+{
+ Q_D(QAbstractItemModel);
+ d->roleNames = roleNames;
+}
+
+/*!
+ Returns the model's role names.
+
+ \sa setRoleNames()
+*/
+const QHash<int,QByteArray> &QAbstractItemModel::roleNames() const
+{
+ Q_D(const QAbstractItemModel);
+ return d->roleNames;
+}
+
+/*!
Called to let the model know that it should submit whatever it has cached
to the permanent storage. Typically used for row editing.
diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h
index dc7d7bd..a6bbff4 100644
--- a/src/corelib/kernel/qabstractitemmodel.h
+++ b/src/corelib/kernel/qabstractitemmodel.h
@@ -220,6 +220,8 @@ public:
Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
virtual QSize span(const QModelIndex &index) const;
+ const QHash<int,QByteArray> &roleNames() const;
+
#ifdef Q_NO_USING_KEYWORD
inline QObject *parent() const { return QObject::parent(); }
#else
@@ -282,6 +284,8 @@ protected:
void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to);
QModelIndexList persistentIndexList() const;
+ void setRoleNames(const QHash<int,QByteArray> &roleNames);
+
private:
Q_DECLARE_PRIVATE(QAbstractItemModel)
Q_DISABLE_COPY(QAbstractItemModel)
diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h
index c047f95..6a29723 100644
--- a/src/corelib/kernel/qabstractitemmodel_p.h
+++ b/src/corelib/kernel/qabstractitemmodel_p.h
@@ -78,7 +78,7 @@ class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QAbstractItemModel)
public:
- QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1) {}
+ QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1), roleNames(defaultRoleNames()) {}
void removePersistentIndexData(QPersistentModelIndexData *data);
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void rowsInserted(const QModelIndex &parent, int first, int last);
@@ -144,6 +144,9 @@ public:
} persistent;
Qt::DropActions supportedDragActions;
+
+ QHash<int,QByteArray> roleNames;
+ static const QHash<int,QByteArray> &defaultRoleNames();
};
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 28c1d9c..b57d385 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -41,11 +41,14 @@
#include "qcore_unix_p.h"
-#include <sys/select.h>
-#include <sys/time.h>
-#include <stdlib.h>
+#ifndef Q_OS_VXWORKS
+# include <sys/select.h>
+# include <sys/time.h>
+#else
+# include <selectLib.h>
+#endif
-#include "qeventdispatcher_unix_p.h" // for the timeval operators
+#include <stdlib.h>
#ifdef Q_OS_MAC
#include <mach/mach_time.h>
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 28bc34a..e301c92 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -67,6 +67,10 @@
#include <errno.h>
#include <fcntl.h>
+#if defined(Q_OS_VXWORKS)
+# include <ioLib.h>
+#endif
+
struct sockaddr;
#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204
@@ -110,6 +114,51 @@ using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement);
QT_BEGIN_NAMESPACE
+// Internal operator functions for timevals
+inline timeval &normalizedTimeval(timeval &t)
+{
+ while (t.tv_usec > 1000000l) {
+ ++t.tv_sec;
+ t.tv_usec -= 1000000l;
+ }
+ while (t.tv_usec < 0l) {
+ --t.tv_sec;
+ t.tv_usec += 1000000l;
+ }
+ return t;
+}
+inline bool operator<(const timeval &t1, const timeval &t2)
+{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); }
+inline bool operator==(const timeval &t1, const timeval &t2)
+{ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; }
+inline timeval &operator+=(timeval &t1, const timeval &t2)
+{
+ t1.tv_sec += t2.tv_sec;
+ t1.tv_usec += t2.tv_usec;
+ return normalizedTimeval(t1);
+}
+inline timeval operator+(const timeval &t1, const timeval &t2)
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec + t2.tv_sec;
+ tmp.tv_usec = t1.tv_usec + t2.tv_usec;
+ return normalizedTimeval(tmp);
+}
+inline timeval operator-(const timeval &t1, const timeval &t2)
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1);
+ tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000);
+ return normalizedTimeval(tmp);
+}
+inline timeval operator*(const timeval &t1, int mul)
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec * mul;
+ tmp.tv_usec = t1.tv_usec * mul;
+ return normalizedTimeval(tmp);
+}
+
// don't call QT_OPEN or ::open
// call qt_safe_open
static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777)
@@ -129,6 +178,7 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07
#undef QT_OPEN
#define QT_OPEN qt_safe_open
+#ifndef Q_OS_VXWORKS // no POSIX pipes in VxWorks
// don't call ::pipe
// call qt_safe_pipe
static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
@@ -164,6 +214,8 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0)
return 0;
}
+#endif // Q_OS_VXWORKS
+
// don't call dup or fcntl(F_DUPFD)
static inline int qt_safe_dup(int oldfd, int atleast = 0, int flags = FD_CLOEXEC)
{
@@ -238,8 +290,8 @@ static inline int qt_safe_close(int fd)
#undef QT_CLOSE
#define QT_CLOSE qt_safe_close
-// Open C does not (yet?) implement these on Symbian OS
-#ifndef Q_OS_SYMBIAN
+// Open C does not (yet?) implement these on Symbian OS and VxWorks doesn't have processes
+#if !defined(Q_OS_SYMBIAN) && !defined(Q_OS_VXWORKS)
static inline int qt_safe_execve(const char *filename, char *const argv[],
char *const envp[])
{
@@ -263,6 +315,7 @@ static inline int qt_safe_execvp(const char *file, char *const argv[])
}
#endif
+#ifndef Q_OS_VXWORKS // no processes on VxWorks
static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
{
register int ret;
@@ -270,6 +323,12 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
return ret;
}
+#endif // Q_OS_VXWORKS
+
+#if !defined(_POSIX_MONOTONIC_CLOCK)
+# define _POSIX_MONOTONIC_CLOCK -1
+#endif
+
bool qt_gettime_is_monotonic();
timeval qt_gettime();
Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 5865dc3..b84ad53 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -61,6 +61,7 @@
#include <private/qthread_p.h>
#include <qlibraryinfo.h>
#include <private/qfactoryloader_p.h>
+#include <private/qfunctions_p.h>
#ifdef Q_OS_SYMBIAN
# include <exception>
@@ -88,6 +89,10 @@
# include <locale.h>
#endif
+#ifdef Q_OS_VXWORKS
+# include <taskLib.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QLockedMutexUnlocker
@@ -1917,8 +1922,9 @@ qint64 QCoreApplication::applicationPid()
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
return GetCurrentProcessId();
+#elif defined(Q_OS_VXWORKS)
+ return (pid_t) taskIdCurrent;
#else
- // UNIX
return getpid();
#endif
}
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index c3979e8..78a2b0b 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -55,6 +55,16 @@
#include <stdio.h>
#include <stdlib.h>
+// VxWorks doesn't correctly set the _POSIX_... options
+#if defined(Q_OS_VXWORKS)
+# if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK <= 0)
+# undef _POSIX_MONOTONIC_CLOCK
+# define _POSIX_MONOTONIC_CLOCK 1
+# endif
+# include <pipeDrv.h>
+# include <selectLib.h>
+#endif
+
#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED)
# include <sys/times.h>
#endif
@@ -77,7 +87,7 @@ static void signalHandler(int sig)
}
-#ifdef Q_OS_INTEGRITY
+#if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS)
static void initThreadPipeFD(int fd)
{
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -98,20 +108,47 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
{
extern Qt::HANDLE qt_application_thread_id;
mainThread = (QThread::currentThreadId() == qt_application_thread_id);
+ bool pipefail = false;
// initialize the common parts of the event loop
-#ifdef Q_OS_INTEGRITY
+#if defined(Q_OS_INTEGRITY)
// INTEGRITY doesn't like a "select" on pipes, so use socketpair instead
- if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1)
+ if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair");
-
- initThreadPipeFD(thread_pipe[0]);
- initThreadPipeFD(thread_pipe[1]);
+ pipefail = true;
+ } else {
+ initThreadPipeFD(thread_pipe[0]);
+ initThreadPipeFD(thread_pipe[1]);
+ }
+#elif defined(Q_OS_VXWORKS)
+ char name[20];
+ qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
+
+ // make sure there is no pipe with this name
+ pipeDevDelete(name, true);
+ // create the pipe
+ if (pipeDevCreate(name, 128 /*maxMsg*/, 1 /*maxLength*/) != OK) {
+ perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe device");
+ pipefail = true;
+ } else {
+ if ((thread_pipe[0] = open(name, O_RDWR, 0)) < 0) {
+ perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
+ pipefail = true;
+ } else {
+ initThreadPipeFD(thread_pipe[0]);
+ thread_pipe[1] = thread_pipe[0];
+ }
+ }
#else
- if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1)
+ if (qt_safe_pipe(thread_pipe, O_NONBLOCK) == -1) {
perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe");
+ pipefail = true;
+ }
#endif
+ if (pipefail)
+ qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
+
sn_highest = -1;
interrupt = false;
@@ -119,9 +156,18 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
{
+#if defined(Q_OS_VXWORKS)
+ close(thread_pipe[0]);
+
+ char name[20];
+ qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdCurrent));
+
+ pipeDevDelete(name, true);
+#else
// cleanup the common parts of the event loop
close(thread_pipe[0]);
close(thread_pipe[1]);
+#endif
// cleanup timers
qDeleteAll(timerList);
@@ -226,9 +272,15 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
// select doesn't immediately return next time
int nevents = 0;
if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) {
+#if defined(Q_OS_VXWORKS)
+ char c[16];
+ ::read(thread_pipe[0], c, sizeof(c));
+ ::ioctl(thread_pipe[0], FIOFLUSH, 0);
+#else
char c[16];
while (::read(thread_pipe[0], c, sizeof(c)) > 0)
;
+#endif
if (!wakeUps.testAndSetRelease(1, 0)) {
// hopefully, this is dead code
qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!");
@@ -313,7 +365,7 @@ timeval qAbs(const timeval &t)
*/
bool QTimerInfoList::timeChanged(timeval *delta)
{
- tms unused;
+ struct tms unused;
clock_t currentTicks = times(&unused);
clock_t elapsedTicks = currentTicks - previousTicks;
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index fedbccf..a52af00 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -56,65 +56,20 @@
#include "QtCore/qabstracteventdispatcher.h"
#include "QtCore/qlist.h"
#include "private/qabstracteventdispatcher_p.h"
+#include "private/qcore_unix_p.h"
#include "private/qpodlist_p.h"
#include "QtCore/qvarlengtharray.h"
-#include <sys/types.h>
-#include <sys/time.h>
-#if !defined(Q_OS_HPUX) || defined(__ia64)
-#include <sys/select.h>
+#if defined(Q_OS_VXWORKS)
+# include <sys/times.h>
+#else
+# include <sys/time.h>
+# if !defined(Q_OS_HPUX) || defined(__ia64)
+# include <sys/select.h>
+# endif
#endif
-#include <unistd.h>
QT_BEGIN_NAMESPACE
-#if !defined(_POSIX_MONOTONIC_CLOCK)
-# define _POSIX_MONOTONIC_CLOCK -1
-#endif
-
-// Internal operator functions for timevals
-inline timeval &normalizedTimeval(timeval &t)
-{
- while (t.tv_usec > 1000000l) {
- ++t.tv_sec;
- t.tv_usec -= 1000000l;
- }
- while (t.tv_usec < 0l) {
- --t.tv_sec;
- t.tv_usec += 1000000l;
- }
- return t;
-}
-inline bool operator<(const timeval &t1, const timeval &t2)
-{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); }
-inline bool operator==(const timeval &t1, const timeval &t2)
-{ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; }
-inline timeval &operator+=(timeval &t1, const timeval &t2)
-{
- t1.tv_sec += t2.tv_sec;
- t1.tv_usec += t2.tv_usec;
- return normalizedTimeval(t1);
-}
-inline timeval operator+(const timeval &t1, const timeval &t2)
-{
- timeval tmp;
- tmp.tv_sec = t1.tv_sec + t2.tv_sec;
- tmp.tv_usec = t1.tv_usec + t2.tv_usec;
- return normalizedTimeval(tmp);
-}
-inline timeval operator-(const timeval &t1, const timeval &t2)
-{
- timeval tmp;
- tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1);
- tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000);
- return normalizedTimeval(tmp);
-}
-inline timeval operator*(const timeval &t1, int mul)
-{
- timeval tmp;
- tmp.tv_sec = t1.tv_sec * mul;
- tmp.tv_usec = t1.tv_usec * mul;
- return normalizedTimeval(tmp);
-}
// internal timer info
struct QTimerInfo {
diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h
index a7f2f9d..ad44a15 100644
--- a/src/corelib/kernel/qfunctions_p.h
+++ b/src/corelib/kernel/qfunctions_p.h
@@ -57,6 +57,8 @@
#if defined(Q_OS_WINCE)
# include "QtCore/qfunctions_wince.h"
+#elif defined(Q_OS_VXWORKS)
+# include "QtCore/qfunctions_vxworks.h"
#endif
#ifdef Q_CC_RVCT
diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp
new file mode 100644
index 0000000..6d5e7cc
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_vxworks.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifdef Q_OS_VXWORKS
+
+#include "qplatformdefs.h"
+#include "qfunctions_vxworks.h"
+
+#include <vmLib.h>
+#include <selectLib.h>
+#include <ioLib.h>
+
+QT_USE_NAMESPACE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// no lfind() - used by the TIF image format
+void *lfind(const void* key, const void* base, size_t* elements, size_t size,
+ int (*compare)(const void*, const void*))
+{
+ const char* current = (char*) base;
+ const char* const end = (char*) (current + (*elements) * size);
+ while (current != end) {
+ if (compare(current, key) == 0)
+ return (void*)current;
+ current += size;
+ }
+ return 0;
+}
+
+
+// no rand_r(), but rand()
+// NOTE: this implementation is wrong for multi threaded applications,
+// but there is no way to get it right on VxWorks (in kernel mode)
+int rand_r(unsigned int * /*seedp*/)
+{
+ return rand();
+}
+
+// no usleep() support
+int usleep(unsigned int usec)
+{
+ div_t dt = div(usec, 1000000);
+ struct timespec ts = { dt.quot, dt.rem * 1000 };
+
+ return nanosleep(&ts, 0);
+}
+
+
+// gettimeofday() is declared, but is missing from the library
+// It IS however defined in the Curtis-Wright X11 libraries, so
+// we have to make the symbol 'weak'
+#if defined(Q_CC_DIAB)
+# pragma weak gettimeofday
+#endif
+int gettimeofday(struct timeval *tv, void /*struct timezone*/ *)
+{
+ // the compiler will optimize this and will only use one code path
+ if (sizeof(struct timeval) == sizeof(struct timespec)) {
+ int res = clock_gettime(CLOCK_REALTIME, (struct timespec *) tv);
+ if (!res)
+ tv->tv_usec /= 1000;
+ return res;
+ } else {
+ struct timespec ts;
+
+ int res = clock_gettime(CLOCK_REALTIME, &ts);
+ if (!res) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+ return res;
+ }
+}
+
+// neither getpagesize() or sysconf(_SC_PAGESIZE) are available
+int getpagesize()
+{
+ return vmPageSizeGet();
+}
+
+// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h)
+int symlink(const char *, const char *)
+{
+ errno = EIO;
+ return -1;
+}
+
+ssize_t readlink(const char *, char *, size_t)
+{
+ errno = EIO;
+ return -1;
+}
+
+// there's no truncate(), but ftruncate() support...
+int truncate(const char *path, off_t length)
+{
+ int fd = open(path, O_WRONLY, 00777);
+ if (fd >= 0) {
+ int res = ftruncate(fd, length);
+ int en = errno;
+ close(fd);
+ errno = en;
+ return res;
+ }
+ // errno is already set by open
+ return -1;
+}
+
+
+
+// VxWorks doesn't know about passwd & friends.
+// in order to avoid patching the unix fs path everywhere
+// we introduce some dummy functions that simulate a single
+// 'root' user on the system.
+
+uid_t getuid()
+{
+ return 0;
+}
+
+gid_t getgid()
+{
+ return 0;
+}
+
+uid_t geteuid()
+{
+ return 0;
+}
+
+struct passwd *getpwuid(uid_t uid)
+{
+ static struct passwd pwbuf = { "root", 0, 0, 0, 0, 0, 0 };
+
+ if (uid == 0) {
+ return &pwbuf;
+ } else {
+ errno = ENOENT;
+ return 0;
+ }
+}
+
+struct group *getgrgid(gid_t gid)
+{
+ static struct group grbuf = { "root", 0, 0, 0 };
+
+ if (gid == 0) {
+ return &grbuf;
+ } else {
+ errno = ENOENT;
+ return 0;
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // Q_OS_VXWORKS
diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h
new file mode 100644
index 0000000..cc98948
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_vxworks.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFUNCTIONS_VXWORKS_H
+#define QFUNCTIONS_VXWORKS_H
+#ifdef Q_OS_VXWORKS
+
+#include <unistd.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/times.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#ifndef QT_NO_IPV6IFNAME
+#include <net/if.h>
+#endif
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+QT_MODULE(Core)
+#endif
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+
+#ifndef NSIG
+#define NSIG _NSIGS
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// isascii is missing (sometimes!!)
+#ifndef isascii
+inline int isascii(int c) { return (c & 0x7f); }
+#endif
+
+// no lfind() - used by the TIF image format
+void *lfind(const void* key, const void* base, size_t* elements, size_t size,
+ int (*compare)(const void*, const void*));
+
+// no rand_r(), but rand()
+// NOTE: this implementation is wrong for multi threaded applications,
+// but there is no way to get it right on VxWorks (in kernel mode)
+int rand_r(unsigned int * /*seedp*/);
+
+// no usleep() support
+int usleep(unsigned int);
+
+// gettimeofday() is declared, but is missing from the library.
+// It IS however defined in the Curtis-Wright X11 libraries, so
+// we have to make the symbol 'weak'
+int gettimeofday(struct timeval *tv, void /*struct timezone*/ *) __attribute__((weak));
+
+// neither getpagesize() or sysconf(_SC_PAGESIZE) are available
+int getpagesize();
+
+// symlinks are not supported (lstat is now just a call to stat - see qplatformdefs.h)
+int symlink(const char *, const char *);
+ssize_t readlink(const char *, char *, size_t);
+
+// there's no truncate(), but ftruncate() support...
+int truncate(const char *path, off_t length);
+
+// VxWorks doesn't know about passwd & friends.
+// in order to avoid patching the unix fs path everywhere
+// we introduce some dummy functions that simulate a single
+// 'root' user on the system.
+
+uid_t getuid();
+gid_t getgid();
+uid_t geteuid();
+
+struct passwd {
+ char *pw_name; /* user name */
+ char *pw_passwd; /* user password */
+ uid_t pw_uid; /* user ID */
+ gid_t pw_gid; /* group ID */
+ char *pw_gecos; /* real name */
+ char *pw_dir; /* home directory */
+ char *pw_shell; /* shell program */
+};
+
+struct group {
+ char *gr_name; /* group name */
+ char *gr_passwd; /* group password */
+ gid_t gr_gid; /* group ID */
+ char **gr_mem; /* group members */
+};
+
+struct passwd *getpwuid(uid_t uid);
+struct group *getgrgid(gid_t gid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // Q_OS_VXWORKS
+#endif // QFUNCTIONS_VXWORKS_H
diff --git a/src/corelib/kernel/qguard_p.h b/src/corelib/kernel/qguard_p.h
new file mode 100644
index 0000000..6af01ac
--- /dev/null
+++ b/src/corelib/kernel/qguard_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGUARD_P_H
+#define QGUARD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qglobal.h"
+
+QT_BEGIN_NAMESPACE
+
+class QObject;
+template<class T>
+class QGuard
+{
+ QObject *o;
+ QGuard<QObject> *next;
+ QGuard<QObject> **prev;
+ friend void q_guard_addGuard(QGuard<QObject> *);
+ friend void q_guard_removeGuard(QGuard<QObject> *);
+ friend class QObjectPrivate;
+public:
+ inline QGuard();
+ inline QGuard(T *);
+ inline QGuard(const QGuard<T> &);
+ inline virtual ~QGuard();
+
+ inline QGuard<T> &operator=(const QGuard<T> &o);
+ inline QGuard<T> &operator=(T *);
+
+ inline bool isNull() const
+ { return !o; }
+
+ inline T* operator->() const
+ { return static_cast<T*>(const_cast<QObject*>(o)); }
+ inline T& operator*() const
+ { return *static_cast<T*>(const_cast<QObject*>(o)); }
+ inline operator T*() const
+ { return static_cast<T*>(const_cast<QObject*>(o)); }
+ inline T* data() const
+ { return static_cast<T*>(const_cast<QObject*>(o)); }
+
+protected:
+ virtual void objectDestroyed(T *) {}
+};
+
+QT_END_NAMESPACE
+
+#include "private/qobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+inline void q_guard_addGuard(QGuard<QObject> *);
+inline void q_guard_removeGuard(QGuard<QObject> *);
+
+template<class T>
+QGuard<T>::QGuard()
+: o(0), next(0), prev(0)
+{
+}
+
+template<class T>
+QGuard<T>::QGuard(T *g)
+: o(g), next(0), prev(0)
+{
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+}
+
+template<class T>
+QGuard<T>::QGuard(const QGuard<T> &g)
+: o(g.o), next(0), prev(0)
+{
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+}
+
+template<class T>
+QGuard<T>::~QGuard()
+{
+ if (prev) q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ o = 0;
+}
+
+template<class T>
+QGuard<T> &QGuard<T>::operator=(const QGuard<T> &g)
+{
+ if (g.o != o) {
+ if (prev)
+ q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ o = g.o;
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ }
+ return *this;
+}
+
+template<class T>
+inline QGuard<T> &QGuard<T>::operator=(T *g)
+{
+ if (g != o) {
+ if (prev)
+ q_guard_removeGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ o = g;
+ if (o) q_guard_addGuard(reinterpret_cast<QGuard<QObject> *>(this));
+ }
+ return *this;
+}
+
+QT_END_NAMESPACE
+
+#endif // QGUARD_P_H
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 08cecaf..9ff0bc1 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -148,7 +148,9 @@ enum PropertyFlags {
Resettable = 0x00000004,
EnumOrFlag = 0x00000008,
StdCppSet = 0x00000100,
-// Override = 0x00000200,
+// Override = 0x00000200,
+ Constant = 0x00000400,
+ Final = 0x00000800,
Designable = 0x00001000,
ResolveDesignable = 0x00002000,
Scriptable = 0x00004000,
@@ -179,6 +181,10 @@ enum MethodFlags {
MethodScriptable = 0x40
};
+enum MetaObjectFlags {
+ DynamicMetaObject = 0x01
+};
+
struct QMetaObjectPrivate
{
int revision;
@@ -188,6 +194,7 @@ struct QMetaObjectPrivate
int propertyCount, propertyData;
int enumeratorCount, enumeratorData;
int constructorCount, constructorData;
+ int flags;
};
static inline const QMetaObjectPrivate *priv(const uint* data)
@@ -277,6 +284,17 @@ int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
}
/*!
+ \internal
+*/
+int QMetaObject::metacall(QObject *object, Call cl, int idx, void **argv)
+{
+ if (QMetaObject *mo = object->d_ptr->metaObject)
+ return static_cast<QAbstractDynamicMetaObject*>(mo)->metaCall(cl, idx, argv);
+ else
+ return object->qt_metacall(cl, idx, argv);
+}
+
+/*!
\fn const char *QMetaObject::className() const
Returns the class name.
@@ -696,6 +714,14 @@ int QMetaObject::indexOfProperty(const char *name) const
}
m = m->d.superdata;
}
+
+ if (i == -1 && priv(this->d.data)->revision >= 3 && (priv(this->d.data)->flags & DynamicMetaObject)){
+ QAbstractDynamicMetaObject *me =
+ const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(this));
+
+ i = me->createProperty(name, 0);
+ }
+
return i;
}
@@ -1326,6 +1352,16 @@ int QMetaMethod::attributes() const
}
/*!
+ Returns this method's index.
+*/
+int QMetaMethod::methodIndex() const
+{
+ if (!mobj)
+ return -1;
+ return ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset();
+}
+
+/*!
Returns the access specification of this method (private,
protected, or public).
@@ -1525,7 +1561,7 @@ bool QMetaMethod::invoke(QObject *object,
// recompute the methodIndex by reversing the arithmetic in QMetaObject::property()
int methodIndex = ((handle - priv(mobj->d.data)->methodData) / 5) + mobj->methodOffset();
if (connectionType == Qt::DirectConnection) {
- return object->qt_metacall(QMetaObject::InvokeMetaMethod, methodIndex, param) < 0;
+ return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, methodIndex, param) < 0;
} else {
if (returnValue.data()) {
qWarning("QMetaMethod::invoke: Unable to invoke methods with return values in "
@@ -2040,6 +2076,16 @@ int QMetaProperty::userType() const
}
/*!
+ Returns this property's index.
+*/
+int QMetaProperty::propertyIndex() const
+{
+ if (!mobj)
+ return -1;
+ return idx + mobj->propertyOffset();
+}
+
+/*!
Returns true if the property's type is an enumeration value that
is used as a flag; otherwise returns false.
@@ -2151,9 +2197,8 @@ QVariant QMetaProperty::read(const QObject *object) const
value = QVariant(t, (void*)0);
argv[0] = value.data();
}
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::ReadProperty,
- idx + mobj->propertyOffset(),
- argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::ReadProperty,
+ idx + mobj->propertyOffset(), argv);
if (status != -1)
return value;
@@ -2224,7 +2269,7 @@ bool QMetaProperty::write(QObject *object, const QVariant &value) const
argv[0] = &v;
else
argv[0] = v.data();
- object->qt_metacall(QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, idx + mobj->propertyOffset(), argv);
return status;
}
@@ -2241,7 +2286,7 @@ bool QMetaProperty::reset(QObject *object) const
if (!object || !mobj || !isResettable())
return false;
void *argv[] = { 0 };
- object->qt_metacall(QMetaObject::ResetProperty, idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(object, QMetaObject::ResetProperty, idx + mobj->propertyOffset(), argv);
return true;
}
@@ -2355,8 +2400,8 @@ bool QMetaProperty::isDesignable(const QObject *object) const
bool b = flags & Designable;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyDesignable,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyDesignable,
+ idx + mobj->propertyOffset(), argv);
}
return b;
@@ -2381,8 +2426,8 @@ bool QMetaProperty::isScriptable(const QObject *object) const
bool b = flags & Scriptable;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyScriptable,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyScriptable,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
@@ -2405,8 +2450,8 @@ bool QMetaProperty::isStored(const QObject *object) const
bool b = flags & Stored;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyStored,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyStored,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
@@ -2432,13 +2477,41 @@ bool QMetaProperty::isUser(const QObject *object) const
bool b = flags & User;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyUser,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyUser,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
/*!
+ Returns true if the property is constant; otherwise returns false.
+
+ A property is constant if the \c{Q_PROPERTY()}'s \c CONSTANT attribute
+ is set.
+*/
+bool QMetaProperty::isConstant() const
+{
+ if (!mobj)
+ return false;
+ int flags = mobj->d.data[handle + 2];
+ return flags & Constant;
+}
+
+/*!
+ Returns true if the property is final; otherwise returns false.
+
+ A property is final if the \c{Q_PROPERTY()}'s \c FINAL attribute
+ is set.
+*/
+bool QMetaProperty::isFinal() const
+{
+ if (!mobj)
+ return false;
+ int flags = mobj->d.data[handle + 2];
+ return flags & Final;
+}
+
+/*!
\obsolete
Returns true if the property is editable for the given \a object;
@@ -2458,8 +2531,8 @@ bool QMetaProperty::isEditable(const QObject *object) const
bool b = flags & Editable;
if (object) {
void *argv[] = { &b };
- const_cast<QObject*>(object)->qt_metacall(QMetaObject::QueryPropertyEditable,
- idx + mobj->propertyOffset(), argv);
+ QMetaObject::metacall(const_cast<QObject*>(object), QMetaObject::QueryPropertyEditable,
+ idx + mobj->propertyOffset(), argv);
}
return b;
}
diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h
index 000ba6e..419fe06 100644
--- a/src/corelib/kernel/qmetaobject.h
+++ b/src/corelib/kernel/qmetaobject.h
@@ -69,6 +69,7 @@ public:
MethodType methodType() const;
enum Attributes { Compatibility = 0x1, Cloned = 0x2, Scriptable = 0x4 };
int attributes() const;
+ int methodIndex() const;
inline const QMetaObject *enclosingMetaObject() const { return mobj; }
@@ -178,6 +179,7 @@ public:
const char *typeName() const;
QVariant::Type type() const;
int userType() const;
+ int propertyIndex() const;
bool isReadable() const;
bool isWritable() const;
@@ -187,6 +189,8 @@ public:
bool isStored(const QObject *obj = 0) const;
bool isEditable(const QObject *obj = 0) const;
bool isUser(const QObject *obj = 0) const;
+ bool isConstant() const;
+ bool isFinal() const;
bool isFlagType() const;
bool isEnumType() const;
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 3aa9193..e849227 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -123,7 +123,7 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), currentSender(0), currentChildBeingDeleted(0), connectionLists(0), senders(0)
+ : threadData(0), currentSender(0), declarativeData(0), connectionLists(0), senders(0)
{
if (version != QObjectPrivateVersion)
qFatal("Cannot mix incompatible Qt libraries");
@@ -139,15 +139,19 @@ QObjectPrivate::QObjectPrivate(int version)
receiveChildEvents = true;
postedEvents = 0;
extraData = 0;
- connectedSignals = 0;
+ for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i)
+ connectedSignals[i] = 0;
inEventHandler = false;
inThreadChangeEvent = false;
deleteWatch = 0;
+ objectGuards = 0;
+ metaObject = 0;
hasGuards = false;
}
QObjectPrivate::~QObjectPrivate()
{
+ delete static_cast<QAbstractDynamicMetaObject*>(metaObject);
if (deleteWatch)
*deleteWatch = 1;
#ifndef QT_NO_USERDATA
@@ -427,8 +431,24 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o)
*/
void QObjectPrivate::clearGuards(QObject *object)
{
- if (!QObjectPrivate::get(object)->hasGuards)
+ QObjectPrivate *priv = QObjectPrivate::get(object);
+ QGuard<QObject> *guard = priv->objectGuards;
+ while (guard) {
+ guard->o = 0;
+ guard = guard->next;
+ }
+ while (priv->objectGuards) {
+ guard = priv->objectGuards;
+ guard->prev = 0;
+ if (guard->next) guard->next->prev = &priv->objectGuards;
+ priv->objectGuards = guard->next;
+ guard->next = 0;
+ guard->objectDestroyed(object);
+ }
+
+ if (!priv->hasGuards)
return;
+
GuardHash *hash = 0;
QMutex *mutex = 0;
QT_TRY {
@@ -479,7 +499,7 @@ QMetaCallEvent::~QMetaCallEvent()
*/
int QMetaCallEvent::placeMetaCall(QObject *object)
{
- return object->qt_metacall(QMetaObject::InvokeMetaMethod, id_, args_);
+ return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, id_, args_);
}
/*!
@@ -844,6 +864,14 @@ QObject::~QObject()
d->eventFilters.clear();
+ // As declarativeData is in a union with currentChildBeingDeleted, this must
+ // be done (and declarativeData set back to 0) before deleting children.
+ if(d->declarativeData) {
+ QDeclarativeData *dd = d->declarativeData;
+ d->declarativeData = 0;
+ dd->destroyed(this);
+ }
+
if (!d->children.isEmpty())
d->deleteChildren();
@@ -1850,12 +1878,13 @@ void QObjectPrivate::deleteChildren()
// don't use qDeleteAll as the destructor of the child might
// delete siblings
for (int i = 0; i < children.count(); ++i) {
- currentChildBeingDeleted = children.at(i);
+ QObject *child = children.at(i);
children[i] = 0;
- delete currentChildBeingDeleted;
+ if (child)
+ child->d_func()->parent = 0;
+ delete child;
}
children.clear();
- currentChildBeingDeleted = 0;
wasDeleted = reallyWasDeleted;
}
@@ -1866,20 +1895,14 @@ void QObjectPrivate::setParent_helper(QObject *o)
return;
if (parent) {
QObjectPrivate *parentD = parent->d_func();
- if (parentD->wasDeleted && wasDeleted
- && parentD->currentChildBeingDeleted == q) {
- // don't do anything since QObjectPrivate::deleteChildren() already
- // cleared our entry in parentD->children.
+ const int index = parentD->children.indexOf(q);
+ if (parentD->wasDeleted) {
+ parentD->children[index] = 0;
} else {
- const int index = parentD->children.indexOf(q);
- if (parentD->wasDeleted) {
- parentD->children[index] = 0;
- } else {
- parentD->children.removeAt(index);
- if (sendChildEvents && parentD->receiveChildEvents) {
- QChildEvent e(QEvent::ChildRemoved, q);
- QCoreApplication::sendEvent(parent, &e);
- }
+ parentD->children.removeAt(index);
+ if (sendChildEvents && parentD->receiveChildEvents) {
+ QChildEvent e(QEvent::ChildRemoved, q);
+ QCoreApplication::sendEvent(parent, &e);
}
}
}
@@ -2867,10 +2890,16 @@ bool QMetaObject::connect(const QObject *sender, int signal_index,
s->d_func()->addConnection(signal_index, c);
- if (signal_index < 0)
- sender->d_func()->connectedSignals = ~0u;
- else if (signal_index < 32)
- sender->d_func()->connectedSignals |= (1 << signal_index);
+ if (signal_index < 0) {
+ for (uint i = 0; i < (sizeof sender->d_func()->connectedSignals
+ / sizeof sender->d_func()->connectedSignals[0] ); ++i)
+ sender->d_func()->connectedSignals[i] = ~0u;
+ } else if (signal_index < (int)sizeof sender->d_func()->connectedSignals * 8) {
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ sender->d_func()->connectedSignals[n] |= (1 << (signal_index - n * 8
+ * sizeof sender->d_func()->connectedSignals[0]));
+ }
+
return true;
}
@@ -3158,10 +3187,10 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal
}
#if defined(QT_NO_EXCEPTIONS)
- receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
#else
QT_TRY {
- receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
+ metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
} QT_CATCH(...) {
locker.relock();
@@ -3210,11 +3239,12 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal
*/
void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
{
- if (signal_index < 32
+ if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
&& !qt_signal_spy_callback_set.signal_begin_callback
&& !qt_signal_spy_callback_set.signal_end_callback) {
- uint signal_mask = 1 << signal_index;
- if ((sender->d_func()->connectedSignals & signal_mask) == 0)
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ if ((sender->d_func()->connectedSignals[n] & m) == 0)
// nothing connected to these signals, and no spy
return;
}
@@ -3227,11 +3257,12 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
void **argv)
{
int signal_index = m->methodOffset() + local_signal_index;
- if (signal_index < 32
+ if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
&& !qt_signal_spy_callback_set.signal_begin_callback
&& !qt_signal_spy_callback_set.signal_end_callback) {
- uint signal_mask = 1 << signal_index;
- if ((sender->d_func()->connectedSignals & signal_mask) == 0)
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ if ((sender->d_func()->connectedSignals[n] & m) == 0)
// nothing connected to these signals, and no spy
return;
}
@@ -3243,21 +3274,59 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
void QMetaObject::activate(QObject *sender, const QMetaObject *m,
int from_local_signal_index, int to_local_signal_index, void **argv)
{
+ Q_ASSERT(from_local_signal_index <= to_local_signal_index);
int offset = m->methodOffset();
int from_signal_index = offset + from_local_signal_index;
int to_signal_index = offset + to_local_signal_index;
- if (to_signal_index < 32
+
+ if (to_signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
&& !qt_signal_spy_callback_set.signal_begin_callback
&& !qt_signal_spy_callback_set.signal_end_callback) {
- uint signal_mask = (1 << (to_signal_index + 1)) - 1;
- signal_mask ^= (1 << from_signal_index) - 1;
- if ((sender->d_func()->connectedSignals & signal_mask) == 0)
+
+ uint n = (from_signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (from_signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ uint nt = (to_signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint mt = 1 << (to_signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ bool connected = false;
+ quint32 *connectedSignals = sender->d_func()->connectedSignals;
+ for (uint i = 0; !connected && i < (sizeof sender->d_func()->connectedSignals
+ / sizeof sender->d_func()->connectedSignals[0]); ++i) {
+ uint mask = 0;
+ if (i > n)
+ mask = ~0u;
+ else if (i == n)
+ mask = ~(m -1);
+ if (i > nt)
+ mask = 0;
+ else if (i == nt)
+ mask &= (mt << 1) - 1;
+ connected = connectedSignals[i] & mask;
+ }
+ if (!connected)
// nothing connected to these signals, and no spy
return;
}
activate(sender, from_signal_index, to_signal_index, argv);
}
+/*! \internal
+
+ Returns true if the signal with index \a signal_index from object \a sender is connected.
+ Signals with indices above a certain range are always considered connected (see connectedSignals
+ in QObjectPrivate). If a signal spy is installed, all signals are considered connected.
+*/
+bool QMetaObject::isConnected(QObject *sender, int signal_index) {
+ if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
+ && !qt_signal_spy_callback_set.signal_begin_callback
+ && !qt_signal_spy_callback_set.signal_end_callback) {
+ uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
+ uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
+ if ((sender->d_func()->connectedSignals[n] & m) == 0)
+ // nothing connected to these signals, and no spy
+ return false;
+ }
+ return true;
+}
/*****************************************************************************
Properties
@@ -3864,6 +3933,7 @@ void qDeleteInEventHandler(QObject *o)
delete o;
}
+
QT_END_NAMESPACE
#include "moc_qobject.cpp"
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 74a5904..a9f005b 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -110,6 +110,7 @@ public:
uint hasGuards : 1; //true iff there is one or more QPointer attached to this object
uint unused : 22;
int postedEvents;
+ QMetaObject *metaObject; // assert dynamic
};
@@ -380,6 +381,9 @@ inline QList<T> qFindChildren(const QObject *o, const QRegExp &re)
#endif // Q_MOC_RUN
+template <class T> inline const char * qobject_interface_iid()
+{ return 0; }
+
template <class T> inline T qobject_cast_helper(QObject *object, T)
{ return static_cast<T>(((T)0)->staticMetaObject.cast(object)); }
@@ -396,6 +400,8 @@ inline T qobject_cast(const QObject *object)
#ifndef Q_MOC_RUN
# define Q_DECLARE_INTERFACE(IFace, IId) \
+ template <> inline const char *qobject_interface_iid<IFace *>() \
+ { return IId; } \
template <> inline IFace *qobject_cast_helper<IFace *>(QObject *object, IFace *) \
{ return (IFace *)(object ? object->qt_metacast(IId) : 0); } \
template <> inline IFace *qobject_cast_helper<IFace *>(const QObject *object, IFace *) \
@@ -459,8 +465,13 @@ inline T qobject_cast(const QObject *object)
}
+template <class T> inline const char * qobject_interface_iid()
+{ return 0; }
+
#ifndef Q_MOC_RUN
# define Q_DECLARE_INTERFACE(IFace, IId) \
+ template <> inline const char *qobject_interface_iid<IFace *>() \
+ { return IId; } \
template <> inline IFace *qobject_cast<IFace *>(QObject *object) \
{ return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : 0)); } \
template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 07c397f..0b41c9a 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -60,6 +60,7 @@
#include "QtCore/qvector.h"
#include "QtCore/qreadwritelock.h"
#include "QtCore/qvariant.h"
+#include "private/qguard_p.h"
QT_BEGIN_NAMESPACE
@@ -85,6 +86,13 @@ inline QObjectData::~QObjectData() {}
enum { QObjectPrivateVersion = QT_VERSION };
+class QDeclarativeData
+{
+public:
+ virtual ~QDeclarativeData() {}
+ virtual void destroyed(QObject *) {}
+};
+
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
@@ -117,7 +125,7 @@ public:
// object currently activating the object
Sender *currentSender;
- QObject *currentChildBeingDeleted;
+ QDeclarativeData *declarativeData;
bool isSender(const QObject *receiver, const char *signal) const;
QObjectList receiverList(const char *signal) const;
@@ -140,7 +148,7 @@ public:
QList<QVariant> propertyValues;
};
ExtraData *extraData;
- mutable quint32 connectedSignals;
+ mutable quint32 connectedSignals[2];
QString objectName;
@@ -174,12 +182,37 @@ public:
static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch);
int *deleteWatch;
+ QGuard<QObject> *objectGuards;
static QObjectPrivate *get(QObject *o) {
return o->d_func();
}
};
+inline void q_guard_addGuard(QGuard<QObject> *g)
+{
+ QObjectPrivate *p = QObjectPrivate::get(g->o);
+ if (p->wasDeleted) {
+ qWarning("QGuard: cannot add guard to deleted object");
+ g->o = 0;
+ return;
+ }
+
+ g->next = p->objectGuards;
+ p->objectGuards = g;
+ g->prev = &p->objectGuards;
+ if (g->next)
+ g->next->prev = &g->next;
+}
+
+inline void q_guard_removeGuard(QGuard<QObject> *g)
+{
+ if (g->next) g->next->prev = g->prev;
+ *g->prev = g->next;
+ g->next = 0;
+ g->prev = 0;
+}
+
Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE);
@@ -220,6 +253,14 @@ private:
void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o);
+
+struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QMetaObject
+{
+ virtual ~QAbstractDynamicMetaObject() {}
+ virtual int metaCall(QMetaObject::Call, int _id, void **) { return _id; }
+ virtual int createProperty(const char *, const char *) { return -1; }
+};
+
QT_END_NAMESPACE
#endif // QOBJECT_P_H
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 9187765..1ae46d5 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -334,6 +334,9 @@ struct Q_CORE_EXPORT QMetaObject
static void activate(QObject *sender, int from_signal_index, int to_signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
static void activate(QObject *sender, const QMetaObject *, int from_local_signal_index, int to_local_signal_index, void **argv);
+
+ static bool isConnected(QObject *sender, int signal_index);
+
// internal guarded pointers
static void addGuard(QObject **ptr);
static void removeGuard(QObject **ptr);
@@ -428,6 +431,7 @@ struct Q_CORE_EXPORT QMetaObject
};
int static_metacall(Call, int, void **) const;
+ static int metacall(QObject *, Call, int, void **);
#ifdef QT3_SUPPORT
QT3_SUPPORT const char *superClassName() const;
@@ -439,6 +443,7 @@ struct Q_CORE_EXPORT QMetaObject
const uint *data;
const void *extradata;
} d;
+
};
struct QMetaObjectExtraData