diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-08-06 06:38:11 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-08-06 07:18:48 (GMT) |
commit | 55c4f15df0d482c7d3d6c889b9fc132ed0bdd12a (patch) | |
tree | 99c01d7a4e0941f415e9a48f51faac94787b6cb0 /src/corelib | |
parent | 57ceb11ecf95032418712a686418116cf2398e7a (diff) | |
parent | b008dfbd67176948f6fdf830dc99d23a538a6b9c (diff) | |
download | Qt-55c4f15df0d482c7d3d6c889b9fc132ed0bdd12a.zip Qt-55c4f15df0d482c7d3d6c889b9fc132ed0bdd12a.tar.gz Qt-55c4f15df0d482c7d3d6c889b9fc132ed0bdd12a.tar.bz2 |
Merge commit 'qt/master-stable'
Conflicts:
configure.exe
doc/src/classes/qnamespace.qdoc
examples/examples.pro
src/corelib/kernel/qcoreevent.cpp
src/corelib/kernel/qobject.cpp
src/gui/kernel/qapplication.cpp
src/gui/kernel/qstandardgestures.h
src/gui/kernel/qwidget.cpp
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 30 | ||||
-rw-r--r-- | src/corelib/animation/qabstractanimation_p.h | 3 | ||||
-rw-r--r-- | src/corelib/animation/qparallelanimationgroup.cpp | 3 | ||||
-rw-r--r-- | src/corelib/arch/qatomic_vxworks.h | 2 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 21 | ||||
-rw-r--r-- | src/corelib/kernel/qabstractitemmodel.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_unix.cpp | 73 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_unix_p.h | 34 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreevent.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreevent.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_glib.cpp | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qfunctions_vxworks.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qfunctions_vxworks.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 52 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 113 | ||||
-rw-r--r-- | src/corelib/tools/qbytedata_p.h | 12 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 76 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 1 |
19 files changed, 214 insertions, 225 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index ced86d2..1d274c9 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -177,17 +177,6 @@ QUnifiedTimer *QUnifiedTimer::instance() return inst; } -void QUnifiedTimer::updateRecentlyStartedAnimations() -{ - if (animationsToStart.isEmpty()) - return; - - animations += animationsToStart; - updateTimer(); //we make sure we start the timer there - - animationsToStart.clear(); -} - void QUnifiedTimer::timerEvent(QTimerEvent *event) { //this is simply the time we last received a tick @@ -195,15 +184,16 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) if (time.isValid()) lastTick = consistentTiming ? oldLastTick + timingInterval : time.elapsed(); - //we transfer the waiting animations into the "really running" state - updateRecentlyStartedAnimations(); if (event->timerId() == startStopAnimationTimer.timerId()) { startStopAnimationTimer.stop(); + //we transfer the waiting animations into the "really running" state + animations += animationsToStart; + animationsToStart.clear(); if (animations.isEmpty()) { animationTimer.stop(); time = QTime(); - } else { + } else if (!animationTimer.isActive()) { animationTimer.start(timingInterval, this); lastTick = 0; time.start(); @@ -219,27 +209,19 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) } } -void QUnifiedTimer::updateTimer() -{ - //we delay the call to start and stop for the animation timer so that if you - //stop and start animations in batch you don't stop/start the timer too often. - if (!startStopAnimationTimer.isActive()) - startStopAnimationTimer.start(0, this); // we delay the actual start of the animation -} - void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation) { if (animations.contains(animation) ||animationsToStart.contains(animation)) return; animationsToStart << animation; - updateTimer(); + startStopAnimationTimer.start(0, this); // we delay the check if we should start/stop the global timer } void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation) { animations.removeAll(animation); animationsToStart.removeAll(animation); - updateTimer(); + startStopAnimationTimer.start(0, this); // we delay the check if we should start/stop the global timer } diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 0d8402e..b281aa2 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -135,11 +135,8 @@ public: protected: void timerEvent(QTimerEvent *); - void updateTimer(); private: - void updateRecentlyStartedAnimations(); - QBasicTimer animationTimer, startStopAnimationTimer; QTime time; int lastTick; diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index 5e4b0d2..8aa04a4 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -214,7 +214,8 @@ void QParallelAnimationGroup::updateState(QAbstractAnimation::State oldState, d->connectUncontrolledAnimations(); for (int i = 0; i < d->animations.size(); ++i) { QAbstractAnimation *animation = d->animations.at(i); - animation->stop(); + if (oldState == Stopped) + animation->stop(); animation->setDirection(d->direction); animation->start(); } diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h index 573a44d..b441210 100644 --- a/src/corelib/arch/qatomic_vxworks.h +++ b/src/corelib/arch/qatomic_vxworks.h @@ -34,7 +34,7 @@ ** 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. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index dc3667b..86f0757 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -285,7 +285,7 @@ namespace QT_NAMESPACE {} # endif #endif -#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE) #error "You are building a 64-bit application, but using a 32-bit version of Qt. Check your build configuration." #endif @@ -317,11 +317,8 @@ namespace QT_NAMESPACE {} # if !defined(MAC_OS_X_VERSION_10_6) # define MAC_OS_X_VERSION_10_6 MAC_OS_X_VERSION_10_5 + 1 # endif -# if (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_6) -# warning "Support for this version of Mac OS X is still preliminary" -# endif # if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6) -# error "This version of Mac OS X is unsupported" +# warning "This version of Mac OS X is unsupported" # endif #endif @@ -1220,6 +1217,11 @@ class QDataStream; # else # define Q_OPENGL_EXPORT Q_DECL_IMPORT # endif +# if defined(QT_BUILD_MULTIMEDIA_LIB) +# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT +# else +# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT +# endif # if defined(QT_BUILD_OPENVG_LIB) # define Q_OPENVG_EXPORT Q_DECL_EXPORT # else @@ -1264,6 +1266,7 @@ class QDataStream; # define Q_SVG_EXPORT Q_DECL_IMPORT # define Q_CANVAS_EXPORT Q_DECL_IMPORT # define Q_OPENGL_EXPORT Q_DECL_IMPORT +# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT # define Q_OPENVG_EXPORT Q_DECL_IMPORT # define Q_XML_EXPORT Q_DECL_IMPORT # define Q_XMLPATTERNS_EXPORT Q_DECL_IMPORT @@ -1290,6 +1293,7 @@ class QDataStream; # define Q_NETWORK_EXPORT Q_DECL_EXPORT # define Q_SVG_EXPORT Q_DECL_EXPORT # define Q_OPENGL_EXPORT Q_DECL_EXPORT +# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT # define Q_OPENVG_EXPORT Q_DECL_EXPORT # define Q_XML_EXPORT Q_DECL_EXPORT # define Q_XMLPATTERNS_EXPORT Q_DECL_EXPORT @@ -1303,6 +1307,7 @@ class QDataStream; # define Q_NETWORK_EXPORT # define Q_SVG_EXPORT # define Q_OPENGL_EXPORT +# define Q_MULTIMEDIA_EXPORT # define Q_XML_EXPORT # define Q_XMLPATTERNS_EXPORT # define Q_SCRIPT_EXPORT @@ -2452,12 +2457,14 @@ Q_CORE_EXPORT int qt_exception2SymbianError(const std::exception& ex); #define QT_MODULE_DBUS 0x08000 #define QT_MODULE_SCRIPTTOOLS 0x10000 #define QT_MODULE_OPENVG 0x20000 +#define QT_MODULE_MULTIMEDIA 0x40000 /* Qt editions */ #define QT_EDITION_CONSOLE (QT_MODULE_CORE \ | QT_MODULE_NETWORK \ | QT_MODULE_SQL \ | QT_MODULE_SCRIPT \ + | QT_MODULE_MULTIMEDIA \ | QT_MODULE_XML \ | QT_MODULE_XMLPATTERNS \ | QT_MODULE_TEST \ @@ -2473,6 +2480,7 @@ Q_CORE_EXPORT int qt_exception2SymbianError(const std::exception& ex); | QT_MODULE_OPENGL \ | QT_MODULE_OPENVG \ | QT_MODULE_SQL \ + | QT_MODULE_MULTIMEDIA \ | QT_MODULE_XML \ | QT_MODULE_XMLPATTERNS \ | QT_MODULE_SCRIPT \ @@ -2524,6 +2532,9 @@ QT_LICENSED_MODULE(OpenVG) #if (QT_EDITION & QT_MODULE_SQL) QT_LICENSED_MODULE(Sql) #endif +#if (QT_EDITION & QT_MODULE_MULTIMEDIA) +QT_LICENSED_MODULE(Multimedia) +#endif #if (QT_EDITION & QT_MODULE_XML) QT_LICENSED_MODULE(Xml) #endif diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index bc95c60..5d5d4cc 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1884,6 +1884,8 @@ QSize QAbstractItemModel::span(const QModelIndex &) const } /*! + \since 4.6 + Sets the model's role names to \a roleNames. This function is provided to allow mapping of role identifiers to @@ -1900,6 +1902,8 @@ void QAbstractItemModel::setRoleNames(const QHash<int,QByteArray> &roleNames) } /*! + \since 4.6 + Returns the model's role names. \sa setRoleNames() diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index b57d385..efa9c6d 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -161,76 +161,3 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, } QT_END_NAMESPACE - -#ifdef Q_OS_LINUX -// Don't wait for libc to supply the calls we need -// Make syscalls directly - -# if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 -// glibc 2.4 has syscall(...) -# include <sys/syscall.h> -# include <asm/unistd.h> -# else -// no syscall(...) -static inline int syscall(...) { errno = ENOSYS; return -1;} -# endif - -# ifndef __NR_dup3 -# if defined(__i386__) -# define __NR_dup3 330 -# define __NR_pipe2 331 -# elif defined(__x86_64__) -# define __NR_dup3 292 -# define __NR_pipe2 293 -# elif defined(__ia64__) -# define __NR_dup3 1316 -# define __NR_pipe2 1317 -# else -// set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the pipe2/dup3 code to this platform" -# define __NR_dup3 -1 -# define __NR_pipe2 -1 -# endif -# endif - -# if !defined(__NR_socketcall) && !defined(__NR_accept4) -# if defined(__x86_64__) -# define __NR_accept4 288 -# elif defined(__ia64__) -// not assigned yet to IA-64 -# define __NR_accept4 -1 -# else -// set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the accept4 code to this platform" -# define __NR_accept4 -1 -# endif -# endif - -QT_BEGIN_NAMESPACE -namespace QtLibcSupplement { - int pipe2(int pipes[], int flags) - { - return syscall(__NR_pipe2, pipes, flags); - } - - int dup3(int oldfd, int newfd, int flags) - { - return syscall(__NR_dup3, oldfd, newfd, flags); - } - - int accept4(int s, sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags) - { -# if defined(__NR_socketcall) - // This platform uses socketcall() instead of raw syscalls - // the SYS_ACCEPT4 number is cross-platform: 18 - return syscall(__NR_socketcall, 18, &s); -# else - return syscall(__NR_accept4, s, addr, addrlen, flags); -# endif - - Q_UNUSED(addr); Q_UNUSED(addrlen); Q_UNUSED(flags); // they're actually used - } -} -QT_END_NAMESPACE -#endif // Q_OS_LINUX - diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index e301c92..9a6069d 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -73,32 +73,16 @@ struct sockaddr; -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 -// Linux supports thread-safe FD_CLOEXEC +#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 - -// add defines for the consts for Linux -# ifndef O_CLOEXEC -# define O_CLOEXEC 02000000 -# endif -# ifndef FD_DUPFD_CLOEXEC -# define F_DUPFD_CLOEXEC 1030 -# endif -# ifndef SOCK_CLOEXEC -# define SOCK_CLOEXEC O_CLOEXEC -# endif -# ifndef SOCK_NONBLOCK -# define SOCK_NONBLOCK O_NONBLOCK -# endif -# ifndef MSG_CMSG_CLOEXEC -# define MSG_CMSG_CLOEXEC 0x40000000 -# endif - QT_BEGIN_NAMESPACE namespace QtLibcSupplement { - Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); - Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags); - Q_CORE_EXPORT int pipe2(int pipes[], int flags); + inline int accept4(int, sockaddr *, QT_SOCKLEN_T *, int) + { errno = ENOSYS; return -1; } + inline int dup3(int, int, int) + { errno = ENOSYS; return -1; } + inline int pipe2(int [], int ) + { errno = ENOSYS; return -1; } } QT_END_NAMESPACE using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement); @@ -190,7 +174,7 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0) #endif register int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) // use pipe2 flags |= O_CLOEXEC; ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR @@ -246,7 +230,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) Q_ASSERT(flags == FD_CLOEXEC || flags == 0); register int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) // use dup3 if (flags & FD_CLOEXEC) { EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 3cb8fe6..72bad5f 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -272,7 +272,7 @@ QT_BEGIN_NAMESPACE \omitvalue CocoaRequestModal \omitvalue Signal \omitvalue SymbianDeferredFocusChanged - \omitvalue WinGesture + \omitvalue NativeGesture */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index c361fd5..42e3d24 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -276,7 +276,7 @@ public: TouchUpdate = 195, TouchEnd = 196, - WinGesture = 197, + NativeGesture = 197, // Internal for platform gesture support RequestSoftwareInputPanel = 199, CloseSoftwareInputPanel = 200, diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 7610631..2bbe560 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -263,6 +263,7 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context) (void) new (&timerSource->timerList) QTimerInfoList(); timerSource->processEventsFlags = QEventLoop::AllEvents; g_source_set_can_recurse(&timerSource->source, true); + g_source_set_priority(&timerSource->source, G_PRIORITY_DEFAULT_IDLE); g_source_attach(&timerSource->source, mainContext); } diff --git a/src/corelib/kernel/qfunctions_vxworks.cpp b/src/corelib/kernel/qfunctions_vxworks.cpp index 6d5e7cc..def8f4c 100644 --- a/src/corelib/kernel/qfunctions_vxworks.cpp +++ b/src/corelib/kernel/qfunctions_vxworks.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -34,7 +34,7 @@ ** 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. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/kernel/qfunctions_vxworks.h b/src/corelib/kernel/qfunctions_vxworks.h index cc98948..e31d495 100644 --- a/src/corelib/kernel/qfunctions_vxworks.h +++ b/src/corelib/kernel/qfunctions_vxworks.h @@ -34,7 +34,7 @@ ** 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. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 7f8d2e8..1d0b2c8 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1352,6 +1352,8 @@ int QMetaMethod::attributes() const } /*! + \since 4.6 + Returns this method's index. */ int QMetaMethod::methodIndex() const @@ -2078,6 +2080,8 @@ int QMetaProperty::userType() const } /*! + \since 4.6 + Returns this property's index. */ int QMetaProperty::propertyIndex() const diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 2630b63..e6947a0 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -123,8 +123,11 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } } +QObjectData::~QObjectData() {} +QDeclarativeData::~QDeclarativeData() {} + QObjectPrivate::QObjectPrivate(int version) - : threadData(0), currentSender(0), declarativeData(0), connectionLists(0), senders(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), declarativeData(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -145,7 +148,6 @@ QObjectPrivate::QObjectPrivate(int version) inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; - objectGuards = 0; metaObject = 0; hasGuards = false; } @@ -794,6 +796,8 @@ QObject::~QObject() QT_TRY { emit destroyed(this); + if (d->declarativeData) + d->declarativeData->destroyed(this); // ### TODO: Can this throw? } QT_CATCH(...) { // all the signal/slots connections are still in place - if we don't // quit now, we will crash pretty soon. @@ -892,14 +896,6 @@ 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(); @@ -1906,13 +1902,12 @@ void QObjectPrivate::deleteChildren() // don't use qDeleteAll as the destructor of the child might // delete siblings for (int i = 0; i < children.count(); ++i) { - QObject *child = children.at(i); + currentChildBeingDeleted = children.at(i); children[i] = 0; - if (child) - child->d_func()->parent = 0; - delete child; + delete currentChildBeingDeleted; } children.clear(); + currentChildBeingDeleted = 0; wasDeleted = reallyWasDeleted; } @@ -1923,14 +1918,20 @@ void QObjectPrivate::setParent_helper(QObject *o) return; if (parent) { QObjectPrivate *parentD = parent->d_func(); - const int index = parentD->children.indexOf(q); - if (parentD->wasDeleted) { - parentD->children[index] = 0; + if (parentD->wasDeleted && wasDeleted + && parentD->currentChildBeingDeleted == q) { + // don't do anything since QObjectPrivate::deleteChildren() already + // cleared our entry in parentD->children. } else { - parentD->children.removeAt(index); - if (sendChildEvents && parentD->receiveChildEvents) { - QChildEvent e(QEvent::ChildRemoved, q); - QCoreApplication::sendEvent(parent, &e); + 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); + } } } } @@ -3965,19 +3966,12 @@ QDebug operator<<(QDebug dbg, const QObject *o) { Synonym for QList<QObject *>. */ -#ifdef QT_JAMBI_BUILD -class QDPtrAccessor : public QObject { -public: - QObjectData *d() const { return d_ptr; } -}; -#endif - void qDeleteInEventHandler(QObject *o) { #ifdef QT_JAMBI_BUILD if (!o) return; - ((QDPtrAccessor *) o)->d()->inEventHandler = false; + QObjectPrivate::get(o)->inEventHandler = false; #endif delete o; } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 0b41c9a..e58ee6c 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -82,15 +82,13 @@ void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set; -inline QObjectData::~QObjectData() {} - enum { QObjectPrivateVersion = QT_VERSION }; -class QDeclarativeData +class Q_CORE_EXPORT QDeclarativeData { public: - virtual ~QDeclarativeData() {} - virtual void destroyed(QObject *) {} + virtual ~QDeclarativeData(); + virtual void destroyed(QObject *) = 0; }; class Q_CORE_EXPORT QObjectPrivate : public QObjectData @@ -98,47 +96,6 @@ class Q_CORE_EXPORT QObjectPrivate : public QObjectData Q_DECLARE_PUBLIC(QObject) public: - QObjectPrivate(int version = QObjectPrivateVersion); - virtual ~QObjectPrivate(); - -#ifdef QT3_SUPPORT - QList<QObject *> pendingChildInsertedEvents; - void sendPendingChildInsertedEvents(); - void removePendingChildInsertedEvents(QObject *child); -#else - // preserve binary compatibility with code compiled without Qt 3 support - QList<QObject *> unused; -#endif - - // id of the thread that owns the object - QThreadData *threadData; - void moveToThread_helper(); - void setThreadData_helper(QThreadData *currentData, QThreadData *targetData); - void _q_reregisterTimers(void *pointer); - - struct Sender - { - QObject *sender; - int signal; - int ref; - }; - // object currently activating the object - Sender *currentSender; - - QDeclarativeData *declarativeData; - - bool isSender(const QObject *receiver, const char *signal) const; - QObjectList receiverList(const char *signal) const; - QObjectList senderList() const; - - QList<QPointer<QObject> > eventFilters; - - void setParent_helper(QObject *); - - void deleteChildren(); - - static void clearGuards(QObject *); - struct ExtraData { #ifndef QT_NO_USERDATA @@ -147,12 +104,7 @@ public: QList<QByteArray> propertyNames; QList<QVariant> propertyValues; }; - ExtraData *extraData; - mutable quint32 connectedSignals[2]; - - QString objectName; - // Note: you must hold the signalSlotLock() before accessing the lists below or calling the functions struct Connection { QObject *sender; @@ -167,11 +119,34 @@ public: }; typedef QList<Connection *> ConnectionList; - QObjectConnectionListVector *connectionLists; + struct Sender + { + QObject *sender; + int signal; + int ref; + }; + + + QObjectPrivate(int version = QObjectPrivateVersion); + virtual ~QObjectPrivate(); + void deleteChildren(); + + void setParent_helper(QObject *); + void moveToThread_helper(); + void setThreadData_helper(QThreadData *currentData, QThreadData *targetData); + void _q_reregisterTimers(void *pointer); + + bool isSender(const QObject *receiver, const char *signal) const; + QObjectList receiverList(const char *signal) const; + QObjectList senderList() const; + void addConnection(int signal, Connection *c); void cleanConnectionLists(); - Connection *senders; //linked list; +#ifdef QT3_SUPPORT + void sendPendingChildInsertedEvents(); + void removePendingChildInsertedEvents(QObject *child); +#endif static Sender *setCurrentSender(QObject *receiver, Sender *sender); @@ -180,13 +155,39 @@ public: Sender *previousSender); static int *setDeleteWatch(QObjectPrivate *d, int *newWatch); static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch); - - int *deleteWatch; - QGuard<QObject> *objectGuards; + static void clearGuards(QObject *); static QObjectPrivate *get(QObject *o) { return o->d_func(); } + +public: + QString objectName; + ExtraData *extraData; // extra data set by the user + QThreadData *threadData; // id of the thread that owns the object + + QObjectConnectionListVector *connectionLists; + + Connection *senders; // linked list of connections connected to this object + Sender *currentSender; // object currently activating the object + mutable quint32 connectedSignals[2]; // 64-bit, so doesn't cause padding on 64-bit platforms + +#ifdef QT3_SUPPORT + QList<QObject *> pendingChildInsertedEvents; +#else + // preserve binary compatibility with code compiled without Qt 3 support + // ### why? + QList<QObject *> unused; +#endif + + QList<QPointer<QObject> > eventFilters; + QObject *currentChildBeingDeleted; + + // these objects are all used to indicate that a QObject was deleted + // plus QPointer, which keeps a separate list + QDeclarativeData *declarativeData; + QGuard<QObject> *objectGuards; + int *deleteWatch; }; inline void q_guard_addGuard(QGuard<QObject> *g) diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/tools/qbytedata_p.h index cc10ea2..f3724f6 100644 --- a/src/corelib/tools/qbytedata_p.h +++ b/src/corelib/tools/qbytedata_p.h @@ -42,8 +42,18 @@ #ifndef QBYTEDATA_H #define QBYTEDATA_H -#include <qbytearray.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 <qbytearray.h> QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 8a63d64..f7b014e 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -133,7 +133,7 @@ To access the pointer that QWeakPointer is tracking, you must first create a QSharedPointer object and verify if the pointer - is null or not. + is null or not. See QWeakPointer::toStrongRef() for more information. \sa QSharedPointer, QScopedPointer */ @@ -215,6 +215,8 @@ If \tt T is a derived type of the template parameter of this class, QSharedPointer will perform an automatic cast. Otherwise, you will get a compiler error. + + \sa QWeakPointer::toStrongRef() */ /*! @@ -367,6 +369,8 @@ Returns a weak reference object that shares the pointer referenced by this object. + + \sa QWeakPointer::QWeakPointer(const QSharedPointer<T> &) */ /*! @@ -483,10 +487,78 @@ */ /*! + \fn T *QWeakPointer::data() const + \since 4.6 + + Returns the value of the pointer being tracked by this QWeakPointer, + \b without ensuring that it cannot get deleted. To have that guarantee, + use toStrongRef(), which returns a QSharedPointer object. If this + function can determine that the pointer has already been deleted, it + returns 0. + + It is ok to obtain the value of the pointer and using that value itself, + like for example in debugging statements: + + \code + qDebug("Tracking %p", weakref.data()); + \endcode + + However, dereferencing the pointer is only allowed if you can guarantee + by external means that the pointer does not get deleted. For example, + if you can be certain that no other thread can delete it, nor the + functions that you may call. + + If that is the case, then the following code is valid: + + \code + // this pointer cannot be used in another thread + // so other threads cannot delete it + QWeakPointer<int> weakref = obtainReference(); + + Object *obj = weakref.data(); + if (obj) { + // if the pointer wasn't deleted yet, we know it can't get + // deleted by our own code here nor the functions we call + otherFunction(obj); + } + \endcode + + Use this function with care. + + \sa isNull(), toStrongRef() +*/ + +/*! \fn QSharedPointer<T> QWeakPointer::toStrongRef() const Promotes this weak reference to a strong one and returns a - QSharedPointer object holding that reference. + QSharedPointer object holding that reference. When promoting to + QSharedPointer, this function verifies if the object has been deleted + already or not. If it hasn't, this function increases the reference + count to the shared object, thus ensuring that it will not get + deleted. + + Since this function can fail to obtain a valid strong reference to the + shared object, you should always verify if the conversion succeeded, + by calling QSharedPointer::isNull() on the returned object. + + For example, the following code promotes a QWeakPointer that was held + to a strong reference and, if it succeeded, it prints the value of the + integer that was held: + + \code + QWeakPointer<int> weakref; + + // ... + + QSharedPointer<int> strong = weakref.toStrongRef(); + if (strong) + qDebug() << "The value is:" << *strong; + else + qDebug() << "The value has already been deleted"; + \endcode + + \sa QSharedPointer::QSharedPointer(const QWeakPointer<T> &) */ /*! diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 9a5532c..25373b3 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -504,6 +504,7 @@ public: inline operator bool() const { return isNull() ? 0 : &QWeakPointer::value; } #endif inline bool operator !() const { return isNull(); } + inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; } inline QWeakPointer() : d(0), value(0) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } |