diff options
author | Warwick Allison <warwick.allison@nokia.com> | 2009-08-02 23:41:38 (GMT) |
---|---|---|
committer | Warwick Allison <warwick.allison@nokia.com> | 2009-08-02 23:41:38 (GMT) |
commit | 98bb5c8cbdef20d060c45a399068580eacf93ae4 (patch) | |
tree | b16faf2c64bb76945b75c4000c234457e5261a6e | |
parent | aa9cf406d62004519ad54596e1c391f9a6439210 (diff) | |
parent | 5aed3db0a4084f470769ad4b965001f17b878c79 (diff) | |
download | Qt-98bb5c8cbdef20d060c45a399068580eacf93ae4.zip Qt-98bb5c8cbdef20d060c45a399068580eacf93ae4.tar.gz Qt-98bb5c8cbdef20d060c45a399068580eacf93ae4.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
56 files changed, 1328 insertions, 198 deletions
diff --git a/doc/src/examples/collidingmice-example.qdoc b/doc/src/examples/collidingmice-example.qdoc index 5b124f9..f627fbf 100644 --- a/doc/src/examples/collidingmice-example.qdoc +++ b/doc/src/examples/collidingmice-example.qdoc @@ -95,11 +95,11 @@ the global qrand() function which is a thread-safe version of the standard C++ rand() function. - Then we call the \l {QGraphicsItem::rotate()}{rotate()} function + Then we call the \l {QGraphicsItem::setRotation()}{setRotation()} function inherited from QGraphicsItem. Items live in their own local coordinate system. Their coordinates are usually centered around (0, 0), and this is also the center for all transformations. By - calling the item's \l {QGraphicsItem::rotate()}{rotate()} function + calling the item's \l {QGraphicsItem::setRotation()}{setRotation()} function we alter the direction in which the mouse will start moving. When the QGraphicsScene decides to advance the scene a frame it will call diff --git a/doc/src/properties.qdoc b/doc/src/properties.qdoc index 5490dd0..2d03e91 100644 --- a/doc/src/properties.qdoc +++ b/doc/src/properties.qdoc @@ -122,6 +122,17 @@ editable property for (checkable) buttons. Note that QItemDelegate gets and sets a widget's \c USER property. + \o The presence of the \c CONSTANT attibute indicates that the property + value is constant. For a given object instance, the READ method of a + constant property must return the same value every time it is called. This + constant value may be different for different instances of the object. A + constant property cannot have a WRTE method or a NOTIFY signal. + + \o The presence of the \c FINAL attribute indicates that the property + will not be overridden by a derived class. This can be used for performance + optimizations in some cases, but is not enforced by moc. Care must be taken + never to override a \c FINAL property. + \endlist The \c READ, \c WRITE, and \c RESET functions can be inherited. diff --git a/doc/src/snippets/code/doc_src_properties.qdoc b/doc/src/snippets/code/doc_src_properties.qdoc index 377cc9c..3c9109f 100644 --- a/doc/src/snippets/code/doc_src_properties.qdoc +++ b/doc/src/snippets/code/doc_src_properties.qdoc @@ -7,7 +7,9 @@ Q_PROPERTY(type name [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] - [USER bool]) + [USER bool] + [CONSTANT] + [FINAL]) //! [0] diff --git a/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp b/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp index 2ab15ee..89b4f33 100644 --- a/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp +++ b/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp @@ -13,9 +13,9 @@ info1.size(); // returns 56201 info1.symLinkTarget(); // returns "/opt/pretty++/bin/untabify" QFileInfo info2(info1.symLinkTarget()); -info1.isSymLink(); // returns false -info1.absoluteFilePath(); // returns "/opt/pretty++/bin/untabify" -info1.size(); // returns 56201 +info2.isSymLink(); // returns false +info2.absoluteFilePath(); // returns "/opt/pretty++/bin/untabify" +info2.size(); // returns 56201 #endif //! [0] diff --git a/examples/gestures/imageviewer/main.cpp b/examples/gestures/imageviewer/main.cpp index 6bda418..cd1928b 100644 --- a/examples/gestures/imageviewer/main.cpp +++ b/examples/gestures/imageviewer/main.cpp @@ -81,6 +81,9 @@ int main(int argc, char *argv[]) if (QApplication::arguments().size() > 1) w.openDirectory(QApplication::arguments().at(1)); + else + w.openDirectory(QFileDialog::getExistingDirectory(0, "Select image folder")); + return app.exec(); } diff --git a/examples/graphicsview/collidingmice/mouse.cpp b/examples/graphicsview/collidingmice/mouse.cpp index c6a67b1..4cc29dd 100644 --- a/examples/graphicsview/collidingmice/mouse.cpp +++ b/examples/graphicsview/collidingmice/mouse.cpp @@ -64,7 +64,7 @@ Mouse::Mouse() : angle(0), speed(0), mouseEyeDirection(0), color(qrand() % 256, qrand() % 256, qrand() % 256) { - rotate(qrand() % (360 * 16)); + setRotation(qrand() % (360 * 16)); } //! [0] @@ -195,7 +195,7 @@ void Mouse::advance(int step) qreal dx = ::sin(angle) * 10; mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; - rotate(dx); + setRotation(rotation() + dx); setPos(mapToParent(0, -(3 + sin(speed) * 3))); } //! [11] diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index ae468ef..19f00db 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -118,6 +118,8 @@ public: QSize minimumSizeHint() const; int qt_metacall(QMetaObject::Call, int isignal, void **argv); + void* qt_metacast(const char *clname); + inline QAxClientSite *clientSite() const { return axhost; @@ -478,7 +480,9 @@ bool axc_FilterProc(void *m) QAxWidget *ax = 0; QAxHostWidget *host = 0; while (!host && hwnd) { - host = qobject_cast<QAxHostWidget*>(QWidget::find(hwnd)); + QWidget *widget = QWidget::find(hwnd); + if (widget && widget->inherits("QAxHostWidget")) + host = qobject_cast<QAxHostWidget*>(widget); hwnd = ::GetParent(hwnd); } if (host) @@ -976,10 +980,34 @@ HRESULT WINAPI QAxClientSite::TransformCoords(POINTL* /*pPtlHimetric*/, POINTF* HRESULT WINAPI QAxClientSite::TranslateAccelerator(LPMSG lpMsg, DWORD /*grfModifiers*/) { - eventTranslated = false; if (lpMsg->message == WM_KEYDOWN && !lpMsg->wParam) return S_OK; + + bool ActiveQtDetected = false; + bool fromInProcServer = false; + LONG_PTR serverType = GetWindowLongPtr(lpMsg->hwnd, GWLP_USERDATA); + if (serverType == QAX_INPROC_SERVER) { + ActiveQtDetected = true; + fromInProcServer = true; + } else if (serverType == QAX_OUTPROC_SERVER) { + ActiveQtDetected = true; + fromInProcServer = false; + } + + eventTranslated = false; + if (!ActiveQtDetected || !fromInProcServer) { + // if the request is coming from an out-of-proc server or a non ActiveQt server, + // we send the message to the host window. This will make sure this key event + // comes to Qt for processing. SendMessage(host->winId(), lpMsg->message, lpMsg->wParam, lpMsg->lParam); + if (ActiveQtDetected && !fromInProcServer) { + // ActiveQt based servers will need further processing of the event + // (eg. <SPACE> key for a checkbox), so we return false. + return S_FALSE; + } + } + // ActiveQt based in-processes-servers will handle the event properly, so + // we dont need to send this key event to the host. return S_OK; } @@ -1617,6 +1645,14 @@ int QAxHostWidget::qt_metacall(QMetaObject::Call call, int isignal, void **argv) return -1; } +void* QAxHostWidget::qt_metacast(const char *clname) +{ + if (!clname) return 0; + if (!qstrcmp(clname,"QAxHostWidget")) + return static_cast<void*>(const_cast< QAxHostWidget*>(this)); + return QWidget::qt_metacast(clname); +} + QSize QAxHostWidget::sizeHint() const { return axhost ? axhost->sizeHint() : QWidget::sizeHint(); diff --git a/src/activeqt/control/qaxserverbase.cpp b/src/activeqt/control/qaxserverbase.cpp index d7a8e07..e482c60 100644 --- a/src/activeqt/control/qaxserverbase.cpp +++ b/src/activeqt/control/qaxserverbase.cpp @@ -3502,24 +3502,24 @@ Q_GUI_EXPORT int qt_translateKeyCode(int); HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) { if (pMsg->message != WM_KEYDOWN || !isWidget) - return S_FALSE; + return S_FALSE; DWORD dwKeyMod = 0; if (::GetKeyState(VK_SHIFT) < 0) - dwKeyMod |= 1; // KEYMOD_SHIFT + dwKeyMod |= 1; // KEYMOD_SHIFT if (::GetKeyState(VK_CONTROL) < 0) - dwKeyMod |= 2; // KEYMOD_CONTROL + dwKeyMod |= 2; // KEYMOD_CONTROL if (::GetKeyState(VK_MENU) < 0) - dwKeyMod |= 4; // KEYMOD_ALT + dwKeyMod |= 4; // KEYMOD_ALT switch (LOWORD(pMsg->wParam)) { case VK_TAB: - if (isUIActive) { - bool shift = ::GetKeyState(VK_SHIFT) < 0; - bool giveUp = true; + if (isUIActive) { + bool shift = ::GetKeyState(VK_SHIFT) < 0; + bool giveUp = true; QWidget *curFocus = qt.widget->focusWidget(); if (curFocus) { - if (shift) { + if (shift) { if (!curFocus->isWindow()) { QWidget *nextFocus = curFocus->nextInFocusChain(); QWidget *prevFocus = 0; @@ -3537,9 +3537,10 @@ HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) if (!topLevel) { giveUp = false; ((HackWidget*)curFocus)->focusNextPrevChild(false); + curFocus->window()->setAttribute(Qt::WA_KeyboardFocusChange); } } - } else { + } else { QWidget *nextFocus = curFocus; while (1) { nextFocus = nextFocus->nextInFocusChain(); @@ -3548,63 +3549,70 @@ HRESULT WINAPI QAxServerBase::TranslateAcceleratorW(MSG *pMsg) if (nextFocus->focusPolicy() & Qt::TabFocus) { giveUp = false; ((HackWidget*)curFocus)->focusNextPrevChild(true); + curFocus->window()->setAttribute(Qt::WA_KeyboardFocusChange); break; } } - } + } + } + if (giveUp) { + HWND hwnd = ::GetParent(m_hWnd); + ::SetFocus(hwnd); + } else { + return S_OK; } - if (giveUp) { - HWND hwnd = ::GetParent(m_hWnd); - ::SetFocus(hwnd); - } else { - return S_OK; - } - } - break; + } + break; case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN: - if (isUIActive) - return S_FALSE; - break; + if (isUIActive) + return S_FALSE; + break; default: - if (isUIActive && qt.widget->focusWidget()) { + if (isUIActive && qt.widget->focusWidget()) { int state = Qt::NoButton; - if (dwKeyMod & 1) - state |= Qt::ShiftModifier; - if (dwKeyMod & 2) - state |= Qt::ControlModifier; - if (dwKeyMod & 4) - state |= Qt::AltModifier; - - int key = pMsg->wParam; + if (dwKeyMod & 1) + state |= Qt::ShiftModifier; + if (dwKeyMod & 2) + state |= Qt::ControlModifier; + if (dwKeyMod & 4) + state |= Qt::AltModifier; + + int key = pMsg->wParam; if (!(key >= 'A' && key <= 'Z') && !(key >= '0' && key <= '9')) key = qt_translateKeyCode(pMsg->wParam); - QKeyEvent override(QEvent::ShortcutOverride, key, (Qt::KeyboardModifiers)state); - override.ignore(); - QApplication::sendEvent(qt.widget->focusWidget(), &override); - if (override.isAccepted()) - return S_FALSE; - } - break; + QKeyEvent override(QEvent::ShortcutOverride, key, (Qt::KeyboardModifiers)state); + override.ignore(); + QApplication::sendEvent(qt.widget->focusWidget(), &override); + if (override.isAccepted()) + return S_FALSE; + } + break; } if (!m_spClientSite) - return S_FALSE; + return S_FALSE; IOleControlSite *controlSite = 0; m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&controlSite); if (!controlSite) - return S_FALSE; - + return S_FALSE; + bool resetUserData = false; + // set server type in the user-data of the window. + LONG_PTR serverType = QAX_INPROC_SERVER; + if (qAxOutProcServer) + serverType = QAX_OUTPROC_SERVER; + LONG_PTR oldData = SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, serverType); HRESULT hres = controlSite->TranslateAcceleratorW(pMsg, dwKeyMod); - controlSite->Release(); + // reset the user-data for the window. + SetWindowLongPtr(pMsg->hwnd, GWLP_USERDATA, oldData); return hres; } diff --git a/src/activeqt/shared/qaxtypes.h b/src/activeqt/shared/qaxtypes.h index 4f647a3..e3c7138 100644 --- a/src/activeqt/shared/qaxtypes.h +++ b/src/activeqt/shared/qaxtypes.h @@ -89,6 +89,9 @@ extern QVariant VARIANTToQVariant(const VARIANT &arg, const QByteArray &typeName extern bool QVariantToVoidStar(const QVariant &var, void *data, const QByteArray &typeName, uint type = 0); extern void clearVARIANT(VARIANT *var); +#define QAX_INPROC_SERVER (0x51540001) +#define QAX_OUTPROC_SERVER (0x51540002) + QT_END_NAMESPACE #endif // QT_NO_WIN_ACTIVEQT diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 48e5ec1..fdd98c2 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -267,7 +267,7 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) localProgress); qSwap(currentValue, ret); q->updateCurrentValue(currentValue); - if ((connectedSignals & changedSignalMask) && currentValue != ret) { + if ((connectedSignals[0] & changedSignalMask) && currentValue != ret) { //the value has changed emit q->valueChanged(currentValue); } diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 7177293..3493784 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 += \ 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_p.h b/src/corelib/kernel/qcore_unix_p.h index dceb73a..69ebb05 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -323,6 +323,10 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) #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/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 9c67c70..5e016d3 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -69,9 +69,6 @@ #endif QT_BEGIN_NAMESPACE -#if !defined(_POSIX_MONOTONIC_CLOCK) -# define _POSIX_MONOTONIC_CLOCK -1 -#endif // internal timer info struct QTimerInfo { 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 6503ab0..ab91799 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -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 @@ -425,7 +429,22 @@ 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 = guardHash(); if (hash) { @@ -467,7 +486,7 @@ QMetaCallEvent::~QMetaCallEvent() */ int QMetaCallEvent::placeMetaCall(QObject *object) { - return object->qt_metacall(QMetaObject::InvokeMetaMethod, id_, args_); + return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, id_, args_); } /*! @@ -825,6 +844,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(); @@ -2849,10 +2876,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; } @@ -3140,10 +3173,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 try { - receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); + metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); } catch (...) { locker.relock(); @@ -3192,11 +3225,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; } @@ -3209,11 +3243,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; } @@ -3225,21 +3260,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 @@ -3846,6 +3919,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 1fb216b..9169a90 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -109,6 +109,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 }; @@ -379,6 +380,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)); } @@ -395,6 +399,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 *) \ @@ -458,8 +464,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..e908753 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,10 @@ public: // object currently activating the object Sender *currentSender; - QObject *currentChildBeingDeleted; + union { + QObject *currentChildBeingDeleted; + QDeclarativeData *declarativeData; + }; bool isSender(const QObject *receiver, const char *signal) const; QObjectList receiverList(const char *signal) const; @@ -140,7 +151,7 @@ public: QList<QVariant> propertyValues; }; ExtraData *extraData; - mutable quint32 connectedSignals; + mutable quint32 connectedSignals[2]; QString objectName; @@ -174,12 +185,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 +256,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 diff --git a/src/corelib/statemachine/qsignalevent.h b/src/corelib/statemachine/qsignalevent.h index c09c5a3..b7ca61f 100644 --- a/src/corelib/statemachine/qsignalevent.h +++ b/src/corelib/statemachine/qsignalevent.h @@ -58,16 +58,16 @@ QT_MODULE(Core) class Q_CORE_EXPORT QSignalEvent : public QEvent { public: - QSignalEvent(const QObject *sender, int signalIndex, + QSignalEvent(QObject *sender, int signalIndex, const QList<QVariant> &arguments); ~QSignalEvent(); - inline const QObject *sender() const { return m_sender; } + inline QObject *sender() const { return m_sender; } inline int signalIndex() const { return m_signalIndex; } inline QList<QVariant> arguments() const { return m_arguments; } private: - const QObject *m_sender; + QObject *m_sender; int m_signalIndex; QList<QVariant> m_arguments; }; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index a02480b..5aa5917 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -205,6 +205,7 @@ This is QStateMachinePrivate::QStateMachinePrivate() { state = NotRunning; + _startState = 0; processing = false; processingScheduled = false; stop = false; @@ -1146,6 +1147,20 @@ protected: } // namespace +QState *QStateMachinePrivate::startState() +{ + Q_Q(QStateMachine); + if (_startState == 0) + _startState = new StartState(q); + return _startState; +} + +void QStateMachinePrivate::removeStartState() +{ + delete _startState; + _startState = 0; +} + void QStateMachinePrivate::_q_start() { Q_Q(QStateMachine); @@ -1165,11 +1180,19 @@ void QStateMachinePrivate::_q_start() processingScheduled = true; // we call _q_process() below emit q->started(); - StartState *start = new StartState(rootState()); - QAbstractTransition *initialTransition = new InitialTransition(initial); - start->addTransition(initialTransition); - QList<QAbstractTransition*> transitions; - transitions.append(initialTransition); + QState *start = startState(); + Q_ASSERT(start != 0); + + QList<QAbstractTransition*> transitions = QStatePrivate::get(start)->transitions(); + + // If a transition has already been added, then we skip this step, as the + // initial transition in that case has been overridden. + if (transitions.isEmpty()) { + QAbstractTransition *initialTransition = new InitialTransition(initial); + start->addTransition(initialTransition); + transitions.append(initialTransition); + } + QEvent nullEvent(QEvent::None); executeTransitionContent(&nullEvent, transitions); QList<QAbstractState*> enteredStates = enterStates(&nullEvent, transitions); @@ -1177,7 +1200,7 @@ void QStateMachinePrivate::_q_start() applyProperties(transitions, QList<QAbstractState*>() << start, enteredStates); #endif - delete start; + removeStartState(); #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": initial configuration:" << configuration; @@ -1277,6 +1300,67 @@ void QStateMachinePrivate::scheduleProcess() QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); } +namespace { + +class GoToStateTransition : public QAbstractTransition +{ +public: + GoToStateTransition(QAbstractState *target) + : QAbstractTransition(QList<QAbstractState*>() << target) {} +protected: + void onTransition(QEvent *) { deleteLater(); } + bool eventTest(QEvent *) { return true; } +}; + +} // namespace + +/*! + \internal + + Causes this state machine to unconditionally transition to the given + \a targetState. + + Provides a backdoor for using the state machine "imperatively"; i.e. rather + than defining explicit transitions, you drive the machine's execution by + calling this function. It breaks the whole integrity of the + transition-driven model, but is provided for pragmatic reasons. +*/ +void QStateMachinePrivate::goToState(QAbstractState *targetState) +{ + if (!targetState) { + qWarning("QStateMachine::goToState(): cannot go to null state"); + return; + } + + if (configuration.contains(targetState)) + return; + + QState *sourceState = 0; + if (state == Running) { + QSet<QAbstractState*>::const_iterator it; + for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { + sourceState = qobject_cast<QState*>(*it); + if (sourceState != 0) + break; + } + } else { + sourceState = startState(); + } + + Q_ASSERT(sourceState != 0); + // Reuse previous GoToStateTransition in case of several calls to + // goToState() in a row. + GoToStateTransition *trans = qFindChild<GoToStateTransition*>(sourceState); + if (!trans) { + trans = new GoToStateTransition(targetState); + sourceState->addTransition(trans); + } else { + trans->setTargetState(targetState); + } + + scheduleProcess(); +} + void QStateMachinePrivate::registerTransitions(QAbstractState *state) { QState *group = qobject_cast<QState*>(state); @@ -1446,7 +1530,7 @@ void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transitio } #endif -void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int signalIndex, +void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalIndex, void **argv) { Q_ASSERT(connections[sender].at(signalIndex) != 0); @@ -2026,7 +2110,7 @@ QSignalEventGenerator::QSignalEventGenerator(QStateMachine *parent) Constructs a new QSignalEvent object with the given \a sender, \a signalIndex and \a arguments. */ -QSignalEvent::QSignalEvent(const QObject *sender, int signalIndex, +QSignalEvent::QSignalEvent(QObject *sender, int signalIndex, const QList<QVariant> &arguments) : QEvent(QEvent::Signal), m_sender(sender), m_signalIndex(signalIndex), m_arguments(arguments) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index cae21aa..387e42e 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -79,7 +79,7 @@ class QAbstractAnimation; #endif class QStateMachine; -class QStateMachinePrivate : public QStatePrivate +class Q_AUTOTEST_EXPORT QStateMachinePrivate : public QStatePrivate { Q_DECLARE_PUBLIC(QStateMachine) public: @@ -116,6 +116,9 @@ public: QState *rootState() const; + QState *startState(); + void removeStartState(); + void microstep(QEvent *event, const QList<QAbstractTransition*> &transitionList); bool isPreempted(const QAbstractState *s, const QSet<QAbstractTransition*> &transitions) const; QSet<QAbstractTransition*> selectTransitions(QEvent *event) const; @@ -138,6 +141,8 @@ public: static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other); static QList<QState*> properAncestors(const QAbstractState *s, const QState *upperBound); + void goToState(QAbstractState *targetState); + void registerTransitions(QAbstractState *state); void registerSignalTransition(QSignalTransition *transition); void unregisterSignalTransition(QSignalTransition *transition); @@ -147,7 +152,7 @@ public: #endif void unregisterTransition(QAbstractTransition *transition); void unregisterAllTransitions(); - void handleTransitionSignal(const QObject *sender, int signalIndex, + void handleTransitionSignal(QObject *sender, int signalIndex, void **args); void scheduleProcess(); @@ -162,6 +167,7 @@ public: #endif State state; + QState *_startState; bool processing; bool processingScheduled; bool stop; @@ -208,7 +214,11 @@ public: f_cloneEvent cloneEvent; }; - static Q_CORE_EXPORT const Handler *handler; + static +#ifndef QT_BUILD_INTERNAL // otherwise Q_AUTOTEST_EXPORT exports it all + Q_CORE_EXPORT +#endif + const Handler *handler; }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 0020d22..7221925 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -44,6 +44,7 @@ #include <QtCore/qatomic.h> #include <limits.h> +#include <new> QT_BEGIN_HEADER @@ -76,6 +77,12 @@ struct QContiguousCacheTypedData int start; int offset; uint sharable : 1; + // uint unused : 31; + + // total is 24 bytes (HP-UX aCC: 40 bytes) + // the next entry is already aligned to 8 bytes + // there will be an 8 byte gap here if T requires 16-byte alignment + // (such as long double on 64-bit platforms, __int128, __float128) T array[1]; }; diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 75d6ead..a047e6a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3535,7 +3535,13 @@ void QGraphicsItem::resetTransform() /*! \obsolete - Use setRotation() instead + Use + + \code + setRotation(rotation() + angle); + \endcode + + instead. Rotates the current item transformation \a angle degrees clockwise around its origin. To translate around an arbitrary point (x, y), you need to @@ -3555,7 +3561,13 @@ void QGraphicsItem::rotate(qreal angle) /*! \obsolete - Use setScale() instead + Use + + \code + setTransform(QTransform::fromScale(sx, sy), true); + \endcode + + instead. Scales the current item transformation by (\a sx, \a sy) around its origin. To scale from an arbitrary point (x, y), you need to combine @@ -3575,7 +3587,13 @@ void QGraphicsItem::scale(qreal sx, qreal sy) /*! \obsolete - Use setTransform() instead. + Use + + \code + setTransform(QTransform().shear(sh, sv), true); + \endcode + + instead. Shears the current item transformation by (\a sh, \a sv). @@ -3589,7 +3607,12 @@ void QGraphicsItem::shear(qreal sh, qreal sv) /*! \obsolete - Use setPos() or setTransformOriginPoint() instead. + Use setPos() or setTransformOriginPoint() instead. For identical + behavior, use + + \code + setTransform(QTransform::fromTranslate(dx, dy), true); + \endcode Translates the current item transformation by (\a dx, \a dy). @@ -6503,7 +6526,7 @@ void QGraphicsItem::prepareGeometryChange() // if someone is connected to the changed signal or the scene has no views. // Note that this has to be done *after* markDirty to ensure that // _q_processDirtyItems is called before _q_emitUpdated. - if ((scenePrivate->connectedSignals & scenePrivate->changedSignalMask) + if ((scenePrivate->connectedSignals[0] & scenePrivate->changedSignalMask) || scenePrivate->views.isEmpty()) { if (d_ptr->hasTranslateOnlySceneTransform()) { d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(), diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a846cf6..da4a347 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -344,7 +344,7 @@ void QGraphicsScenePrivate::_q_emitUpdated() // the optimization that items send updates directly to the views, but it // needs to happen in order to keep compatibility with the behavior from // Qt 4.4 and backward. - if (connectedSignals & changedSignalMask) { + if (connectedSignals[0] & changedSignalMask) { for (int i = 0; i < views.size(); ++i) { QGraphicsView *view = views.at(i); if (!view->d_func()->connectedToScene) { @@ -2899,7 +2899,7 @@ void QGraphicsScene::update(const QRectF &rect) // Check if anyone's connected; if not, we can send updates directly to // the views. Otherwise or if there are no views, use old behavior. - bool directUpdates = !(d->connectedSignals & d->changedSignalMask) && !d->views.isEmpty(); + bool directUpdates = !(d->connectedSignals[0] & d->changedSignalMask) && !d->views.isEmpty(); if (rect.isNull()) { d->updateAll = true; d->updatedRects.clear(); @@ -4477,7 +4477,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b if (removingItemFromScene) { // Note that this function can be called from the item's destructor, so // do NOT call any virtual functions on it within this block. - if ((connectedSignals & changedSignalMask) || views.isEmpty()) { + if ((connectedSignals[0] & changedSignalMask) || views.isEmpty()) { // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below // method of delivering updates. @@ -4623,7 +4623,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool // Process item. if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) { - const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask); + const bool useCompatUpdate = views.isEmpty() || (connectedSignals[0] & changedSignalMask); const QRectF itemBoundingRect = adjustedItemBoundingRect(item); if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) { diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 336ca79..aff715c 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -1226,9 +1226,12 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event) } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { //the Hide event will take care of he editors that are in fact complete dialogs if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { - if (editor->isAncestorOf(QApplication::focusWidget())) - return false; // don't worry about focus changes internally in the editor - + QWidget *w = QApplication::focusWidget(); + while (w) { // don't worry about focus changes internally in the editor + if (w == editor) + return false; + w = w->parentWidget(); + } #ifndef QT_NO_DRAGANDDROP // The window may lose focus during an drag operation. // i.e when dragging involves the taskbar on Windows. diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index bd8fdac..7ec2afe 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -674,9 +674,12 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event) } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { //the Hide event will take care of he editors that are in fact complete dialogs if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { - if (editor->isAncestorOf(QApplication::focusWidget())) - return false; // don't worry about focus changes internally in the editor - + QWidget *w = QApplication::focusWidget(); + while (w) { // don't worry about focus changes internally in the editor + if (w == editor) + return false; + w = w->parentWidget(); + } #ifndef QT_NO_DRAGANDDROP // The window may lose focus during an drag operation. // i.e when dragging involves the taskbar on Windows. diff --git a/src/gui/kernel/qaction.h b/src/gui/kernel/qaction.h index 133fab4..cb681c4 100644 --- a/src/gui/kernel/qaction.h +++ b/src/gui/kernel/qaction.h @@ -68,24 +68,24 @@ class Q_GUI_EXPORT QAction : public QObject Q_ENUMS(MenuRole) Q_ENUMS(Priority) - Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable) + Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable NOTIFY changed) Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled) - Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) - Q_PROPERTY(QIcon icon READ icon WRITE setIcon) - Q_PROPERTY(QString text READ text WRITE setText) - Q_PROPERTY(QString iconText READ iconText WRITE setIconText) - Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip) - Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip) - Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis) - Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY changed) + Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY changed) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY changed) + Q_PROPERTY(QString iconText READ iconText WRITE setIconText NOTIFY changed) + Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY changed) + Q_PROPERTY(QString statusTip READ statusTip WRITE setStatusTip NOTIFY changed) + Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis NOTIFY changed) + Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed) #ifndef QT_NO_SHORTCUT - Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) - Q_PROPERTY(Qt::ShortcutContext shortcutContext READ shortcutContext WRITE setShortcutContext) - Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat) + Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut NOTIFY changed) + Q_PROPERTY(Qt::ShortcutContext shortcutContext READ shortcutContext WRITE setShortcutContext NOTIFY changed) + Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat NOTIFY changed) #endif - Q_PROPERTY(bool visible READ isVisible WRITE setVisible) - Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole) - Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY changed) + Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole NOTIFY changed) + Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu NOTIFY changed) Q_PROPERTY(Priority priority READ priority WRITE setPriority) public: diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp index 0b7656f..de33f93 100644 --- a/src/gui/kernel/qformlayout.cpp +++ b/src/gui/kernel/qformlayout.cpp @@ -689,16 +689,12 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) // are split. maxLabelWidth = 0; if (!wrapAllRows) { - int maxFieldMinWidth = 0; //the maximum minimum size of the field for (int i = 0; i < rr; ++i) { const QFormLayoutItem *label = m_matrix(i, 0); const QFormLayoutItem *field = m_matrix(i, 1); - if (label && field && label->sideBySide) + if (label && (label->sizeHint.width() + (field ? field->minSize.width() : 0) <= width)) maxLabelWidth = qMax(maxLabelWidth, label->sizeHint.width()); - if (field) - maxFieldMinWidth = qMax(maxFieldMinWidth, field->minSize.width() + field->sbsHSpace); } - maxLabelWidth = qMin(maxLabelWidth, width - maxFieldMinWidth); } else { maxLabelWidth = width; } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 8b8a853..6ee229a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1375,6 +1375,12 @@ QWidget::~QWidget() // set all QPointers for this object to zero QObjectPrivate::clearGuards(this); + if(d->declarativeData) { + QDeclarativeData *dd = d->declarativeData; + d->declarativeData = 0; + dd->destroyed(this); + } + if (!d->children.isEmpty()) d->deleteChildren(); diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h index 872bcd5..eb0d749 100644 --- a/src/gui/text/qtextcontrol_p.h +++ b/src/gui/text/qtextcontrol_p.h @@ -83,7 +83,7 @@ class QAbstractScrollArea; class QEvent; class QTimerEvent; -class Q_AUTOTEST_EXPORT QTextControl : public QObject +class Q_GUI_EXPORT QTextControl : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QTextControl) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index a1009ac..8cddc76 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -209,7 +209,6 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) if (!dfbWindow) createWindow(); ::setGeometry(dfbWindow, oldRect, rect); - // ### do I need to release and get the surface again here? #endif break; case Offscreen: { @@ -227,7 +226,10 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) if (result != DFB_OK) DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); } - + if (engine) { + delete engine; + engine = 0; + } QWSWindowSurface::setGeometry(rect); } diff --git a/src/script/qscriptextqobject.cpp b/src/script/qscriptextqobject.cpp index 88fd007..3ea5963 100644 --- a/src/script/qscriptextqobject.cpp +++ b/src/script/qscriptextqobject.cpp @@ -736,7 +736,7 @@ static void callQtMethod(QScriptContextPrivate *context, QMetaMethod::MethodType meta->static_metacall(QMetaObject::CreateInstance, chosenIndex, params); } else { Q_ASSERT(thisQObject != 0); - thisQObject->qt_metacall(QMetaObject::InvokeMetaMethod, chosenIndex, params); + QMetaObject::metacall(thisQObject, QMetaObject::InvokeMetaMethod, chosenIndex, params); } if (scriptable) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 1dae828..ac4ca83 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -818,6 +818,8 @@ void filter_unprintable(char *str) } } +/*! \internal + */ int qt_asprintf(char **str, const char *format, ...) { static const int MAXSIZE = 1024*1024*2; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index b872dfd..e3ce2ec 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -56,6 +56,8 @@ enum PropertyFlags { EnumOrFlag = 0x00000008, StdCppSet = 0x00000100, // Override = 0x00000200, + Constant = 0x00000400, + Final = 0x00000800, Designable = 0x00001000, ResolveDesignable = 0x00002000, Scriptable = 0x00004000, @@ -68,6 +70,7 @@ enum PropertyFlags { ResolveUser = 0x00200000, Notify = 0x00400000 }; + enum MethodFlags { AccessPrivate = 0x00, AccessProtected = 0x01, @@ -202,10 +205,10 @@ void Generator::generateCode() QByteArray qualifiedClassNameIdentifier = cdef->qualified; qualifiedClassNameIdentifier.replace(':', '_'); - int index = 12; + int index = 13; fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData()); fprintf(out, "\n // content:\n"); - fprintf(out, " %4d, // revision\n", 2); + fprintf(out, " %4d, // revision\n", 3); fprintf(out, " %4d, // classname\n", strreg(cdef->qualified)); fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0); index += cdef->classInfoList.count() * 2; @@ -225,6 +228,9 @@ void Generator::generateCode() fprintf(out, " %4d, %4d, // constructors\n", isConstructible ? cdef->constructorList.count() : 0, isConstructible ? index : 0); + fprintf(out, " %4d, // flags\n", 0); + + // // Build classinfo array // @@ -379,7 +385,7 @@ void Generator::generateCode() if (isQt || !cdef->hasQObject) return; - fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return &staticMetaObject;\n}\n", + fprintf(out, "\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;\n}\n", cdef->qualified.constData()); // // Generate smart cast function @@ -597,6 +603,11 @@ void Generator::generateProperties() if (p.notifyId != -1) flags |= Notify; + if (p.constant) + flags |= Constant; + if (p.final) + flags |= Final; + fprintf(out, " %4d, %4d, ", strreg(p.name), strreg(p.type)); diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 0ba7d53..74b1a67 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -908,6 +908,15 @@ void Moc::parseProperty(ClassDef *def) propDef.name = lexem(); while (test(IDENTIFIER)) { QByteArray l = lexem(); + + if (l[0] == 'C' && l == "CONSTANT") { + propDef.constant = true; + continue; + } else if(l[0] == 'F' && l == "FINAL") { + propDef.final = true; + continue; + } + QByteArray v, v2; if (test(LPAREN)) { v = lexemUntil(RPAREN); @@ -963,6 +972,23 @@ void Moc::parseProperty(ClassDef *def) msg += " has no READ accessor function. The property will be invalid."; warning(msg.constData()); } + if (propDef.constant && !propDef.write.isNull()) { + QByteArray msg; + msg += "Property declaration "; + msg += propDef.name; + msg += " is both WRITEable and CONSTANT. CONSTANT will be ignored."; + propDef.constant = false; + warning(msg.constData()); + } + if (propDef.constant && !propDef.notify.isNull()) { + QByteArray msg; + msg += "Property declaration "; + msg += propDef.name; + msg += " is both NOTIFYable and CONSTANT. CONSTANT will be ignored."; + propDef.constant = false; + warning(msg.constData()); + } + if(!propDef.notify.isEmpty()) def->notifyableProperties++; diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 9fa9ac2..767f84e 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -115,9 +115,11 @@ struct FunctionDef struct PropertyDef { - PropertyDef():notifyId(-1), gspec(ValueSpec){} + PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec){} QByteArray name, type, read, write, reset, designable, scriptable, editable, stored, user, notify; int notifyId; + bool constant; + bool final; enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; Specification gspec; bool stdCppSet() const { diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp index 1cd84db..8019551 100644 --- a/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp +++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp @@ -125,7 +125,7 @@ QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, networkLoop.connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(error(QNetworkReply::NetworkError))); networkLoop.connect(reply, SIGNAL(finished()), SLOT(finished())); - if(networkLoop.exec()) + if(networkLoop.exec(QEventLoop::ExcludeUserInputEvents)) { const QString errorMessage(escape(reply->errorString())); diff --git a/tests/auto/qformlayout/tst_qformlayout.cpp b/tests/auto/qformlayout/tst_qformlayout.cpp index 74384a9..9806557 100644 --- a/tests/auto/qformlayout/tst_qformlayout.cpp +++ b/tests/auto/qformlayout/tst_qformlayout.cpp @@ -125,7 +125,6 @@ private slots: Qt::Orientations expandingDirections() const; */ - void fieldMinimumSize(); }; tst_QFormLayout::tst_QFormLayout() @@ -906,35 +905,6 @@ void tst_QFormLayout::layoutAlone() QTest::qWait(500); } - -void tst_QFormLayout::fieldMinimumSize() -{ - //check that the field with is bigger than its minimumSizeHint for any size of the widget - // even if the label with is not fixed - QWidget w; - QFormLayout layout; - layout.setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - w.setLayout(&layout); - QLabel label1("Here is a strange test case"); - label1.setWordWrap(true); - QLabel label2("Here is another label"); - label2.setWordWrap(true); - QLabel shortLabel("short"); - QLabel longLabel("Quite long label"); - layout.addRow(&label1, &shortLabel); - layout.addRow(&label2, &longLabel); - w.show(); - int width = w.size().width() + 9; - - do { - w.resize(width, w.size().height()); - layout.activate(); - QVERIFY(shortLabel.size().width() >= shortLabel.minimumSizeHint().width()); - QVERIFY(longLabel.size().width() >= longLabel.minimumSizeHint().width()); - width -= 3; - } while(width >= w.minimumSizeHint().width()); -} - QTEST_MAIN(tst_QFormLayout) #include "tst_qformlayout.moc" diff --git a/tests/auto/qguard/qguard.pro b/tests/auto/qguard/qguard.pro new file mode 100644 index 0000000..f249dde --- /dev/null +++ b/tests/auto/qguard/qguard.pro @@ -0,0 +1,2 @@ +load(qttest_p4) +SOURCES += tst_qguard.cpp diff --git a/tests/auto/qguard/tst_qguard.cpp b/tests/auto/qguard/tst_qguard.cpp new file mode 100644 index 0000000..96d1b60 --- /dev/null +++ b/tests/auto/qguard/tst_qguard.cpp @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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$ +** +****************************************************************************/ + +// NOTE: This is identical to the QPointer autotest + +#include <QtTest/QtTest> + +#include <QApplication> +#include <QDebug> +#include <QWidget> +#include <private/qguard_p.h> + +class tst_QGuard : public QObject +{ + Q_OBJECT +public: + tst_QGuard(); + ~tst_QGuard(); + + inline tst_QGuard *me() const + { return const_cast<tst_QGuard *>(this); } + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void constructors(); + void destructor(); + void assignment_operators(); + void equality_operators(); + void isNull(); + void dereference_operators(); + void disconnect(); + void castDuringDestruction(); + void data() const; + void dataSignature() const; +}; + +tst_QGuard::tst_QGuard() +{ } + +tst_QGuard::~tst_QGuard() +{ } + +void tst_QGuard::initTestCase() +{ } + +void tst_QGuard::cleanupTestCase() +{ } + +void tst_QGuard::init() +{ } + +void tst_QGuard::cleanup() +{ } + +void tst_QGuard::constructors() +{ + QGuard<QObject> p1; + QGuard<QObject> p2(this); + QGuard<QObject> p3(p2); + QCOMPARE(p1, QGuard<QObject>(0)); + QCOMPARE(p2, QGuard<QObject>(this)); + QCOMPARE(p3, QGuard<QObject>(this)); +} + +void tst_QGuard::destructor() +{ + QObject *object = new QObject; + QGuard<QObject> p = object; + QCOMPARE(p, QGuard<QObject>(object)); + delete object; + QCOMPARE(p, QGuard<QObject>(0)); +} + +void tst_QGuard::assignment_operators() +{ + QGuard<QObject> p1; + QGuard<QObject> p2; + + p1 = this; + p2 = p1; + + QCOMPARE(p1, QGuard<QObject>(this)); + QCOMPARE(p2, QGuard<QObject>(this)); + QCOMPARE(p1, QGuard<QObject>(p2)); + + p1 = 0; + p2 = p1; + QCOMPARE(p1, QGuard<QObject>(0)); + QCOMPARE(p2, QGuard<QObject>(0)); + QCOMPARE(p1, QGuard<QObject>(p2)); + + QObject *object = new QObject; + + p1 = object; + p2 = p1; + QCOMPARE(p1, QGuard<QObject>(object)); + QCOMPARE(p2, QGuard<QObject>(object)); + QCOMPARE(p1, QGuard<QObject>(p2)); + + delete object; + QCOMPARE(p1, QGuard<QObject>(0)); + QCOMPARE(p2, QGuard<QObject>(0)); + QCOMPARE(p1, QGuard<QObject>(p2)); +} + +void tst_QGuard::equality_operators() +{ + QGuard<QObject> p1; + QGuard<QObject> p2; + + QVERIFY(p1 == p2); + + QObject *object = 0; + QWidget *widget = 0; + + p1 = object; + QVERIFY(p1 == p2); + QVERIFY(p1 == object); + p2 = object; + QVERIFY(p2 == p1); + QVERIFY(p2 == object); + + p1 = this; + QVERIFY(p1 != p2); + p2 = p1; + QVERIFY(p1 == p2); + + // compare to zero + p1 = 0; + QVERIFY(p1 == 0); + QVERIFY(0 == p1); + QVERIFY(p2 != 0); + QVERIFY(0 != p2); + QVERIFY(p1 == object); + QVERIFY(object == p1); + QVERIFY(p2 != object); + QVERIFY(object != p2); + QVERIFY(p1 == widget); + QVERIFY(widget == p1); + QVERIFY(p2 != widget); + QVERIFY(widget != p2); +} + +void tst_QGuard::isNull() +{ + QGuard<QObject> p1; + QVERIFY(p1.isNull()); + p1 = this; + QVERIFY(!p1.isNull()); + p1 = 0; + QVERIFY(p1.isNull()); +} + +void tst_QGuard::dereference_operators() +{ + QGuard<tst_QGuard> p1 = this; + + QObject *object = p1->me(); + QVERIFY(object == this); + + QObject &ref = *p1; + QVERIFY(&ref == this); + + object = static_cast<QObject *>(p1); + QVERIFY(object == this); +} + +void tst_QGuard::disconnect() +{ + QGuard<QObject> p1 = new QObject; + QVERIFY(!p1.isNull()); + p1->disconnect(); + QVERIFY(!p1.isNull()); + delete static_cast<QObject *>(p1); + QVERIFY(p1.isNull()); +} + +class ChildObject : public QObject +{ + QGuard<QObject> guardedPointer; + +public: + ChildObject(QObject *parent) + : QObject(parent), guardedPointer(parent) + { } + ~ChildObject(); +}; + +ChildObject::~ChildObject() +{ + QCOMPARE(static_cast<QObject *>(guardedPointer), static_cast<QObject *>(0)); + QCOMPARE(qobject_cast<QObject *>(guardedPointer), static_cast<QObject *>(0)); +} + +class ChildWidget : public QWidget +{ + QGuard<QWidget> guardedPointer; + +public: + ChildWidget(QWidget *parent) + : QWidget(parent), guardedPointer(parent) + { } + ~ChildWidget(); +}; + +ChildWidget::~ChildWidget() +{ + QCOMPARE(static_cast<QWidget *>(guardedPointer), static_cast<QWidget *>(0)); + QCOMPARE(qobject_cast<QWidget *>(guardedPointer), static_cast<QWidget *>(0)); +} + +class DerivedChild; + +class DerivedParent : public QObject +{ + Q_OBJECT + + DerivedChild *derivedChild; + +public: + DerivedParent(); + ~DerivedParent(); +}; + +class DerivedChild : public QObject +{ + Q_OBJECT + + DerivedParent *parentPointer; + QGuard<DerivedParent> guardedParentPointer; + +public: + DerivedChild(DerivedParent *parent) + : QObject(parent), parentPointer(parent), guardedParentPointer(parent) + { } + ~DerivedChild(); +}; + +DerivedParent::DerivedParent() + : QObject() +{ + derivedChild = new DerivedChild(this); +} + +DerivedParent::~DerivedParent() +{ + delete derivedChild; +} + +DerivedChild::~DerivedChild() +{ + QCOMPARE(static_cast<DerivedParent *>(guardedParentPointer), parentPointer); + QCOMPARE(qobject_cast<DerivedParent *>(guardedParentPointer), parentPointer); +} + +void tst_QGuard::castDuringDestruction() +{ + { + QObject *parentObject = new QObject(); + (void) new ChildObject(parentObject); + delete parentObject; + } + + { + QWidget *parentWidget = new QWidget(); + (void) new ChildWidget(parentWidget); + delete parentWidget; + } + + { + delete new DerivedParent(); + } +} + +void tst_QGuard::data() const +{ + /* Check value of a default constructed object. */ + { + QGuard<QObject> p; + QCOMPARE(p.data(), static_cast<QObject *>(0)); + } + + /* Check value of a default constructed object. */ + { + QObject *const object = new QObject(); + QGuard<QObject> p(object); + QCOMPARE(p.data(), object); + } +} + +void tst_QGuard::dataSignature() const +{ + /* data() should be const. */ + { + const QGuard<QObject> p; + p.data(); + } + + /* The return type should be T. */ + { + const QGuard<QWidget> p; + /* If the types differs, the QCOMPARE will fail to instansiate. */ + QCOMPARE(p.data(), static_cast<QWidget *>(0)); + } +} + +QTEST_MAIN(tst_QGuard) +#include "tst_qguard.moc" diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index dea0ffb..ac2858c 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -108,6 +108,8 @@ class tst_QMetaObject : public QObject Q_PROPERTY(int value6 READ value6 NOTIFY value6Changed) Q_PROPERTY(MyStruct value7 READ value7 WRITE setVal7 NOTIFY value7Changed) Q_PROPERTY(int value8 READ value8 NOTIFY value8Changed) + Q_PROPERTY(int value9 READ value9 CONSTANT) + Q_PROPERTY(int value10 READ value10 FINAL) public: enum EnumType { EnumType1 }; @@ -137,6 +139,10 @@ public: int value8() const { return 1; } + int value9() const { return 1; } + + int value10() const { return 1; } + QList<QVariant> value4; QVariantList value5; @@ -159,6 +165,8 @@ private slots: void customPropertyType(); void checkScope(); void propertyNotify(); + void propertyConstant(); + void propertyFinal(); void stdSet(); void classInfo(); @@ -785,6 +793,32 @@ void tst_QMetaObject::propertyNotify() QCOMPARE(signal.signature(), (const char *)0); } +void tst_QMetaObject::propertyConstant() +{ + const QMetaObject *mo = metaObject(); + + QMetaProperty prop = mo->property(mo->indexOfProperty("value8")); + QVERIFY(prop.isValid()); + QVERIFY(!prop.isConstant()); + + prop = mo->property(mo->indexOfProperty("value9")); + QVERIFY(prop.isValid()); + QVERIFY(prop.isConstant()); +} + +void tst_QMetaObject::propertyFinal() +{ + const QMetaObject *mo = metaObject(); + + QMetaProperty prop = mo->property(mo->indexOfProperty("value10")); + QVERIFY(prop.isValid()); + QVERIFY(prop.isFinal()); + + prop = mo->property(mo->indexOfProperty("value9")); + QVERIFY(prop.isValid()); + QVERIFY(!prop.isFinal()); +} + class ClassInfoTestObjectA : public QObject { Q_OBJECT diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 4f25af6..3df83d7 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -118,6 +118,7 @@ private slots: void connectToSender(); void qobjectConstCast(); void uniqConnection(); + void interfaceIid(); protected: }; @@ -2887,5 +2888,15 @@ void tst_QObject::uniqConnection() delete r2; } +void tst_QObject::interfaceIid() +{ + QCOMPARE(QByteArray(qobject_interface_iid<Foo::Bleh *>()), + QByteArray(Bleh_iid)); + QCOMPARE(QByteArray(qobject_interface_iid<Foo::Bar *>()), + QByteArray("com.qtest.foobar")); + QCOMPARE(QByteArray(qobject_interface_iid<FooObject *>()), + QByteArray()); +} + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index d96006d..3c9ea4c9 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -72,6 +72,7 @@ private slots: void scopeChain(); void pushAndPopScope(); void getSetActivationObject(); + void inheritActivationAndThisObject(); void toString(); }; @@ -689,6 +690,35 @@ void tst_QScriptContext::getSetActivationObject() } } +static QScriptValue myEval(QScriptContext *ctx, QScriptEngine *eng) +{ + QString code = ctx->argument(0).toString(); + ctx->setActivationObject(ctx->parentContext()->activationObject()); + ctx->setThisObject(ctx->parentContext()->thisObject()); + return eng->evaluate(code); +} + +void tst_QScriptContext::inheritActivationAndThisObject() +{ + QScriptEngine eng; + eng.globalObject().setProperty("myEval", eng.newFunction(myEval)); + { + QScriptValue ret = eng.evaluate("var a = 123; myEval('a')"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } + { + QScriptValue ret = eng.evaluate("(function() { return myEval('this'); }).call(Number)"); + QVERIFY(ret.isFunction()); + QVERIFY(ret.equals(eng.globalObject().property("Number"))); + } + { + QScriptValue ret = eng.evaluate("(function(a) { return myEval('a'); })(123)"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 123); + } +} + static QScriptValue parentContextToString(QScriptContext *ctx, QScriptEngine *) { return ctx->parentContext()->toString(); diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 7f4d9f5..32812e2 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -192,6 +192,7 @@ private slots: // void overrideDefaultTargetAnimationWithSource(); void nestedStateMachines(); + void goToState(); }; tst_QStateMachine::tst_QStateMachine() @@ -3900,5 +3901,45 @@ void tst_QStateMachine::nestedStateMachines() QTRY_COMPARE(finishedSpy.count(), 1); } +void tst_QStateMachine::goToState() +{ + QStateMachine machine; + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); + machine.setInitialState(s1); + QSignalSpy startedSpy(&machine, SIGNAL(started())); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + + QStateMachinePrivate::get(&machine)->goToState(s2); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QStateMachinePrivate::get(&machine)->goToState(s2); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QStateMachinePrivate::get(&machine)->goToState(s1); + QStateMachinePrivate::get(&machine)->goToState(s2); + QStateMachinePrivate::get(&machine)->goToState(s1); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s2)); + + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + + // go to state in group + QState *s2_1 = new QState(s2); + s2->setInitialState(s2_1); + QStateMachinePrivate::get(&machine)->goToState(s2_1); + QCoreApplication::processEvents(); + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s2_1)); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp index 55b4ea7..9412f1c 100644 --- a/tools/assistant/lib/qhelpprojectdata.cpp +++ b/tools/assistant/lib/qhelpprojectdata.cpp @@ -45,6 +45,7 @@ #include <QtCore/QFileInfo> #include <QtCore/QStack> #include <QtCore/QMap> +#include <QtCore/QRegExp> #include <QtCore/QVariant> #include <QtXml/QXmlStreamReader> @@ -75,6 +76,8 @@ private: void readFiles(); void raiseUnknownTokenError(); void addMatchingFiles(const QString &pattern); + + QMap<QString, QStringList> dirEntriesCache; }; void QHelpProjectDataPrivate::raiseUnknownTokenError() @@ -265,14 +268,40 @@ void QHelpProjectDataPrivate::readFiles() // meaningful warning later. void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern) { + // The pattern matching is expensive, so we skip it if no + // wildcard symbols occur in the string. + if (!pattern.contains('?') && !pattern.contains('*') + && !pattern.contains('[') && !pattern.contains(']')) { + filterSectionList.last().addFile(pattern); + return; + } + QFileInfo fileInfo(rootPath + '/' + pattern); - const QStringList &matches = - fileInfo.dir().entryList(QStringList(fileInfo.fileName())); - for (QStringList::ConstIterator it = matches.constBegin(); - it != matches.constEnd(); - ++it) - filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it); - if (matches.empty()) + const QDir &dir = fileInfo.dir(); + const QString &path = dir.canonicalPath(); + + // QDir::entryList() is expensive, so we cache the results. + QMap<QString, QStringList>::ConstIterator it = dirEntriesCache.find(path); + const QStringList &entries = it != dirEntriesCache.constEnd() ? + it.value() : dir.entryList(QDir::Files); + if (it == dirEntriesCache.constEnd()) + dirEntriesCache.insert(path, entries); + + bool matchFound = false; +#ifdef Q_OS_WIN + Qt::CaseSensitivity cs = Qt::CaseInsensitive; +#else + Qt::CaseSensitivity cs = Qt::CaseSensitive; +#endif + QRegExp regExp(fileInfo.fileName(), cs, QRegExp::Wildcard); + foreach (const QString &file, entries) { + if (regExp.exactMatch(file)) { + matchFound = true; + filterSectionList.last(). + addFile(QFileInfo(pattern).dir().path() + '/' + file); + } + } + if (!matchFound) filterSectionList.last().addFile(pattern); } diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch Binary files differindex 99687ed..3e66bd9 100644 --- a/tools/assistant/tools/assistant/assistant.qch +++ b/tools/assistant/tools/assistant/assistant.qch diff --git a/tools/assistant/tools/assistant/doc/assistant.qhp b/tools/assistant/tools/assistant/doc/assistant.qhp index 7a26101..7ea4cdd 100644 --- a/tools/assistant/tools/assistant/doc/assistant.qhp +++ b/tools/assistant/tools/assistant/doc/assistant.qhp @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <QtHelpProject version="1.0"> <virtualFolder>assistant</virtualFolder> - <namespace>com.trolltech.com.assistantinternal_1.0.0</namespace> + <namespace>com.trolltech.com.assistantinternal-1.0.0</namespace> <filterSection> <files> <file>assistant.html</file> diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 6799db3..5422bf46 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -306,7 +306,7 @@ void HelpViewer::setSource(const QUrl &url) loadFinished = false; if (url.toString() == QLatin1String("help")) { load(QUrl(QLatin1String("qthelp://com.trolltech.com." - "assistantinternal_1.0.0/assistant/assistant.html"))); + "assistantinternal-1.0.0/assistant/assistant.html"))); } else { load(url); } @@ -425,7 +425,7 @@ void HelpViewer::setSource(const QUrl &url) if (help) { QTextBrowser::setSource(QUrl(QLatin1String("qthelp://com.trolltech.com." - "assistantinternal_1.0.0/assistant/assistant.html"))); + "assistantinternal-1.0.0/assistant/assistant.html"))); } else { QTextBrowser::setSource(url); setHtml(tr("<title>Error 404...</title><div align=\"center\"><br><br>" diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index 05355d9..a0a5a0d 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -306,7 +306,7 @@ int main(int argc, char *argv[]) } } - QLatin1String intern("com.trolltech.com.assistantinternal_"); + QLatin1String intern("com.trolltech.com.assistantinternal-"); foreach (const QString &doc, userDocs) { if (!callerDocs.contains(doc) && !doc.startsWith(intern)) user.unregisterDocumentation(doc); diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 7926020..0c1723c 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -274,7 +274,7 @@ bool MainWindow::initHelpDB() return false; bool assistantInternalDocRegistered = false; - QString intern(QLatin1String("com.trolltech.com.assistantinternal_")); + QString intern(QLatin1String("com.trolltech.com.assistantinternal-")); foreach (const QString &ns, m_helpEngine->registeredDocumentations()) { if (ns.startsWith(intern)) { intern = ns; diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 796d012..a6795cb 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -359,7 +359,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) const QChar quote = QLatin1Char('"'); const QChar newline = QLatin1Char('\n'); QTextStream in(&dev); - in.setCodec(cd.m_codecForSource.isEmpty() ? "UTF-8" : cd.m_codecForSource); + in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); bool error = false; // format of a .po file entry: @@ -555,7 +555,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) { bool ok = true; QTextStream out(&dev); - out.setCodec(cd.m_outputCodec.isEmpty() ? "UTF-8" : cd.m_outputCodec); + out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); bool first = true; if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) { |