diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2009-12-02 19:27:48 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2009-12-02 19:27:48 (GMT) |
commit | 204fc5ed9642a3754dfefe7d4b1a5374615726a4 (patch) | |
tree | 65465f39338fb4d00c1c86be65edc372ab990795 /src | |
parent | 2eb96bf5b68cbdcc1ebd2616b0b9e5f0f77eb257 (diff) | |
parent | f29f1bb287c6b39bd1270802d1579f1c1d53f905 (diff) | |
download | Qt-204fc5ed9642a3754dfefe7d4b1a5374615726a4.zip Qt-204fc5ed9642a3754dfefe7d4b1a5374615726a4.tar.gz Qt-204fc5ed9642a3754dfefe7d4b1a5374615726a4.tar.bz2 |
Merge branch '4.6'
Conflicts:
src/corelib/global/qglobal.h
src/gui/dialogs/qfiledialog_win.cpp
src/plugins/qpluginbase.pri
src/qbase.pri
tests/auto/selftests/expected_cmptest.txt
tests/auto/selftests/expected_crashes_3.txt
tests/auto/selftests/expected_longstring.txt
tests/auto/selftests/expected_maxwarnings.txt
tests/auto/selftests/expected_skip.txt
tools/assistant/tools/assistant/doc/assistant.qdocconf
tools/qdoc3/test/assistant.qdocconf
tools/qdoc3/test/designer.qdocconf
tools/qdoc3/test/linguist.qdocconf
tools/qdoc3/test/qmake.qdocconf
tools/qdoc3/test/qt-build-docs.qdocconf
tools/qdoc3/test/qt.qdocconf
Diffstat (limited to 'src')
98 files changed, 1309 insertions, 895 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index f3ec8e1..bfb03ab 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -975,7 +975,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) face->glyphs_substituted = false; face->buffer = 0; - HB_Error error; + HB_Error error = HB_Err_Ok; HB_Stream stream; HB_Stream gdefStream; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri index 28328e7..a6fb2f8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri @@ -39,10 +39,12 @@ win32-* { contains(JAVASCRIPTCORE_JIT,yes) { DEFINES+=ENABLE_JIT=1 DEFINES+=ENABLE_YARR_JIT=1 + DEFINES+=ENABLE_YARR=1 } contains(JAVASCRIPTCORE_JIT,no) { DEFINES+=ENABLE_JIT=0 DEFINES+=ENABLE_YARR_JIT=0 + DEFINES+=ENABLE_YARR=0 } # In debug mode JIT disabled until crash fixed diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h index 56659a8..c03e8a7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h @@ -155,7 +155,7 @@ namespace WTF { typedef IntegralConstant<bool, true> true_type; typedef IntegralConstant<bool, false> false_type; -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, // but for some unexplained reason it doesn't work on built-in types. template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ }; diff --git a/src/3rdparty/javascriptcore/WebKit.pri b/src/3rdparty/javascriptcore/WebKit.pri index 8291f30..16f89bf 100644 --- a/src/3rdparty/javascriptcore/WebKit.pri +++ b/src/3rdparty/javascriptcore/WebKit.pri @@ -11,7 +11,7 @@ isEmpty(OUTPUT_DIR) { DEFINES += BUILDING_QT__=1 building-libs { - win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 + win32-msvc*|win32-icc: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 } else { CONFIG(QTDIR_build) { QT += webkit diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 2059fbe..b6f53ae 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -50,6 +50,8 @@ MMF::VideoPlayer::VideoPlayer() , m_window(0) , m_totalTime(0) , m_pendingChanges(false) + , m_dsaActive(false) + , m_dsaWasActive(false) { construct(); } @@ -61,6 +63,7 @@ MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player) , m_window(0) , m_totalTime(0) , m_pendingChanges(false) + , m_dsaActive(false) { construct(); } @@ -86,6 +89,9 @@ void MMF::VideoPlayer::construct() )) ); + // CVideoPlayerUtility::NewL starts DSA + m_dsaActive = true; + if (KErrNone != err) changeState(ErrorState); @@ -315,8 +321,7 @@ void MMF::VideoPlayer::getVideoWindow() m_videoOutput->dump(); initVideoOutput(); - m_window = m_videoOutput->videoWindow(); - updateVideoRect(); + videoWindowChanged(); } else // Top-level window m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); @@ -349,6 +354,18 @@ void MMF::VideoPlayer::initVideoOutput() Q_ASSERT(connected); connected = connect( + m_videoOutput, SIGNAL(beginVideoWindowNativePaint()), + this, SLOT(suspendDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(endVideoWindowNativePaint()), + this, SLOT(resumeDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( m_videoOutput, SIGNAL(aspectRatioChanged()), this, SLOT(aspectRatioChanged()) ); @@ -370,12 +387,48 @@ void MMF::VideoPlayer::videoWindowChanged() TRACE_ENTRY("state %d", state()); m_window = m_videoOutput->videoWindow(); - updateVideoRect(); TRACE_EXIT_0(); } +void MMF::VideoPlayer::suspendDirectScreenAccess() +{ + m_dsaWasActive = stopDirectScreenAccess(); +} + +void MMF::VideoPlayer::resumeDirectScreenAccess() +{ + if(m_dsaWasActive) { + startDirectScreenAccess(); + m_dsaWasActive = false; + } +} + +void MMF::VideoPlayer::startDirectScreenAccess() +{ + if(!m_dsaActive) { + TRAPD(err, m_player->StartDirectScreenAccessL()); + if(KErrNone == err) + m_dsaActive = true; + else + setError(NormalError); + } +} + +bool MMF::VideoPlayer::stopDirectScreenAccess() +{ + const bool dsaWasActive = m_dsaActive; + if(m_dsaActive) { + TRAPD(err, m_player->StopDirectScreenAccessL()); + if(KErrNone == err) + m_dsaActive = false; + else + setError(NormalError); + } + return dsaWasActive; +} + // Helper function for aspect ratio / scale mode handling QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) { @@ -393,7 +446,18 @@ QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) void MMF::VideoPlayer::updateVideoRect() { QRect videoRect; - const QRect windowRect = m_videoOutput->videoWindowRect(); + QRect windowRect = m_videoOutput->videoWindowRect(); + + // Clip to physical window size + // This is due to a defect in the layout when running on S60 3.2, which + // results in the rectangle of the video widget extending outside the + // screen in certain circumstances. These include the initial startup + // of the mediaplayer demo in portrait mode. When this rectangle is + // passed to the CVideoPlayerUtility, no video is rendered. + const TSize screenSize = m_screenDevice.SizeInPixels(); + const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight); + windowRect = windowRect.intersected(screenRect); + const QSize windowSize = windowRect.size(); // Calculate size of smallest rect which contains video frame size @@ -553,6 +617,7 @@ void MMF::VideoPlayer::applyVideoWindowChange() TRACE("SetDisplayWindowL err %d", err); setError(NormalError); } else { + m_dsaActive = true; TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (2) err %d", err); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index 599bb88..abb1da8 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -72,6 +72,8 @@ public Q_SLOTS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); + void suspendDirectScreenAccess(); + void resumeDirectScreenAccess(); private: void construct(); @@ -89,6 +91,9 @@ private: void applyPendingChanges(); void applyVideoWindowChange(); + void startDirectScreenAccess(); + bool stopDirectScreenAccess(); + // AbstractMediaPlayer virtual int numberOfMetaDataEntries() const; virtual QPair<QString, QString> metaDataEntry(int index) const; @@ -111,6 +116,8 @@ private: qint64 m_totalTime; bool m_pendingChanges; + bool m_dsaActive; + bool m_dsaWasActive; }; diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp index 2efebdb..edad537 100644 --- a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp +++ b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp @@ -46,7 +46,7 @@ QList<QByteArray> QAnnotatorWidget::annotation(const QObject& object) stream << "widget (Symbian): "; stream << "activated " << extra->activated << ' '; - stream << "disableBlit " << extra->disableBlit << ' '; + stream << "nativePaintMode " << extra->nativePaintMode << ' '; stream.flush(); result.append(array); diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp index ddf30de..119dcb1 100644 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ b/src/3rdparty/phonon/mmf/videooutput.cpp @@ -34,6 +34,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <coecntrl.h> +#include <coemain.h> // for CCoeEnv + QT_BEGIN_NAMESPACE using namespace Phonon; @@ -72,12 +74,8 @@ MMF::VideoOutput::VideoOutput setAttribute(Qt::WA_NoSystemBackground, true); setAutoFillBackground(false); - // Causes QSymbianControl::Draw not to BitBlt this widget's region of the - // backing store. Since the backing store is (by default) a 16MU bitmap, - // blitting it results in this widget's screen region in the final - // framebuffer having opaque alpha values. This in turn causes the video - // to be invisible when running on the target device. - qt_widget_private(this)->extraData()->disableBlit = true; + qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill; + qt_widget_private(this)->extraData()->receiveNativePaintEvents = true; getVideoWindowRect(); registerForAncestorMoved(); @@ -288,5 +286,18 @@ void MMF::VideoOutput::dump() const #endif } +void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/) +{ + emit beginVideoWindowNativePaint(); +} + +void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/) +{ + // Ensure that draw ops are executed into the WSERV output framebuffer + CCoeEnv::Static()->WsSession().Flush(); + + emit endVideoWindowNativePaint(); +} + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h index 6dfe69d..2788401 100644 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ b/src/3rdparty/phonon/mmf/videooutput.h @@ -63,10 +63,16 @@ public: // Debugging output void dump() const; +public Q_SLOTS: + void beginNativePaintEvent(const QRect& /*controlRect*/); + void endNativePaintEvent(const QRect& /*controlRect*/); + Q_SIGNALS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); + void beginVideoWindowNativePaint(); + void endVideoWindowNativePaint(); protected: // Override QWidget functions diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog index 26dbaf7..1e89d1e 100644 --- a/src/3rdparty/webkit/ChangeLog +++ b/src/3rdparty/webkit/ChangeLog @@ -1,3 +1,13 @@ +2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with win32-icc + + Include os-win32 for stdint.h since MS does not ship that in their PSDK. + + * WebKit.pri: + 2009-10-30 Adam Barth <abarth@webkit.org> Reviewed by Mark Rowe. diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 382a8c7..d7d2d57 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,39 @@ +2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with win32-icc + + The Intel compiler does not support the __has_trivial_constructor type + trait. The Intel Compiler can report itself as _MSC_VER >= 1400. The + reason for that is that the Intel Compiler depends on the Microsoft + Platform SDK, and in order to try to be "fully" MS compatible it will + "pretend" to be the same MS compiler as was shipped with the MS PSDK. + (Thus, compiling with win32-icc with VC8 SDK will make the source code + "think" the compiler at hand supports this type trait). + + * wtf/TypeTraits.h: + +2009-11-28 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + Apply workaround for the limitation of VirtualFree with MEM_RELEASE to all ports running on Windows + https://bugs.webkit.org/show_bug.cgi?id=31943 + + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + +2009-11-18 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Fix the clobber list of cacheFlush for ARM and Thumb2 on Linux + https://bugs.webkit.org/show_bug.cgi?id=31631 + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + 2009-11-23 Laszlo Gombos <laszlo.1.gombos@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h index 5c43eeb..9ca62c8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h @@ -203,7 +203,7 @@ public: "pop {r7}\n" : : "r" (code), "r" (reinterpret_cast<char*>(code) + size) - : "r0", "r1"); + : "r0", "r1", "r2"); } #elif PLATFORM(SYMBIAN) static void cacheFlush(void* code, size_t size) @@ -224,7 +224,7 @@ public: "pop {r7}\n" : : "r" (code), "r" (reinterpret_cast<char*>(code) + size) - : "r0", "r1"); + : "r0", "r1", "r2"); } #else #error "The cacheFlush support is missing on this platform." diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h index ea09f54..a114ae0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h @@ -153,7 +153,7 @@ namespace JSC { ASSERT(0 == (size % MarkStack::pageSize())); if (size == m_allocated) return; -#if PLATFORM(WIN) || PLATFORM(SYMBIAN) +#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN) // We cannot release a part of a region with VirtualFree. To get around this, // we'll release the entire region and reallocate the size that we want. releaseStack(m_data, m_allocated); diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h index 6ce6a3e..9e75e7a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h @@ -155,7 +155,7 @@ namespace WTF { typedef IntegralConstant<bool, true> true_type; typedef IntegralConstant<bool, false> false_type; -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, // but for some unexplained reason it doesn't work on built-in types. template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ }; diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 5818e83..62acbdf 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - efa69b6181ce5c045097351cdcf6c158da3f4888 + 9de63cde0ac8aa08e207d4ffce2846df1a44a364 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 9644470..4f6146f 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,44 @@ +2009-11-23 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Wrong runtime instance objects of wrapped QObjects may be used if + the wrapped object died before the gc removed the instance. + + https://bugs.webkit.org/show_bug.cgi?id=31681 + + Before using a cached instance, verify that its wrapped QObject is + still alive. + + * bridge/qt/qt_instance.cpp: + (JSC::Bindings::QtInstance::getQtInstance): + * bridge/qt/qt_instance.h: + (JSC::Bindings::QtInstance::hashKey): + +2009-11-25 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix crash of QtWebKit on any page with Flash when compiled with MinGW. + + Fix inline assembly, don't dereference the function pointer twice. + + * plugins/win/PluginViewWin.cpp: + (WebCore::PluginView::hookedBeginPaint): + (WebCore::PluginView::hookedEndPaint): + +2009-11-22 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Adam Barth. + + [Qt] Remove the Referer header when redirecting to a non-secure site + https://bugs.webkit.org/show_bug.cgi?id=31785 + + This makes Qt pass two tests introduced in r50226. + + * platform/network/qt/QNetworkReplyHandler.cpp: + (WebCore::QNetworkReplyHandler::sendResponseIfNeeded): + 2009-11-19 Olivier Goffart <ogoffart@trolltech.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp index 0546014..ec362ec 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp @@ -111,10 +111,17 @@ PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObje { JSLock lock(SilenceAssertionsOnly); - foreach(QtInstance* instance, cachedInstances.values(o)) { - if (instance->rootObject() == rootObject) - return instance; - } + foreach(QtInstance* instance, cachedInstances.values(o)) + if (instance->rootObject() == rootObject) { + // The garbage collector removes instances, but it may happen that the wrapped + // QObject dies before the gc kicks in. To handle that case we have to do an additional + // check if to see if the instance's wrapped object is still alive. If it isn't, then + // we have to create a new wrapper. + if (!instance->getObject()) + cachedInstances.remove(instance->hashKey()); + else + return instance; + } RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership); cachedInstances.insert(o, ret.get()); diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h index 00aaa5b..0afc6c7 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h @@ -59,6 +59,7 @@ public: JSValue booleanValue() const; QObject* getObject() const { return m_object; } + QObject* hashKey() const { return m_hashkey; } static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>, QScriptEngine::ValueOwnership ownership); diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 2f4722f..1ac80f6 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -325,6 +325,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded() newRequest.setHTTPMethod("GET"); } + // Should not set Referer after a redirect from a secure resource to non-secure one. + if (!newRequest.url().protocolIs("https") && protocolIs(newRequest.httpReferrer(), "https")) + newRequest.clearHTTPReferrer(); + client->willSendRequest(m_resourceHandle, newRequest, response); m_redirected = true; m_request = newRequest.toNetworkRequest(m_resourceHandle->getInternal()->m_frame); diff --git a/src/3rdparty/webkit/WebKit.pri b/src/3rdparty/webkit/WebKit.pri index 10291b4..5188662 100644 --- a/src/3rdparty/webkit/WebKit.pri +++ b/src/3rdparty/webkit/WebKit.pri @@ -11,7 +11,7 @@ isEmpty(OUTPUT_DIR) { DEFINES += BUILDING_QT__=1 building-libs { - win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 + win32-msvc*|win32-icc: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 } else { CONFIG(QTDIR_build) { QT += webkit diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp index 8922150..441bec7 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp @@ -99,6 +99,14 @@ public: It is possible to replace the contents of child elements using setPlainText() and setInnerXml(). To replace the element itself and its contents, use setOuterXml(). + + \section1 Examples + + The \l{DOM Traversal Example} shows one way to traverse documents in a running + example. + + The \l{Simple Selector Example} can be used to experiment with the searching + features of this class and provides sample code you can start working with. */ /*! @@ -195,8 +203,7 @@ bool QWebElement::isNull() const \a selectorQuery. If there are no matching elements, an empty list is returned. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} - syntax is used for the query. + \l{Standard CSS2 selector} syntax is used for the query. \note This search is performed recursively. @@ -211,8 +218,7 @@ QWebElementCollection QWebElement::findAll(const QString &selectorQuery) const Returns the first child element that matches the given CSS selector \a selectorQuery. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} - syntax is used for the query. + \l{Standard CSS2 selector} syntax is used for the query. \note This search is performed recursively. diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index aedf95a..1bdc3ed 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -864,7 +864,12 @@ void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button) { #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + Frame* frame = page->focusController()->focusedFrame(); + if (!frame) + return; + if (client && client->inputMethodEnabled() + && frame->document()->focusedNode() && button == Qt::LeftButton && qApp->autoSipEnabled()) { QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 2408dd4..2f0bf17 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,47 @@ +2009-11-28 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] SoftwareInputPanelRequest event sent when clicking in newly loaded page + + https://bugs.webkit.org/show_bug.cgi?id=31401 + + Don't set the event unless there is a focused node we can use + for editing afterwards. + + * Api/qwebpage.cpp: + (QWebPagePrivate::handleSoftwareInputPanel): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2009-11-23 David Boddie <dboddie@trolltech.com> + + Reviewed by Simon Hausmann. + + Updated the QWebElement documentation with links to examples and + external resources. + Fixed the project file for the webelement snippet and tidied up the + markers used for quoting the code. + + * Api/qwebelement.cpp: + * docs/webkitsnippets/webelement/main.cpp: + (findAll): + * docs/webkitsnippets/webelement/webelement.pro: + +2009-11-23 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Wrong runtime instance objects of wrapped QObjects may be used if + the wrapped object died before the gc removed the instance. + + https://bugs.webkit.org/show_bug.cgi?id=31681 + + Added a unit-test to verify that wrapping a QObject with the + same identity as a previously but now dead object works. + + * tests/qwebframe/tst_qwebframe.cpp: + 2009-11-19 Olivier Goffart <ogoffart@trolltech.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp index d437a6f..2707ffb 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp +++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp @@ -22,7 +22,6 @@ #include <qwebview.h> #include <qwebframe.h> #include <qwebelement.h> -#include <qdebug.h> static QWebFrame *frame; @@ -53,9 +52,10 @@ static void findAll() </p> */ +//! [FindAll intro] QList<QWebElement> allSpans = document.findAll("span"); QList<QWebElement> introSpans = document.findAll("p.intro span"); -//! [FindAll] +//! [FindAll intro] //! [FindAll] } int main(int argc, char *argv[]) diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro index f9b403b..8ca4b59 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro +++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro @@ -1,5 +1,8 @@ TEMPLATE = app CONFIG -= app_bundle +CONFIG(QTDIR_build) { + QT += webkit +} SOURCES = main.cpp include(../../../../../WebKit.pri) QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index d88d905..8cc7953 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -605,6 +605,7 @@ private slots: void render(); void scrollPosition(); void evaluateWillCauseRepaint(); + void qObjectWrapperWithSameIdentity(); private: QString evalJS(const QString&s) { @@ -2785,6 +2786,43 @@ void tst_QWebFrame::evaluateWillCauseRepaint() QTest::qWait(2000); } +class TestFactory : public QObject +{ + Q_OBJECT +public: + TestFactory() + : obj(0), counter(0) + {} + + Q_INVOKABLE QObject* getNewObject() + { + delete obj; + obj = new QObject(this); + obj->setObjectName(QLatin1String("test") + QString::number(++counter)); + return obj; + + } + + QObject* obj; + int counter; +}; + +void tst_QWebFrame::qObjectWrapperWithSameIdentity() +{ + m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>" + "<body><span id='span1'>test</span></body>"); + + QWebFrame* mainFrame = m_view->page()->mainFrame(); + QCOMPARE(mainFrame->toPlainText(), QString("test")); + + mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test1")); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test2")); +} QTEST_MAIN(tst_QWebFrame) #include "tst_qwebframe.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 32002e7..ee1969d 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1487,6 +1487,21 @@ void tst_QWebPage::inputMethods() QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText)); #endif + page->mainFrame()->setHtml("<html><body><p>nothing to input here"); + viewEventSpy.clear(); + + QWebElement para = page->mainFrame()->findFirstElement("p"); + { + QMouseEvent evpres(QEvent::MouseButtonPress, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpres); + QMouseEvent evrel(QEvent::MouseButtonRelease, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrel); + } + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + delete container; } diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index ef4989b..299585a 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -229,7 +229,10 @@ void QUnifiedTimer::restartAnimationTimer() void QUnifiedTimer::timerEvent(QTimerEvent *event) { - if (event->timerId() == startStopAnimationTimer.timerId()) { + //in the case of consistent timing we make sure the orders in which events come is always the same + //for that purpose we do as if the startstoptimer would always fire before the animation timer + if ((consistentTiming && startStopAnimationTimer.isActive()) || + event->timerId() == startStopAnimationTimer.timerId()) { startStopAnimationTimer.stop(); //we transfer the waiting animations into the "really running" state @@ -247,7 +250,9 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) time.start(); } } - } else if (event->timerId() == animationTimer.timerId()) { + } + + if (event->timerId() == animationTimer.timerId()) { // update current time on all top level animations updateAnimationsTime(); restartAnimationTimer(); diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 8c4cc82..0fb78d5 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -378,7 +378,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } int invalidCount = 0; - do { + while (inBytesLeft != 0) { if (iconv(state->cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) { if (errno == EINVAL && convState) { // buffer ends in a surrogate @@ -418,7 +418,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } } } - } while (inBytesLeft != 0); + } // reset to initial state iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft); diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp index 17ac9c6..c70232c 100644 --- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp @@ -269,8 +269,11 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths, } } - fd = ::dirfd(d); - int parentFd = parent?::dirfd(parent):0; + fd = qt_safe_dup(::dirfd(d)); + int parentFd = parent ? qt_safe_dup(::dirfd(parent)) : 0; + + ::closedir(d); + if(parent) ::closedir(parent); Q_ASSERT(fd); if(::fcntl(fd, F_SETSIG, SIGIO) || @@ -279,10 +282,6 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths, (parent && ::fcntl(parentFd, F_SETSIG, SIGIO)) || (parent && ::fcntl(parentFd, F_NOTIFY, DN_DELETE | DN_RENAME | DN_MULTISHOT))) { - - ::closedir(d); - if(parent) ::closedir(parent); - continue; // Could not set appropriate flags } diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 3cf9b7e..37b0ea1 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -55,6 +55,7 @@ #include "private/qcore_unix_p.h" #endif #include <stdio.h> +#include <stdlib.h> QT_BEGIN_NAMESPACE @@ -137,6 +138,21 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) if (path.isEmpty()) return path; + // FIXME let's see if this stuff works, then we might be able to remove some of the other code. +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + if (path.size() == 1 && path.at(0) == QLatin1Char('/')) + return path; +#endif + // Mac OS X 10.5.x doesn't support the realpath(X,0) extenstion we use here. +#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) || defined(Q_OS_SYMBIAN) + char *ret = realpath(path.toLocal8Bit().constData(), (char*)0); + if (ret) { + QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); + free(ret); + return canonicalPath; + } +#endif + QFileInfo fi; const QChar slash(QLatin1Char('/')); QString tmpPath = path; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 87f0737..41a6a1b 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE #define Q_USE_DEPRECATED_MAP_API 1 #endif -class QFSFileEnginePrivate : public QAbstractFileEnginePrivate +class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate { Q_DECLARE_PUBLIC(QFSFileEngine) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 8cbf6a3..71414ce 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -191,12 +191,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) return false; } - QT_STATBUF statBuf; - if (QT_FSTAT(fd, &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - QT_CLOSE(fd); - return false; + if (!(openMode & QIODevice::WriteOnly)) { + // we don't need this check if we tried to open for writing because then + // we had received EISDIR anyway. + QT_STATBUF statBuf; + if (QT_FSTAT(fd, &statBuf) != -1) { + if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + QT_CLOSE(fd); + return false; + } } } @@ -230,12 +234,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) return false; } - QT_STATBUF statBuf; - if (QT_FSTAT(fileno(fh), &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - fclose(fh); - return false; + if (!(openMode & QIODevice::WriteOnly)) { + // we don't need this check if we tried to open for writing because then + // we had received EISDIR anyway. + QT_STATBUF statBuf; + if (QT_FSTAT(fileno(fh), &statBuf) != -1) { + if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + fclose(fh); + return false; + } } } diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 10a61ca..9335085 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2546,9 +2546,9 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour int destinationLast = destinationChild + (sourceLast - sourceFirst); d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast)); - d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild); emit layoutAboutToBeChanged(); + d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); return true; } diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index b197b9d..c6eef5e 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -336,6 +336,7 @@ public: // internal window handle used for socketnotifiers/timers/etc HWND internalHwnd; + HHOOK getMessageHook; // for controlling when to send posted events QAtomicInt serialNumber; @@ -363,7 +364,7 @@ public: }; QEventDispatcherWin32Private::QEventDispatcherWin32Private() - : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), serialNumber(0), lastSerialNumber(0), wakeUps(0) + : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), wakeUps(0) { resolveTimerAPI(); } @@ -471,37 +472,11 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) } return 0; } else if (message == WM_TIMER) { - if (wp == SendPostedEventsTimerId) { - KillTimer(d->internalHwnd, wp); - int localSerialNumber = d->serialNumber; - (void) d->wakeUps.fetchAndStoreRelease(0); - if (localSerialNumber != d->lastSerialNumber) { - PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); - } - } else { - Q_ASSERT(d != 0); - d->sendTimerEvent(wp); - } + Q_ASSERT(d != 0); + d->sendTimerEvent(wp); return 0; } else if (message == WM_QT_SENDPOSTEDEVENTS) { int localSerialNumber = d->serialNumber; - - if (GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER) != 0) { - // delay the next pass of sendPostedEvents() until we get the special - // WM_TIMER, which allows all pending Windows messages to be processed - if (SetTimer(d->internalHwnd, SendPostedEventsTimerId, 0, 0) == 0) { - // failed to start the timer, oops, clear wakeUps in an attempt to keep things running - qErrnoWarning("Qt: INTERNAL ERROR: failed to start sendPostedEvents() timer"); - d->wakeUps.fetchAndStoreRelease(0); - } else { - // SetTimer() succeeded, nothing to do now - ; - } - } else { - // nothing pending in the queue, let sendPostedEvents go through - d->wakeUps.fetchAndStoreRelease(0); - } - if (localSerialNumber != d->lastSerialNumber) { d->lastSerialNumber = localSerialNumber; QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); @@ -512,6 +487,31 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) return DefWindowProc(hwnd, message, wp, lp); } +LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) +{ + if (wp == PM_REMOVE) { + QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); + Q_ASSERT(q != 0); + if (q) { + QEventDispatcherWin32Private *d = q->d_func(); + int localSerialNumber = d->serialNumber; + if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0) { + // no more input or timer events in the message queue, we can allow posted events to be + // sent now + (void) d->wakeUps.fetchAndStoreRelease(0); + MSG *msg = (MSG *) lp; + if (localSerialNumber != d->lastSerialNumber + // if this message IS the one that triggers sendPostedEvents(), no need to post it again + && msg->hwnd != d->internalHwnd + && msg->message != WM_QT_SENDPOSTEDEVENTS) { + PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); + } + } + } + } + return CallNextHookEx(0, code, wp, lp); +} + static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher) { // make sure that multiple Qt's can coexist in the same process @@ -636,6 +636,12 @@ void QEventDispatcherWin32::createInternalHwnd() return; d->internalHwnd = qt_create_internal_window(this); + // setup GetMessage hook needed to drive our posted events + d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); + if (!d->getMessageHook) { + qFatal("Qt: INTERNALL ERROR: failed to install GetMessage hook"); + } + // register all socket notifiers QList<int> sockets = (d->sn_read.keys().toSet() + d->sn_write.keys().toSet() @@ -1058,6 +1064,10 @@ void QEventDispatcherWin32::closingDown() d->unregisterTimer(d->timerVec.at(i), true); d->timerVec.clear(); d->timerDict.clear(); + + if (d->getMessageHook) + UnhookWindowsHookEx(d->getMessageHook); + d->getMessageHook = 0; } bool QEventDispatcherWin32::event(QEvent *e) diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a5ef4d4..7f0e87d 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -102,6 +102,7 @@ public: private: friend LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); + friend LRESULT CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM); }; QT_END_NAMESPACE diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 52c94e9..a922022 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -145,8 +145,7 @@ QObjectPrivate::QObjectPrivate(int version) receiveChildEvents = true; postedEvents = 0; extraData = 0; - for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i) - connectedSignals[i] = 0; + connectedSignals = 0; inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; @@ -2949,13 +2948,9 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, QObjectPrivate *const sender_d = QObjectPrivate::get(s); if (signal_index < 0) { - for (uint i = 0; i < (sizeof sender_d->connectedSignals - / sizeof sender_d->connectedSignals[0] ); ++i) - sender_d->connectedSignals[i] = ~0u; - } else if (signal_index < (int)sizeof sender_d->connectedSignals * 8) { - uint n = (signal_index / (8 * sizeof sender_d->connectedSignals[0])); - sender_d->connectedSignals[n] |= (1 << (signal_index - n * 8 - * sizeof sender_d->connectedSignals[0])); + sender_d->connectedSignals = ~ulong(0); + } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) { + sender_d->connectedSignals |= ulong(1) << signal_index; } return true; @@ -3213,15 +3208,9 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign computeOffsets(m, &signalOffset, &methodOffset); int signal_index = signalOffset + local_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; - } + + if (!sender->d_func()->isSignalConnected(signal_index)) + return; // nothing connected to these signals, and no spy if (sender->d_func()->blockSig) return; @@ -3384,28 +3373,6 @@ int QObjectPrivate::signalIndex(const char *signalName) const return relative_index + signalOffset; } -/*! \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. - - \a signal_index must be the index returned by QObjectPrivate::signalIndex; -*/ -bool QObjectPrivate::isSignalConnected(int signal_index) const -{ - if (signal_index < (int)sizeof(connectedSignals) * 8 - && !qt_signal_spy_callback_set.signal_begin_callback - && !qt_signal_spy_callback_set.signal_end_callback) { - uint n = (signal_index / (8 * sizeof connectedSignals[0])); - uint m = 1 << (signal_index - n * 8 * sizeof connectedSignals[0]); - if ((connectedSignals[n] & m) == 0) - // nothing connected to these signals, and no spy - return false; - } - return true; -} - /***************************************************************************** Properties *****************************************************************************/ diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 425a1df..a92ae3b 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -172,7 +172,7 @@ public: } int signalIndex(const char *signalName) const; - bool isSignalConnected(int signalIdx) const; + inline bool isSignalConnected(int signalIdx) const; public: QString objectName; @@ -183,7 +183,7 @@ public: 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 + mutable ulong connectedSignals; #ifdef QT3_SUPPORT QList<QObject *> pendingChildInsertedEvents; @@ -205,6 +205,23 @@ public: int *deleteWatch; }; +/*! \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. + + \a signal_index must be the index returned by QObjectPrivate::signalIndex; +*/ +inline bool QObjectPrivate::isSignalConnected(int signal_index) const +{ + return signal_index >= (int)sizeof(connectedSignals) * 8 + || qt_signal_spy_callback_set.signal_begin_callback + || qt_signal_spy_callback_set.signal_end_callback + || (connectedSignals & (ulong(1) << signal_index)); +} + + inline void q_guard_addGuard(QGuard<QObject> *g) { QObjectPrivate *p = QObjectPrivate::get(g->o); diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index f0de98d..201e7b3 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -324,7 +324,7 @@ void QVector<T>::detach_helper() { realloc(d->size, d->alloc); } template <typename T> void QVector<T>::reserve(int asize) -{ if (asize > d->alloc || d->ref != 1) realloc(d->size, asize); d->capacity = 1; } +{ if (asize > d->alloc) realloc(d->size, asize); if (d->ref == 1) d->capacity = 1; } template <typename T> void QVector<T>::resize(int asize) { realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ? @@ -441,6 +441,7 @@ void QVector<T>::free(Data *x) template <typename T> void QVector<T>::realloc(int asize, int aalloc) { + Q_ASSERT(asize <= aalloc); T *pOld; T *pNew; union { QVectorData *d; Data *p; } x; @@ -496,7 +497,8 @@ void QVector<T>::realloc(int asize, int aalloc) pOld = p->array + x.d->size; pNew = x.p->array + x.d->size; // copy objects from the old array into the new array - while (x.d->size < qMin(asize, d->size)) { + const int toMove = qMin(asize, d->size); + while (x.d->size < toMove) { new (pNew++) T(*pOld++); x.d->size++; } diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index 73ca94c..c74f622 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -526,7 +526,7 @@ static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); // Multiple selection is allowed only in IFileOpenDialog. - IFileOpenDialog *pfd; + IFileOpenDialog *pfd = 0; HRESULT hr = CoCreateInstance(QT_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, QT_IID_IFileOpenDialog, reinterpret_cast<void**>(&pfd)); @@ -597,6 +597,8 @@ static QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, } } } + if (pfd) + pfd->Release(); return result; } diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 5b0983b..0c467cd 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -625,10 +625,11 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) } NSFontManager *mgr = [NSFontManager sharedFontManager]; - nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(font.family()) + QFontInfo fontInfo(font); + nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) traits:mask weight:weight - size:QFontInfo(font).pointSize()]; + size:fontInfo.pointSize()]; } [mgr setSelectedFont:nsFont isMultiple:NO]; diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index c0e4890..cf28dc4 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -236,6 +236,18 @@ bool QEglContext::makeCurrent(EGLSurface surface) currentSurface = surface; setCurrentContext(apiType, this); + // Force the right API to be bound before making the context current. + // The EGL implementation should be able to figure this out from ctx, + // but some systems require the API to be explicitly set anyway. +#ifdef EGL_OPENGL_ES_API + if (apiType == QEgl::OpenGL) + eglBindAPI(EGL_OPENGL_ES_API); +#endif +#ifdef EGL_OPENVG_API + if (apiType == QEgl::OpenVG) + eglBindAPI(EGL_OPENVG_API); +#endif + bool ok = eglMakeCurrent(dpy, surface, surface, ctx); if (!ok) qWarning() << "QEglContext::makeCurrent():" << errorString(eglGetError()); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 7e5929e..686096c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -370,12 +370,6 @@ void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### We don't support negative spacing yet - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[0] = spacing; invalidate(); } @@ -389,12 +383,6 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### We don't support negative spacing yet - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[1] = spacing; invalidate(); } @@ -405,7 +393,8 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) If an item is anchored with no spacing associated with the anchor, it will use the default spacing. - Currently QGraphicsAnchorLayout does not support negative default spacings. + QGraphicsAnchorLayout does not support negative spacings. Setting a negative value will unset the + previous spacing and make the layout use the spacing provided by the current widget style. \sa setHorizontalSpacing(), setVerticalSpacing() */ @@ -413,14 +402,6 @@ void QGraphicsAnchorLayout::setSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### Currently we do not support negative anchors inside the graph. - // To avoid those being created by a negative spacing, we must - // make this test. - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[0] = d->spacings[1] = spacing; invalidate(); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 94a37a0..bb45e7e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -755,7 +755,6 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch case QGraphicsItem::ItemClipsChildrenToShape: flag = AncestorClipsChildren; enabled = flags & QGraphicsItem::ItemClipsChildrenToShape; - invalidateCachedClipPathRecursively(/*childrenOnly=*/true); break; case QGraphicsItem::ItemIgnoresTransformations: flag = AncestorIgnoresTransformations; @@ -1104,9 +1103,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); if (scene) { if (!implicitUpdate) - scene->d_func()->markDirty(q_ptr, QRect(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/true); + scene->d_func()->markDirty(q_ptr); // Re-enable scene pos notifications for new ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) @@ -1147,11 +1144,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) setEnabledHelper(true, /* explicit = */ false); // If the item is being deleted, the whole scene will be updated. - if (scene) { - scene->d_func()->markDirty(q_ptr, QRect(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/true); - } + if (scene) + scene->d_func()->markDirty(q_ptr); } } @@ -1732,9 +1726,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemClipsChildrenToShape); } - if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape)) - d_ptr->invalidateCachedClipPath(); - if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) { // Item children clipping changes. Propagate the ancestor flag to // all children. @@ -1777,9 +1768,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) else d_ptr->scene->d_func()->unregisterScenePosItem(this); } - d_ptr->scene->d_func()->markDirty(this, QRectF(), - /*invalidateChildren=*/true, - /*maybeDirtyClipPath*/true); + d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true); } // Notify change. @@ -2127,12 +2116,8 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData)); if (c) c->purge(); - if (scene) { - scene->d_func()->markDirty(q_ptr, QRectF(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/false, - /*force=*/true); - } + if (scene) + scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true); } // Certain properties are dropped as an item becomes invisible. @@ -2542,7 +2527,6 @@ void QGraphicsItem::setOpacity(qreal opacity) #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, - /*maybeDirtyClipPath=*/false, /*force=*/false, /*ignoreOpacity=*/true); } @@ -2590,8 +2574,11 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) d_ptr->graphicsEffect = 0; if (oldEffectPrivate) { oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source. - if (d_ptr->scene) // Update the views directly. - d_ptr->scene->d_func()->markDirty(this, QRectF(), false, false, false, false, true); + if (d_ptr->scene) { // Update the views directly. + d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/false, + /*force=*/false, /*ignoreOpacity=*/false, + /*removeItemFromScene=*/true); + } } } else { // Set new effect. @@ -3399,7 +3386,6 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) { Q_Q(QGraphicsItem); inSetPosHelper = 1; - updateCachedClipPathFromSetPosHelper(pos); if (scene) q->prepareGeometryChange(); QPointF oldPos = this->pos; @@ -4535,22 +4521,12 @@ bool QGraphicsItem::isClipped() const QPainterPath QGraphicsItem::clipPath() const { Q_D(const QGraphicsItem); - if (!d->dirtyClipPath) - return d->emptyClipPath ? QPainterPath() : d->cachedClipPath; - - if (!isClipped()) { - d_ptr->setCachedClipPath(QPainterPath()); - return d->cachedClipPath; - } + if (!isClipped()) + return QPainterPath(); const QRectF thisBoundingRect(boundingRect()); - if (thisBoundingRect.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + if (thisBoundingRect.isEmpty()) return QPainterPath(); - } QPainterPath clip; // Start with the item's bounding rect. @@ -4561,40 +4537,18 @@ QPainterPath QGraphicsItem::clipPath() const const QGraphicsItem *lastParent = this; // Intersect any in-between clips starting at the top and moving downwards. - bool foundValidClipPath = false; while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { // Map clip to the current parent and intersect with its shape/clipPath clip = lastParent->itemTransform(parent).map(clip); - if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) { - if (parent->d_ptr->emptyClipPath) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); - return QPainterPath(); - } - clip = clip.intersected(parent->d_ptr->cachedClipPath); - if (!(parent->d_ptr->flags & ItemClipsToShape)) - clip = clip.intersected(parent->shape()); - } else { - clip = clip.intersected(parent->shape()); - } - - if (clip.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + clip = clip.intersected(parent->shape()); + if (clip.isEmpty()) return clip; - } lastParent = parent; } - if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - || foundValidClipPath) { + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) break; - } } if (lastParent != this) { @@ -4607,7 +4561,6 @@ QPainterPath QGraphicsItem::clipPath() const if (d->flags & ItemClipsToShape) clip = clip.intersected(shape()); - d_ptr->setCachedClipPath(clip); return clip; } @@ -5026,15 +4979,14 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) \internal Returns true if we can discard an update request; otherwise false. */ -bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignoreVisibleBit, - bool ignoreDirtyBit, bool ignoreOpacity) const +bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit, + bool ignoreOpacity) const { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. return !scene || (!visible && !ignoreVisibleBit && !this->ignoreVisible) || (!ignoreDirtyBit && fullUpdatePending) - || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); } @@ -5169,109 +5121,6 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } -void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect) -{ - setEmptyCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull() - && !(flags & QGraphicsItem::ItemClipsChildrenToShape); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->setEmptyCachedClipPathRecursively(); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect) -{ - if (!childrenOnly) - invalidateCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull(); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos) -{ - Q_ASSERT(inSetPosHelper); - - if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) - return; // Not clipped by any ancestor. - - // Find closest clip ancestor and transform. - Q_Q(QGraphicsItem); - // COMBINE - QTransform thisToParentTransform = QTransform::fromTranslate(newPos.x(), newPos.y()); - if (transformData) - thisToParentTransform = transformData->computedFullTransform(&thisToParentTransform); - QGraphicsItem *clipParent = parent; - while (clipParent && !clipParent->d_ptr->inDestructor && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) { - thisToParentTransform *= clipParent->d_ptr->transformToParent(); - clipParent = clipParent->d_ptr->parent; - } - - // Ensure no parents are currently being deleted. This can only - // happen if the item is moved by a dying ancestor. - QGraphicsItem *p = clipParent; - while (p) { - if (p->d_ptr->inDestructor) - return; - p = p->d_ptr->parent; - } - - // From here everything is calculated in clip parent's coordinates. - const QRectF parentBoundingRect(clipParent->boundingRect()); - const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect())); - - if (!parentBoundingRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's bounding rect, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect)); - return; - } - - const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape()); - if (parentClip.contains(thisBoundingRect)) - return; // Item is inside the clip parent's shape. No update required. - - const QRectF parentClipRect(parentClip.controlPointRect()); - if (!parentClipRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's shape, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect)); - } else { - // Item is partially inside the clip parent's shape, - // i.e. the cached clip path must be invalidated. - invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect)); - } -} - // Traverses all the ancestors up to the top-level and updates the pointer to // always point to the top-most item that has a dirty scene transform. // It then backtracks to the top-most dirty item and start calculating the @@ -7288,9 +7137,7 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->index->prepareBoundingRectChange(this); - scenePrivate->markDirty(this, QRectF(), - /*invalidateChildren=*/true, - /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); + scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); // For compatibility reasons, we have to update the item's old geometry // if someone is connected to the changed signal or the scene has no views. @@ -7313,16 +7160,6 @@ void QGraphicsItem::prepareGeometryChange() // ### Only do this if the parent's effect applies to the entire subtree. parent->d_ptr->notifyBoundingRectChanged = 1; } - - if (d_ptr->inSetPosHelper) - return; - - if (d_ptr->flags & ItemClipsChildrenToShape - || d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - d_ptr->invalidateCachedClipPathRecursively(); - } else { - d_ptr->invalidateCachedClipPath(); - } } /*! @@ -9604,9 +9441,11 @@ void QGraphicsTextItem::setDefaultTextColor(const QColor &col) { QTextControl *c = dd->textControl(); QPalette pal = c->palette(); + QColor old = pal.color(QPalette::Text); pal.setColor(QPalette::Text, col); c->setPalette(pal); - update(); + if (old != col) + update(); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 75c8246..d6ffb1a 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -152,8 +152,6 @@ public: dirty(0), dirtyChildren(0), localCollisionHack(0), - dirtyClipPath(1), - emptyClipPath(0), inSetPosHelper(0), needSortChildren(1), // ### can be 0 by default? allChildrenDirty(0), @@ -221,7 +219,7 @@ public: void appendGraphicsTransform(QGraphicsTransform *t); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); - bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, + bool discardUpdateRequest(bool ignoreVisibleBit = false, bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT @@ -307,26 +305,6 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); - inline void setCachedClipPath(const QPainterPath &path) - { - cachedClipPath = path; - dirtyClipPath = 0; - emptyClipPath = 0; - } - - inline void setEmptyCachedClipPath() - { - emptyClipPath = 1; - dirtyClipPath = 0; - } - - void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF()); - - inline void invalidateCachedClipPath() - { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; } - - void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); - void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); inline void ensureSceneTransform() { @@ -409,17 +387,12 @@ public: return true; } - inline bool isClippedAway() const - { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } - inline bool childrenClippedToShape() const { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); } inline bool isInvisible() const { - return !visible - || (childrenClippedToShape() && isClippedAway()) - || (childrenCombineOpacity() && isFullyTransparent()); + return !visible || (childrenCombineOpacity() && isFullyTransparent()); } void setFocusHelper(Qt::FocusReason focusReason, bool climb); @@ -435,7 +408,6 @@ public: inline void sendScenePosChange(); virtual void siblingOrderChange(); - QPainterPath cachedClipPath; QRectF childrenBoundingRect; QRectF needsRepaint; QMap<QWidget *, QRect> paintedViewBoundingRects; @@ -480,8 +452,6 @@ public: quint32 dirty : 1; quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; - quint32 dirtyClipPath : 1; - quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; quint32 needSortChildren : 1; quint32 allChildrenDirty : 1; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 10d251d..8777cdc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -555,7 +555,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) // Clear focus on the item to remove any reference in the focusWidget chain. item->clearFocus(); - markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true); + markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false, + /*ignoreOpacity=*/false, /*removingItemFromScene=*/true); if (item->d_ptr->inDestructor) { // The item is actually in its destructor, we call the special method in the index. @@ -4759,15 +4760,13 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, - bool maybeDirtyClipPath, bool force, bool ignoreOpacity, - bool removingItemFromScene) + bool force, bool ignoreOpacity, bool removingItemFromScene) { Q_ASSERT(item); if (updateAll) return; - if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, - /*ignoreVisibleBit=*/force, + if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, /*ignoreOpacity=*/ignoreOpacity)) { if (item->d_ptr->dirty) { diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index fdec466..69e4d5b 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -78,7 +78,7 @@ class QGraphicsSceneIndex; class QGraphicsView; class QGraphicsWidget; -class QGraphicsScenePrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QGraphicsScenePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGraphicsScene) public: @@ -222,8 +222,7 @@ public: QRegion *, QWidget *, qreal, const QTransform *const, bool, bool); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, - bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false, - bool removingItemFromScene = false); + bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); @@ -266,6 +265,7 @@ public: { if (needSortTopLevelItems) { qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + topLevelSequentialOrdering = false; needSortTopLevelItems = false; } } diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index d9c65bb..fe569f4 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -385,8 +385,6 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - wd->invalidateCachedClipPathRecursively(); - // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { @@ -1303,7 +1301,8 @@ bool QGraphicsWidget::event(QEvent *event) case QEvent::Polish: polishEvent(); d->polished = true; - d->updateFont(d->font); + if (!d->font.isCopyOf(QApplication::font())) + d->updateFont(d->font); break; case QEvent::WindowActivate: case QEvent::WindowDeactivate: diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 35322e9..650075b 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -55,20 +55,11 @@ Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64 = 0; Q_GUI_EXPORT _qt_image_cleanup_hook qt_image_cleanup_hook = 0; Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64 = 0; - -QImagePixmapCleanupHooks* qt_image_and_pixmap_cleanup_hooks = 0; - - -QImagePixmapCleanupHooks::QImagePixmapCleanupHooks() -{ - qt_image_and_pixmap_cleanup_hooks = this; -} +Q_GLOBAL_STATIC(QImagePixmapCleanupHooks, qt_image_and_pixmap_cleanup_hooks) QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance() { - if (!qt_image_and_pixmap_cleanup_hooks) - qt_image_and_pixmap_cleanup_hooks = new QImagePixmapCleanupHooks; - return qt_image_and_pixmap_cleanup_hooks; + return qt_image_and_pixmap_cleanup_hooks(); } void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) @@ -105,9 +96,8 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook) void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks[i](pm); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->pixmapModificationHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->pixmapModificationHooks[i](pm); if (qt_pixmap_cleanup_hook_64) qt_pixmap_cleanup_hook_64(pm->cacheKey()); @@ -115,9 +105,8 @@ void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks[i](pm); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->pixmapDestructionHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->pixmapDestructionHooks[i](pm); if (qt_pixmap_cleanup_hook_64) qt_pixmap_cleanup_hook_64(pm->cacheKey()); @@ -125,9 +114,8 @@ void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->imageHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->imageHooks[i](key); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->imageHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->imageHooks[i](key); if (qt_image_cleanup_hook_64) qt_image_cleanup_hook_64(key); diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h index 9e490d7..dfc5f28 100644 --- a/src/gui/image/qimagepixmapcleanuphooks_p.h +++ b/src/gui/image/qimagepixmapcleanuphooks_p.h @@ -61,13 +61,10 @@ typedef void (*_qt_image_cleanup_hook_64)(qint64); typedef void (*_qt_pixmap_cleanup_hook_pm)(QPixmap*); class QImagePixmapCleanupHooks; -extern QImagePixmapCleanupHooks* qt_image_and_pixmap_cleanup_hooks; class Q_GUI_EXPORT QImagePixmapCleanupHooks { public: - QImagePixmapCleanupHooks(); - static QImagePixmapCleanupHooks *instance(); static void enableCleanupHooks(const QImage &image); diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index b085c09..406dc0b 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1168,7 +1168,7 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) Qt::HANDLE QPixmap::handle() const { #if defined(Q_WS_X11) - if (data->classId() == QPixmapData::X11Class) + if (data && data->classId() == QPixmapData::X11Class) return static_cast<const QX11PixmapData*>(data.constData())->handle(); #endif return 0; @@ -1219,7 +1219,7 @@ QPixmap::QPixmap(const QImage& image) if (!qt_pixmap_thread_test()) return; - if (data->pixelType() == QPixmapData::BitmapType) + if (data && data->pixelType() == QPixmapData::BitmapType) *this = QBitmap::fromImage(image); else *this = fromImage(image); diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index ad15655..acfeff8 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2552,7 +2552,9 @@ void QAbstractItemView::verticalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); - d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + if (viewport()->rect().contains(posInVp)) + d->checkMouseMove(posInVp); } /*! @@ -2563,7 +2565,9 @@ void QAbstractItemView::horizontalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); - d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + if (viewport()->rect().contains(posInVp)) + d->checkMouseMove(posInVp); } /*! diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index f1ae3d2..fc82f30 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1153,6 +1153,8 @@ void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset() { Q_Q(QSortFilterProxyModel); q->beginResetModel(); + invalidatePersistentIndexes(); + clear_mapping(); } void QSortFilterProxyModelPrivate::_q_sourceReset() @@ -1470,6 +1472,8 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) { Q_D(QSortFilterProxyModel); + beginResetModel(); + disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex))); @@ -1551,7 +1555,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); d->clear_mapping(); - reset(); + endResetModel(); if (d->update_source_sort_column() && d->dynamic_sortfilter) d->sort(); } diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index fb2bc72..ab57c32 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -133,36 +133,46 @@ private: TTimeIntervalMicroSeconds iDuration; }; +static QS60Beep* qt_S60Beep = 0; + QS60Beep::~QS60Beep() { + if (iToneUtil) { + switch (iState) { + case EBeepPlaying: + iToneUtil->CancelPlay(); + break; + case EBeepNotPrepared: + iToneUtil->CancelPrepare(); + break; + } + } delete iToneUtil; } QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - QS60Beep* self=new (ELeave) QS60Beep(); + QS60Beep* self = new (ELeave) QS60Beep(); CleanupStack::PushL(self); self->ConstructL(aFrequency, aDuration); CleanupStack::Pop(); return self; -}; +} void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - iToneUtil=CMdaAudioToneUtility::NewL(*this); - iState=EBeepNotPrepared; - iFrequency=aFrequency; - iDuration=aDuration; - iToneUtil->PrepareToPlayTone(iFrequency,iDuration); + iToneUtil = CMdaAudioToneUtility::NewL(*this); + iState = EBeepNotPrepared; + iFrequency = aFrequency; + iDuration = aDuration; + iToneUtil->PrepareToPlayTone(iFrequency, iDuration); } void QS60Beep::Play() { - if (iState != EBeepNotPrepared) { - if (iState == EBeepPlaying) { - iToneUtil->CancelPlay(); - iState = EBeepPrepared; - } + if (iState == EBeepPlaying) { + iToneUtil->CancelPlay(); + iState = EBeepPrepared; } iToneUtil->Play(); @@ -173,13 +183,14 @@ void QS60Beep::MatoPrepareComplete(TInt aError) { if (aError == KErrNone) { iState = EBeepPrepared; + Play(); } } void QS60Beep::MatoPlayComplete(TInt aError) { Q_UNUSED(aError); - iState=EBeepPrepared; + iState = EBeepPrepared; } @@ -812,6 +823,12 @@ void QSymbianControl::Draw(const TRect& controlRect) const if (!engine) return; + const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents; + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r)); + } + // Map source rectangle into coordinates of the backing store. const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY); const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase); @@ -822,14 +839,48 @@ void QSymbianControl::Draw(const TRect& controlRect) const CFbsBitmap *bitmap = s60Surface->symbianBitmap(); CWindowGc &gc = SystemGc(); - if(!qwidget->d_func()->extraData()->disableBlit) { + switch(qwidget->d_func()->extraData()->nativePaintMode) { + case QWExtra::Disable: + // Do nothing + break; + + case QWExtra::Blit: if (qwidget->d_func()->isOpaque) gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect); + break; + + case QWExtra::ZeroFill: + if (Window().DisplayMode() == EColor16MA) { + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + gc.SetBrushColor(TRgb::Color16MA(0)); + gc.Clear(controlRect); + } else { + gc.SetBrushColor(TRgb(0x000000)); + gc.Clear(controlRect); + }; + break; + + default: + Q_ASSERT(false); } } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); } + + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + // The draw ops aren't actually sent to WSERV until the graphics + // context is deactivated, which happens in the function calling + // this one. We therefore delay the delivery of endNativePaintEvent, + // to ensure that drawing has completed by the time the widget + // receives the event. Note that, if the widget needs to ensure + // that the draw ops have actually been executed into the output + // framebuffer, a call to RWsSession::Flush is required in the + // endNativePaintEvent implementation. + QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r)); + } } void QSymbianControl::SizeChanged() @@ -1226,6 +1277,10 @@ void qt_init(QApplicationPrivate * /* priv */, int) *****************************************************************************/ void qt_cleanup() { + if(qt_S60Beep) { + delete qt_S60Beep; + qt_S60Beep = 0; + } QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there @@ -1467,14 +1522,13 @@ void QApplication::setCursorFlashTime(int msecs) void QApplication::beep() { - TInt frequency=440; - TTimeIntervalMicroSeconds duration(500000); - QS60Beep* beep=NULL; - TRAPD(err, beep=QS60Beep::NewL(frequency, duration)); - if (!err) - beep->Play(); - delete beep; - beep=NULL; + if (!qt_S60Beep) { + TInt frequency = 880; + TTimeIntervalMicroSeconds duration(500000); + TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration)); + } + if (qt_S60Beep) + qt_S60Beep->Play(); } /*! diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 2a53a16..265f52f 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -282,8 +282,8 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \i SelectPreviousPage \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \row \i SelectStartOfLine \i Shift+Home \i Ctrl+Shift+Left \i Shift+Home \i Shift+Home \i Shift+Home \row \i SelectEndOfLine \i Shift+End \i Ctrl+Shift+Right \i Shift+End \i Shift+End \i Shift+End - \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up \i (none) \i (none) \i (none) - \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down \i (none) \i (none) \i (none) + \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up, Meta+Shift+A \i (none) \i (none) \i (none) + \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down, Meta+Shift+E \i (none) \i (none) \i (none) \row \i SelectStartOfDocument\i Ctrl+Shift+Home \i Ctrl+Shift+Up, Shift+Home \i Ctrl+Shift+Home\i Ctrl+Shift+Home \i Ctrl+Shift+Home \row \i SelectEndOfDocument \i Ctrl+Shift+End \i Ctrl+Shift+Down, Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End \row \i DeleteStartOfWord \i Ctrl+Backspace \i Alt+Backspace \i Ctrl+Backspace \i Ctrl+Backspace \i (none) @@ -732,6 +732,8 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = { {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, QApplicationPrivate::KB_Mac}, {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, QApplicationPrivate::KB_Mac}, {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, QApplicationPrivate::KB_Mac}, + {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, QApplicationPrivate::KB_Mac}, + {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, QApplicationPrivate::KB_Mac}, {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Mac}, {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Mac} }; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index f31dcc4..49292ac 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -366,7 +366,8 @@ bool QWidget::hasEditFocus() const normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to change focus. - This feature is only available in Qt for Embedded Linux. + This feature is only available in Qt for Embedded Linux and Qt + for Symbian. \sa hasEditFocus(), QApplication::keypadNavigationEnabled() */ @@ -4605,7 +4606,7 @@ void QWidgetPrivate::updateFont(const QFont &font) if (!q->parentWidget() && extra && extra->proxyWidget) { QGraphicsProxyWidget *p = extra->proxyWidget; inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve(); - } else + } else #endif //QT_NO_GRAPHICSVIEW if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedFontResolveMask = 0; @@ -6053,6 +6054,11 @@ bool QWidget::hasFocus() const (Nothing happens if the focus in and focus out widgets are the same.) + \note On embedded platforms, setFocus() will not cause an input panel + to be opened by the input method. If you want this to happen, you + have to send a QEvent::RequestSoftwareInputPanel event to the + widget yourself. + setFocus() gives focus to a widget regardless of its focus policy, but does not clear any keyboard grab (see grabKeyboard()). @@ -6065,7 +6071,7 @@ bool QWidget::hasFocus() const \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(), setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(), - grabMouse(), {Keyboard Focus} + grabMouse(), {Keyboard Focus}, QEvent::RequestSoftwareInputPanel */ void QWidget::setFocus(Qt::FocusReason reason) @@ -9905,13 +9911,13 @@ void QWidget::scroll(int dx, int dy) Q_D(QWidget); #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { - // Graphics View maintains its own dirty region as a list of rects; - // until we can connect item updates directly to the view, we must - // separately add a translated dirty region. - if (!d->dirty.isEmpty()) { - foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) - proxy->update(rect); - } + // Graphics View maintains its own dirty region as a list of rects; + // until we can connect item updates directly to the view, we must + // separately add a translated dirty region. + if (!d->dirty.isEmpty()) { + foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) + proxy->update(rect); + } proxy->scroll(dx, dy, proxy->subWidgetRect(this)); return; } @@ -9940,13 +9946,13 @@ void QWidget::scroll(int dx, int dy, const QRect &r) Q_D(QWidget); #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { - // Graphics View maintains its own dirty region as a list of rects; - // until we can connect item updates directly to the view, we must - // separately add a translated dirty region. - if (!d->dirty.isEmpty()) { - foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) - proxy->update(rect); - } + // Graphics View maintains its own dirty region as a list of rects; + // until we can connect item updates directly to the view, we must + // separately add a translated dirty region. + if (!d->dirty.isEmpty()) { + foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) + proxy->update(rect); + } proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint())); return; } diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 0d9f9ee..1907cca 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2617,8 +2617,6 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) releaseMouse(); if(mac_keyboard_grabber == this) releaseKeyboard(); - if(acceptDrops()) - setAcceptDrops(false); if(testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal QApplicationPrivate::leaveModal(this); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index ba375d8..64e3290 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -230,12 +230,42 @@ struct QWExtra { #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called - // If set, QSymbianControl::Draw does not blit this widget - // This is to allow, for use cases such as video, widgets which, from the Qt point - // of view, are just placeholders in the scene. For these widgets, any necessary - // drawing to the UI framebuffer is done by the relevant Symbian subsystem. For - // video rendering, this would be an MMF controller, or MDF post-processor. - uint disableBlit : 1; + /** + * Defines the behaviour of QSymbianControl::Draw. + */ + enum NativePaintMode { + /** + * Normal drawing mode: blits the required region of the backing store + * via WSERV. + */ + Blit, + + /** + * Disable drawing for this widget. + */ + Disable, + + /** + * Paint zeros into the WSERV framebuffer, using BitGDI APIs. For windows + * with an EColor16MU display mode, zero is written only into the R, G and B + * channels of the pixel. + */ + ZeroFill, + + Default = Blit + }; + + NativePaintMode nativePaintMode : 2; + + /** + * If this bit is set, each native widget receives the signals from the + * Symbian control immediately before and immediately after draw ops are + * sent to the window server for this control: + * void beginNativePaintEvent(const QRect &paintRect); + * void endNativePaintEvent(const QRect &paintRect); + */ + uint receiveNativePaintEvents : 1; + #endif }; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 359df2a..37614c7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -881,7 +881,8 @@ void QWidgetPrivate::deleteTLSysExtra() void QWidgetPrivate::createSysExtra() { extra->activated = 0; - extra->disableBlit = 0; + extra->nativePaintMode = QWExtra::Default; + extra->receiveNativePaintEvents = 0; } void QWidgetPrivate::deleteSysExtra() diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8226797..1b8f413 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -949,6 +949,8 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; QWidgetBackingStore *wbs = x->backingStore; + if (!wbs) + return; static int accelEnv = -1; if (accelEnv == -1) { diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3f33319..4a72434 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3240,7 +3240,8 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; // ### Remove the TestFontEngine and Box engine crap, in these diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 7d1c109..9a0e319 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -56,6 +56,20 @@ QT_BEGIN_NAMESPACE * class QVectorPath * */ +QVectorPath::~QVectorPath() +{ + if (m_hints & ShouldUseCacheHint) { + CacheEntry *e = m_cache; + while (e) { + if (e->data) + e->cleanup(e->engine, e->data); + CacheEntry *n = e->next; + delete e; + e = n; + } + } +} + QRectF QVectorPath::controlPointRect() const { @@ -94,7 +108,7 @@ QRectF QVectorPath::controlPointRect() const QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, - qvectorpath_cache_cleanup cleanup) { + qvectorpath_cache_cleanup cleanup) const{ Q_ASSERT(!lookupCacheData(engine)); if ((m_hints & IsCachedHint) == 0) { m_cache = 0; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 48629d1..443c9c5 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5886,7 +5886,12 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption Draws the text item \a ti at position \a p. */ -/*! \internal +/*! + \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti) + + \internal + \since 4.1 + Draws the text item \a ti at position \a p. This method ignores the painters background mode and @@ -5899,34 +5904,57 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption ignored aswell. You'll need to pass in the correct flags to get underlining and strikeout. */ -static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device) + +static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) { - extern int qt_defaultDpi(); + const qreal radiusBase = qMax(qreal(1), maxRadius); + + QString key = QLatin1String("WaveUnderline-"); + key += pen.color().name(); + key += QLatin1Char('-'); + key += QString::number(radiusBase); + + QPixmap pixmap; + if (QPixmapCache::find(key, pixmap)) + return pixmap; + + const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio + const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod); + const int radius = qFloor(radiusBase); + QPainterPath path; - bool up = true; - const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius)); - qreal xs, ys; - int i = 0; - path.moveTo(0, radius); - do { - xs = i*(2*radius); - ys = 0; + qreal xs = 0; + qreal ys = radius; - qreal remaining = minWidth - xs; - qreal angle = 180; + while (xs < width) { + xs += halfPeriod; + ys = -ys; + path.quadTo(xs - halfPeriod / 2, ys, xs, 0); + } - // cut-off at the last arc segment - if (remaining < 2 * radius) - angle = 180 * remaining / (2 * radius); + pixmap = QPixmap(width, radius * 2); + pixmap.fill(Qt::transparent); + { + QPen wavePen = pen; + wavePen.setCapStyle(Qt::SquareCap); + + // This is to protect against making the line too fat, as happens on Mac OS X + // due to it having a rather thick width for the regular underline. + const qreal maxPenWidth = .8 * radius; + if (wavePen.widthF() > maxPenWidth) + wavePen.setWidth(maxPenWidth); - path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle); + QPainter imgPainter(&pixmap); + imgPainter.setPen(wavePen); + imgPainter.setRenderHint(QPainter::Antialiasing); + imgPainter.translate(0, radius); + imgPainter.drawPath(path); + } - up = !up; - ++i; - } while (xs + 2*radius < minWidth); + QPixmapCache::insert(key, pixmap); - return path; + return pixmap; } static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) @@ -5947,9 +5975,11 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setCapStyle(Qt::FlatCap); QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y()); + + const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal()); + const qreal underlinePos = pos.y() + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); @@ -5957,16 +5987,18 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const if (underlineStyle == QTextCharFormat::WaveUnderline) { painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - painter->translate(pos.x(), underlinePos); + painter->translate(0, pos.y() + 1); QColor uc = ti.charFormat.underlineColor(); if (uc.isValid()) - painter->setPen(uc); + pen.setColor(uc); - painter->drawPath(generateWavyPath(ti.width.toReal(), - fe->underlinePosition().toReal(), - painter->device())); + // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms + const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); + const int descent = (int) ti.descent.toReal(); + + painter->setBrushOrigin(painter->brushOrigin().x(), 0); + painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); @@ -6001,10 +6033,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } -/*! - \internal - \since 4.1 -*/ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index ec27970..5eaddf4 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -68,7 +68,7 @@ QT_MODULE(Gui) class QPaintEngineEx; -typedef void (*qvectorpath_cache_cleanup)(void *data); +typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data); struct QRealRect { qreal x1, y1, x2, y2; @@ -118,6 +118,8 @@ public: { } + ~QVectorPath(); + QRectF controlPointRect() const; inline Hint shape() const { return (Hint) (m_hints & ShapeMask); } @@ -128,6 +130,7 @@ public: inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } inline bool hasWindingFill() const { return m_hints & WindingFill; } + inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; } inline uint hints() const { return m_hints; } inline const QPainterPath::ElementType *elements() const { return m_elements; } @@ -146,9 +149,9 @@ public: CacheEntry *next; }; - CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup); + CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup) const; inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const { - Q_ASSERT(m_hints & IsCachedHint); + Q_ASSERT(m_hints & ShouldUseCacheHint); CacheEntry *e = m_cache; while (e) { if (e->engine == engine) @@ -162,14 +165,14 @@ public: private: Q_DISABLE_COPY(QVectorPath) - CacheEntry *m_cache; - const QPainterPath::ElementType *m_elements; const qreal *m_points; const int m_count; mutable uint m_hints; mutable QRealRect m_cp_rect; + + mutable CacheEntry *m_cache; }; Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path); diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index fab3998..91974c2 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -770,8 +770,6 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight)); else if (vopt->features & QStyleOptionViewItemV2::Alternate) p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); - else if (!(vopt->state & QStyle::State_Enabled)) - p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Base)); } break; case PE_PanelItemViewItem: diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 51c2a96..4075cf7 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -4843,9 +4843,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex uint sc = SC_TitleBarMinButton; ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox; bool active = titlebar->state & State_Active; - int border = 2; - titleBarRect.origin.x += border; - titleBarRect.origin.y -= border; + if (qMacVersion() < QSysInfo::MV_10_6) { + int border = 2; + titleBarRect.origin.x += border; + titleBarRect.origin.y -= border; + } while (sc <= SC_TitleBarCloseButton) { if (sc & titlebar->subControls) { diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index b5c0d4f..dca78ca 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -144,7 +144,7 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed}, {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, - {SE_Editor, QS60StyleEnums::SP_QsnFrNotepadCenter}, + {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, }; static const int frameElementsCount = @@ -459,11 +459,6 @@ void QS60StylePrivate::setThemePalette(QApplication *app) const storeThemePalette(&widgetPalette); } -void QS60StylePrivate::setThemePalette(QStyleOption *option) const -{ - setThemePalette(&option->palette); -} - QPalette* QS60StylePrivate::themePalette() { return m_themePalette; @@ -475,6 +470,8 @@ void QS60StylePrivate::setBackgroundTexture(QApplication *app) const QPalette applicationPalette = QApplication::palette(); applicationPalette.setBrush(QPalette::Window, backgroundTexture()); setThemePalette(&applicationPalette); + QApplication::setPalette(applicationPalette); + setThemePaletteHash(&applicationPalette); } void QS60StylePrivate::deleteBackground() @@ -638,16 +635,16 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const { if(!widget) return; - QPalette widgetPalette = QApplication::palette(widget); //header view and its viewport need to be set 100% transparent button color, since drawing code will //draw transparent theme graphics to table column and row headers. if (qobject_cast<QHeaderView *>(widget)){ + QPalette widgetPalette = QApplication::palette(widget); widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); QHeaderView* header = qobject_cast<QHeaderView *>(widget); widgetPalette.setColor(QPalette::Button, Qt::transparent ); - if ( header->viewport() ) + if (header->viewport()) header->viewport()->setPalette(widgetPalette); QApplication::setPalette(widgetPalette, "QHeaderView"); } @@ -810,7 +807,7 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag case QS60StyleEnums::SP_QgnGrafTabActiveL: //Returned QSize for tabs must not be square, but narrow rectangle with width:height //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). - result.setWidth(10); + result.setWidth(result.height()>>1); break; case QS60StyleEnums::SP_QgnIndiSliderEdit: result.scale(pixelMetric(QStyle::PM_SliderLength), @@ -868,7 +865,7 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag return result; } -bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) +bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) { //If brush is not changed from style's default values, draw theme graphics. return (backgroundBrush.color() == Qt::transparent || @@ -1786,7 +1783,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (qobject_cast<const QAbstractButton *>(widget)) { //Make cornerButton slightly smaller so that it is not on top of table border graphic. QStyleOptionHeader subopt = *header; - const int borderTweak = + const int borderTweak = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); @@ -1879,7 +1876,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, adjustableFlags = (adjustableFlags | QS60StylePrivate::SF_PointWest); } else { const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); - if (option->direction == Qt::LeftToRight) + if (option->direction == Qt::LeftToRight) headerRect.adjust(-2*frameWidth, 0, 0, 0); else headerRect.adjust(0, 0, 2*frameWidth, 0); @@ -2025,7 +2022,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti buttonRect.setHeight((int)(buttonRect.height() * scaler)); // move the rect up for half of the new height-gain const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ; - buttonRect.adjust(0,-newY,0,-newY); + buttonRect.adjust(0, -newY, -1, -newY); painter->save(); QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); @@ -2594,7 +2591,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin); const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth); ret = toolButton->rect; - const bool popup = (toolButton->features & + const bool popup = (toolButton->features & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay)) == QStyleOptionToolButton::MenuButtonPopup; switch (scontrol) { diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index ea86bb2..5ab2308 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -271,15 +271,6 @@ public: SP_QsnFrButtonSideLInactive, SP_QsnFrButtonSideRInactive, SP_QsnFrButtonCenterInactive, - SP_QsnFrNotepadCornerTl, - SP_QsnFrNotepadCornerTr, - SP_QsnFrNotepadCornerBl, - SP_QsnFrNotepadCornerBr, - SP_QsnFrNotepadSideT, - SP_QsnFrNotepadSideB, - SP_QsnFrNotepadSideL, - SP_QsnFrNotepadSideR, - SP_QsnFrNotepadCenter }; enum ColorLists { @@ -418,8 +409,6 @@ public: //set theme palette for application void setThemePalette(QApplication *application) const; - //set theme palette for style option - void setThemePalette(QStyleOption *option) const; //access to theme palette static QPalette* themePalette(); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index a8dbf8d..48b8fad 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -1324,9 +1324,9 @@ QS60Style::QS60Style() void QS60StylePrivate::handleDynamicLayoutVariantSwitch() { clearCaches(QS60StylePrivate::CC_LayoutChange); + setBackgroundTexture(qApp); setActiveLayout(); refreshUI(); - setBackgroundTexture(qApp); foreach (QWidget *widget, QApplication::allWidgets()) widget->ensurePolished(); } diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 30f2f35..0a59d6d 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -213,10 +213,12 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) case QEvent::StyleChange: case QEvent::Show: if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) { - d->bars << bar; - if (d->bars.size() == 1) { - Q_ASSERT(d->animationFps> 0); - d->animateTimer = startTimer(1000 / d->animationFps); + if (!d->bars.contains(bar)) { + d->bars << bar; + if (d->bars.size() == 1) { + Q_ASSERT(d->animationFps> 0); + d->animateTimer = startTimer(1000 / d->animationFps); + } } } break; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 21b9cca..27fc3c1 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1370,8 +1370,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, for (int i = 0; i < len; ++i) { bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); - if (glyphs->glyphs[glyph_pos] == 0) { + if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) { QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos); for (int x = 1; x < engines.size(); ++x) { QFontEngine *engine = engines.at(x); diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 18851b7..7ec8e31 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -485,6 +485,7 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); } +#ifndef Q_WS_WINCE bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const { Q_ASSERT(metrics != 0); @@ -536,6 +537,7 @@ bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph return false; } } +#endif glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) { diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index 43e1f12..bab71c9 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -109,7 +109,9 @@ public: int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; void getCMap(); +#ifndef Q_WS_WINCE bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const; +#endif QString _name; HFONT hfont; diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 9b7e8de..1bd4dd6 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -447,18 +447,19 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat writer.writeStartElement(styleNS, QString::fromLatin1("paragraph-properties")); if (format.hasProperty(QTextFormat::BlockAlignment)) { + const Qt::Alignment alignment = format.alignment() & Qt::AlignHorizontal_Mask; QString value; - if (format.alignment() == Qt::AlignLeading) + if (alignment == Qt::AlignLeading) value = QString::fromLatin1("start"); - else if (format.alignment() == Qt::AlignTrailing) + else if (alignment == Qt::AlignTrailing) value = QString::fromLatin1("end"); - else if (format.alignment() == (Qt::AlignLeft | Qt::AlignAbsolute)) + else if (alignment == (Qt::AlignLeft | Qt::AlignAbsolute)) value = QString::fromLatin1("left"); - else if (format.alignment() == (Qt::AlignRight | Qt::AlignAbsolute)) + else if (alignment == (Qt::AlignRight | Qt::AlignAbsolute)) value = QString::fromLatin1("right"); - else if (format.alignment() == Qt::AlignHCenter) + else if (alignment == Qt::AlignHCenter) value = QString::fromLatin1("center"); - else if (format.alignment() == Qt::AlignJustify) + else if (alignment == Qt::AlignJustify) value = QString::fromLatin1("justify"); else qWarning() << "QTextOdfWriter: unsupported paragraph alignment; " << format.alignment(); diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 07914b2..0a26a77 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1167,7 +1167,8 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid QDockAreaLayoutInfo *subinfo = item.subinfo; QLayoutItem *widgetItem = item.widgetItem; - QRect r = subinfo == 0 ? dockedGeometry(widgetItem->widget()) : subinfo->rect; + QPlaceHolderItem *placeHolderItem = item.placeHolderItem; + QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect; Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal; #ifdef QT_NO_TABBAR @@ -1176,13 +1177,15 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid QDockAreaLayoutInfo *new_info = new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow); + //item become a new top-level item.subinfo = new_info; item.widgetItem = 0; + item.placeHolderItem = 0; QDockAreaLayoutItem new_item = widgetItem == 0 ? QDockAreaLayoutItem(subinfo) - : QDockAreaLayoutItem(widgetItem); + : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem); new_item.size = pick(opposite, r.size()); new_item.pos = pick(opposite, r.topLeft()); new_info->item_list.append(new_item); diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp index d601f81..b976b94 100644 --- a/src/gui/widgets/qfontcombobox.cpp +++ b/src/gui/widgets/qfontcombobox.cpp @@ -269,9 +269,8 @@ void QFontComboBoxPrivate::_q_updateModel() void QFontComboBoxPrivate::_q_currentChanged(const QString &text) { Q_Q(QFontComboBox); - QFont newFont(text); - if (currentFont.family() != newFont.family()) { - currentFont = newFont; + if (currentFont.family() != text) { + currentFont.setFamily(text); emit q->currentFontChanged(currentFont); } } diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 87975c3..117c550 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -1586,16 +1586,16 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } } #endif //QT_NO_CLIPBOARD - else if (event == QKeySequence::MoveToStartOfLine) { + else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) { home(0); } - else if (event == QKeySequence::MoveToEndOfLine) { + else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) { end(0); } - else if (event == QKeySequence::SelectStartOfLine) { + else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) { home(1); } - else if (event == QKeySequence::SelectEndOfLine) { + else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) { end(1); } else if (event == QKeySequence::MoveToNextChar) { diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 3800224..785b2bd 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1411,6 +1411,8 @@ bool QLineEdit::event(QEvent * e) QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate())); }else if(e->type() == QEvent::ShortcutOverride){ d->control->processEvent(e); + } else if (e->type() == QEvent::KeyRelease) { + d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); } #ifdef QT_KEYPAD_NAVIGATION @@ -1615,6 +1617,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) } #endif d->control->processKeyEvent(event); + if (event->isAccepted()) + d->control->setCursorBlinkPeriod(0); } /*! diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 501e62f..557acfb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -120,6 +120,7 @@ void QMainWindowPrivate::init() #ifdef QT_SOFTKEYS_ENABLED menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q); menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction")); + menuBarAction->setVisible(false); #endif } diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 761a060..2e27226 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -229,7 +229,7 @@ void QMenuPrivate::updateActionRects() const Q_Q(const QMenu); if (!itemsDirty) return; - + q->ensurePolished(); //let's reinitialize the buffer @@ -292,7 +292,7 @@ void QMenuPrivate::updateActionRects() const if (!action->isVisible() || (collapsibleSeparators && previousWasSeparator && action->isSeparator())) continue; // we continue, this action will get an empty QRect - + previousWasSeparator = action->isSeparator(); //let the style modify the above size.. @@ -1139,7 +1139,7 @@ void QMenuPrivate::_q_actionTriggered() //we check the parent hierarchy QList< QPointer<QWidget> > list; for(QWidget *widget = q->parentWidget(); widget; ) { - if (qobject_cast<QMenu*>(widget) + if (qobject_cast<QMenu*>(widget) #ifndef QT_NO_MENUBAR || qobject_cast<QMenuBar*>(widget) #endif @@ -1306,7 +1306,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) the addAction(), addActions() and insertAction() functions. An action is represented vertically and rendered by QStyle. In addition, actions can have a text label, an optional icon drawn on the very left side, - and shortcut key sequence such as "Ctrl+X". + and shortcut key sequence such as "Ctrl+X". The existing actions held by a menu can be found with actions(). @@ -1906,9 +1906,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction) pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); } else { if (pos.x()+size.width()-1 > screen.right()-desktopFrame) - pos.setX(qMin(p.x()+size.width(), screen.right()-desktopFrame-size.width()+1)); + pos.setX(screen.right()-desktopFrame-size.width()+1); if (pos.x() < screen.left()+desktopFrame) - pos.setX(qMax(p.x(), screen.left() + desktopFrame)); + pos.setX(screen.left() + desktopFrame); } if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { if(snapToMouse) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c7759e8..eae8b7d 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1802,6 +1802,9 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e) QTextBlock block = firstVisibleBlock(); qreal maximumWidth = document()->documentLayout()->documentSize().width(); + // Set a brush origin so that the WaveUnderline knows where the wave started + painter.setBrushOrigin(offset); + // keep right margin clean from full-width selection int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) - document()->documentMargin(); diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index 9eb07ac..50b225c 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -65,14 +65,13 @@ class QSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QSpinBox) public: - QSpinBoxPrivate(QWidget *parent = 0); + QSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; virtual QString textFromValue(const QVariant &n) const; QVariant validateAndInterpret(QString &input, int &pos, QValidator::State &state) const; - QChar thousand; inline void init() { Q_Q(QSpinBox); @@ -85,7 +84,7 @@ class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QDoubleSpinBox) public: - QDoubleSpinBoxPrivate(QWidget *parent = 0); + QDoubleSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; @@ -95,7 +94,6 @@ public: double round(double input) const; // variables int decimals; - QChar delimiter, thousand; inline void init() { Q_Q(QDoubleSpinBox); @@ -201,7 +199,7 @@ public: */ QSpinBox::QSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->init(); @@ -213,7 +211,7 @@ QSpinBox::QSpinBox(QWidget *parent) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); setObjectName(QString::fromAscii(name)); @@ -225,7 +223,7 @@ QSpinBox::QSpinBox(QWidget *parent, const char *name) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->minimum = QVariant(qMin<int>(minimum, maximum)); @@ -464,10 +462,9 @@ void QSpinBox::setRange(int minimum, int maximum) QString QSpinBox::textFromValue(int value) const { - Q_D(const QSpinBox); QString str = locale().toString(value); if (qAbs(value) >= 1000 || value == INT_MIN) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; @@ -516,9 +513,7 @@ QValidator::State QSpinBox::validate(QString &text, int &pos) const */ void QSpinBox::fixup(QString &input) const { - Q_D(const QSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } @@ -600,7 +595,7 @@ void QSpinBox::fixup(QString &input) const \sa setMinimum(), setMaximum(), setSingleStep() */ QDoubleSpinBox::QDoubleSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QDoubleSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QDoubleSpinBoxPrivate, parent) { Q_D(QDoubleSpinBox); d->init(); @@ -875,7 +870,7 @@ QString QDoubleSpinBox::textFromValue(double value) const Q_D(const QDoubleSpinBox); QString str = locale().toString(value, 'f', d->decimals); if (qAbs(value) >= 1000.0) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; } @@ -920,9 +915,7 @@ QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const */ void QDoubleSpinBox::fixup(QString &input) const { - Q_D(const QDoubleSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } // --- QSpinBoxPrivate --- @@ -932,18 +925,13 @@ void QDoubleSpinBox::fixup(QString &input) const Constructs a QSpinBoxPrivate object */ -QSpinBoxPrivate::QSpinBoxPrivate(QWidget *parent) +QSpinBoxPrivate::QSpinBoxPrivate() { minimum = QVariant((int)0); maximum = QVariant((int)99); value = minimum; singleStep = QVariant((int)1); type = QVariant::Int; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567); - if (str.size() == 5) { - thousand = QChar(str.at(1)); - } - } /*! @@ -1019,20 +1007,17 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100 } else { bool ok = false; - bool removedThousand = false; num = locale.toInt(copy, &ok, 10); - if (!ok && copy.contains(thousand) && (max >= 1000 || min <= -1000)) { - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - removedThousand = true; - num = locale.toInt(copy, &ok, 10); + if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) { + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toInt(copy2, &ok, 10); } QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num; if (!ok) { state = QValidator::Invalid; } else if (num >= min && num <= max) { - state = removedThousand ? QValidator::Intermediate : QValidator::Acceptable; + state = QValidator::Acceptable; } else if (max == min) { state = QValidator::Invalid; } else { @@ -1064,7 +1049,7 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, Constructs a QSpinBoxPrivate object */ -QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) +QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate() { minimum = QVariant(0.0); maximum = QVariant(99.99); @@ -1072,15 +1057,6 @@ QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) singleStep = QVariant(1.0); decimals = 2; type = QVariant::Double; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567.1); - if (str.size() == 6) { - delimiter = str.at(4); - thousand = QChar((ushort)0); - } else if (str.size() == 7) { - thousand = str.at(1); - delimiter = str.at(5); - } - Q_ASSERT(!delimiter.isNull()); } /*! @@ -1155,7 +1131,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = max != min ? QValidator::Intermediate : QValidator::Invalid; goto end; case 1: - if (copy.at(0) == delimiter + if (copy.at(0) == locale.decimalPoint() || (plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-'))) { state = QValidator::Intermediate; @@ -1163,7 +1139,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } break; case 2: - if (copy.at(1) == delimiter + if (copy.at(1) == locale.decimalPoint() && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) { state = QValidator::Intermediate; goto end; @@ -1172,14 +1148,14 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, default: break; } - if (copy.at(0) == thousand) { + if (copy.at(0) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; } else if (len > 1) { - const int dec = copy.indexOf(delimiter); + const int dec = copy.indexOf(locale.decimalPoint()); if (dec != -1) { - if (dec + 1 < copy.size() && copy.at(dec + 1) == delimiter && pos == dec + 1) { + if (dec + 1 < copy.size() && copy.at(dec + 1) == locale.decimalPoint() && pos == dec + 1) { copy.remove(dec + 1, 1); // typing a delimiter when you are on the delimiter } // should be treated as typing right arrow @@ -1189,7 +1165,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, goto end; } for (int i=dec + 1; i<copy.size(); ++i) { - if (copy.at(i).isSpace() || copy.at(i) == thousand) { + if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; @@ -1198,12 +1174,12 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } else { const QChar &last = copy.at(len - 1); const QChar &secondLast = copy.at(len - 2); - if ((last == thousand || last.isSpace()) - && (secondLast == thousand || secondLast.isSpace())) { + if ((last == locale.groupSeparator() || last.isSpace()) + && (secondLast == locale.groupSeparator() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; - } else if (last.isSpace() && (!thousand.isSpace() || secondLast.isSpace())) { + } else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1215,11 +1191,10 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, bool ok = false; num = locale.toDouble(copy, &ok); QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok; - bool notAcceptable = false; if (!ok) { - if (thousand.isPrint()) { - if (max < 1000 && min > -1000 && copy.contains(thousand)) { + if (locale.groupSeparator().isPrint()) { + if (max < 1000 && min > -1000 && copy.contains(locale.groupSeparator())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1227,27 +1202,23 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, const int len = copy.size(); for (int i=0; i<len- 1; ++i) { - if (copy.at(i) == thousand && copy.at(i + 1) == thousand) { + if (copy.at(i) == locale.groupSeparator() && copy.at(i + 1) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; } } - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - - - num = locale.toDouble(copy, &ok); - QSBDEBUG() << thousand << num << copy << ok; + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toDouble(copy2, &ok); + QSBDEBUG() << locale.groupSeparator() << num << copy2 << ok; if (!ok) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; } - notAcceptable = true; } } @@ -1255,9 +1226,8 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; } else if (num >= min && num <= max) { - state = notAcceptable ? QValidator::Intermediate : QValidator::Acceptable; - QSBDEBUG() << __FILE__ << __LINE__<< "state is set to " - << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable"); + state = QValidator::Acceptable; + QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Acceptable"; } else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min) state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index b7e985c..c329305 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -1296,6 +1296,8 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* QList<QToolBar*> toolBars = _toolBars; int lines; stream >> lines; + if (!testing) + testing = mainWindow->unifiedTitleAndToolBarOnMac(); for (int j = 0; j < lines; ++j) { int pos; @@ -1306,6 +1308,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* stream >> cnt; QToolBarAreaLayoutInfo &dock = docks[pos]; + const bool applyingLayout = !testing && !(pos == QInternal::TopDock && mainWindow->unifiedTitleAndToolBarOnMac()); QToolBarAreaLayoutLine line(dock.o); for (int k = 0; k < cnt; ++k) { @@ -1346,7 +1349,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* continue; } - if (!testing) { + if (applyingLayout) { item.widgetItem = new QWidgetItemV2(toolBar); toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o); toolBar->setVisible(shown & 1); @@ -1357,7 +1360,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* } } - if (!testing) { + if (applyingLayout) { dock.lines.append(line); } } diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index 1fe3999..ee1a797 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE void QGL2PEXVertexArray::clear() { vertexArray.reset(); - vertexArrayStops.clear(); + vertexArrayStops.reset(); boundingRectDirty = true; } @@ -101,7 +101,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc boundingRectDirty = false; } - if (!outline) + if (!outline && !path.isConvex()) addCentroid(path, 0); int lastMoveTo = vertexArray.size(); @@ -120,15 +120,14 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc // qDebug("QVectorPath has element types"); for (int i=1; i<path.elementCount(); ++i) { - const QPainterPath::ElementType elementType = elements[i]; - switch (elementType) { + switch (elements[i]) { case QPainterPath::MoveToElement: if (!outline) addClosingLine(lastMoveTo); // qDebug("element[%d] is a MoveToElement", i); - vertexArrayStops.append(vertexArray.size()); + vertexArrayStops.add(vertexArray.size()); if (!outline) { - addCentroid(path, i); + if (!path.isConvex()) addCentroid(path, i); lastMoveTo = vertexArray.size(); } lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex @@ -137,11 +136,22 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc // qDebug("element[%d] is a LineToElement", i); lineToArray(points[i].x(), points[i].y()); break; - case QPainterPath::CurveToElement: -// qDebug("element[%d] is a CurveToElement", i); - curveToArray(points[i], points[i+1], points[i+2], curveInverseScale); - i+=2; - break; + case QPainterPath::CurveToElement: { + QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1), + points[i], + points[i+1], + points[i+2]); + QRectF bounds = b.bounds(); + // threshold based on same algorithm as in qtriangulatingstroker.cpp + int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6)); + if (threshold < 3) threshold = 3; + qreal one_over_threshold_minus_1 = 1.f / (threshold - 1); + for (int t=0; t<threshold; ++t) { + QPointF pt = b.pointAt(t * one_over_threshold_minus_1); + lineToArray(pt.x(), pt.y()); + } + i += 2; + break; } default: break; } @@ -150,7 +160,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc if (!outline) addClosingLine(lastMoveTo); - vertexArrayStops.append(vertexArray.size()); + vertexArrayStops.add(vertexArray.size()); } void QGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y) @@ -167,35 +177,4 @@ void QGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y) minY = y; } -void QGL2PEXVertexArray::curveToArray(const QGLPoint &cp1, const QGLPoint &cp2, const QGLPoint &ep, GLfloat inverseScale) -{ - qreal inverseScaleHalf = inverseScale / 2; - - QBezier beziers[32]; - beziers[0] = QBezier::fromPoints(vertexArray.last(), cp1, cp2, ep); - QBezier *b = beziers; - while (b >= beziers) { - // check if we can pop the top bezier curve from the stack - qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1); - qreal d; - if (l > inverseScale) { - d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) ) - + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) ); - d /= l; - } else { - d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) + - qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3); - } - if (d < inverseScaleHalf || b == beziers + 31) { - // good enough, we pop it off and add the endpoint - lineToArray(b->x4, b->y4); - --b; - } else { - // split, second half of the polygon goes lower into the stack - b->split(b+1, b); - ++b; - } - } -} - QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index 719904f..98eaa91 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -108,23 +108,23 @@ public: void clear(); QGLPoint* data() {return vertexArray.data();} - QVector<int>& stops() {return vertexArrayStops;} + int *stops() const { return vertexArrayStops.data(); } + int stopCount() const { return vertexArrayStops.size(); } QGLRect boundingRect() const; + int vertexCount() const { return vertexArray.size(); } + void lineToArray(const GLfloat x, const GLfloat y); private: QDataBuffer<QGLPoint> vertexArray; - QVector<int> vertexArrayStops; + QDataBuffer<int> vertexArrayStops; GLfloat maxX; GLfloat maxY; GLfloat minX; GLfloat minY; bool boundingRectDirty; - - inline void curveToArray(const QGLPoint &cp1, const QGLPoint &cp2, const QGLPoint &ep, GLfloat inverseScale); - void addClosingLine(int index); void addCentroid(const QVectorPath &path, int subPathIndex); }; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 823f919..3fce384 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -62,6 +62,8 @@ and use the correct program when we really need it. */ +// #define QT_OPENGL_CACHE_AS_VBOS + #include "qpaintengineex_opengl2_p.h" #include <string.h> //for memcpy @@ -344,6 +346,13 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() { delete shaderManager; + + while (pathCaches.size()) { + QVectorPath::CacheEntry *e = *(pathCaches.constBegin()); + e->cleanup(e->engine, e->data); + e->data = 0; + e->engine = 0; + } } void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) @@ -846,6 +855,30 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) mode = newMode; } +struct QGL2PEVectorPathCache +{ +#ifdef QT_OPENGL_CACHE_AS_VBOS + GLuint vbo; +#else + float *vertices; +#endif + int vertexCount; + GLenum primitiveType; + qreal iscale; +}; + +void qopengl2paintengine_cleanup_vectorpath(QPaintEngineEx *engine, void *data) +{ + QGL2PEVectorPathCache *c = (QGL2PEVectorPathCache *) data; +#ifdef QT_OPENGL_CACHE_AS_VBOS + QGL2PaintEngineExPrivate *d = QGL2PaintEngineExPrivate::getData((QGL2PaintEngineEx *) engine); + d->unusedVBOSToClean << c->vbo; +#else + qFree(c->vertices); +#endif + delete c; +} + // Assumes everything is configured for the brush you want to use void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { @@ -863,10 +896,74 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush->isOpaque()); composite(rect); } else if (path.isConvex()) { - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - prepareForDraw(currentBrush->isOpaque()); - drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); + + if (path.isCacheable()) { + QVectorPath::CacheEntry *data = path.lookupCacheData(q); + QGL2PEVectorPathCache *cache; + + if (data) { + cache = (QGL2PEVectorPathCache *) data->data; + // Check if scale factor is exceeded for curved paths and generate curves if so... + if (path.isCurved()) { + qreal scaleFactor = cache->iscale / inverseScale; + if (scaleFactor < 0.5 || scaleFactor > 2.0) { +#ifdef QT_OPENGL_CACHE_AS_VBOS + glDeleteBuffers(1, &cache->vbo); + cache->vbo = 0; +#else + qFree(cache->vertices); +#endif + cache->vertexCount = 0; + } + } + } else { + cache = new QGL2PEVectorPathCache; + cache->vertexCount = 0; + data = const_cast<QVectorPath &>(path).addCacheData(q, cache, qopengl2paintengine_cleanup_vectorpath); + } + + // Flatten the path at the current scale factor and fill it into the cache struct. + if (!cache->vertexCount) { + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale, false); + int vertexCount = vertexCoordinateArray.vertexCount(); + int floatSizeInBytes = vertexCount * 2 * sizeof(float); + cache->vertexCount = vertexCount; + cache->primitiveType = GL_TRIANGLE_FAN; + cache->iscale = inverseScale; +#ifdef QT_OPENGL_CACHE_AS_VBOS + glGenBuffers(1, &cache->vbo); + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); +#else + cache->vertices = (float *) qMalloc(floatSizeInBytes); + memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes); +#endif + } + + prepareForDraw(currentBrush->isOpaque()); + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); +#ifdef QT_OPENGL_CACHE_AS_VBOS + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, 0); +#else + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, cache->vertices); +#endif + glDrawArrays(cache->primitiveType, 0, cache->vertexCount); + + } else { + // printf(" - Marking path as cachable...\n"); + // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable + // ### Remove before release... + static bool do_vectorpath_cache = qgetenv("QT_OPENGL_NO_PATH_CACHE").isEmpty(); + if (do_vectorpath_cache) + path.makeCacheable(); + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale, false); + prepareForDraw(currentBrush->isOpaque()); + drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); + } + } else { // The path is too complicated & needs the stencil technique vertexCoordinateArray.clear(); @@ -908,7 +1005,8 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, int count, - const QVector<int> *stops, + int *stops, + int stopCount, const QGLRect &bounds, StencilFillMode mode) { @@ -966,7 +1064,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, // Dec. for back-facing "holes" glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); glStencilMask(~GL_STENCIL_HIGH_BIT); - drawVertexArrays(data, stops, GL_TRIANGLE_FAN); + drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); if (q->state()->clipTestEnabled) { // Clear high bit of stencil outside of path @@ -978,7 +1076,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, } else if (mode == OddEvenFillMode) { glStencilMask(GL_STENCIL_HIGH_BIT); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit - drawVertexArrays(data, stops, GL_TRIANGLE_FAN); + drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); } else { // TriStripStrokeFillMode Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops @@ -1137,7 +1235,7 @@ void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect) } // Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans. -void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, const QVector<int> *stops, +void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive) { // Now setup the pointer to the vertex array: @@ -1145,7 +1243,8 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, const QVector glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, data); int previousStop = 0; - foreach(int stop, *stops) { + for (int i=0; i<stopCount; ++i) { + int stop = stops[i]; /* qDebug("Drawing triangle fan for vertecies %d -> %d:", previousStop, stop-1); for (int i=previousStop; i<stop; ++i) @@ -1304,7 +1403,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); d->fillStencilWithVertexArray(d->stroker.vertices(), d->stroker.vertexCount() / 2, - 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); + 0, 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); @@ -1452,7 +1551,8 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 @@ -1753,7 +1853,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->device->beginPaint(); #if !defined(QT_OPENGL_ES_2) - bool success = qt_resolve_version_2_0_functions(d->ctx); + bool success = qt_resolve_version_2_0_functions(d->ctx) + && qt_resolve_buffer_extensions(d->ctx); Q_ASSERT(success); Q_UNUSED(success); #endif @@ -1773,13 +1874,10 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; #if !defined(QT_OPENGL_ES_2) - if (!d->device->format().alpha() #if defined(Q_WS_WIN) - && qt_cleartype_enabled + if (qt_cleartype_enabled) #endif - ) { d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; - } #endif #if defined(QT_OPENGL_ES_2) @@ -1817,6 +1915,13 @@ bool QGL2PaintEngineEx::end() delete d->shaderManager; d->shaderManager = 0; +#ifdef QT_OPENGL_CACHE_AS_VBOS + if (!d->unusedVBOSToClean.isEmpty()) { + glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData()); + d->unusedVBOSToClean.clear(); + } +#endif + return false; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 9720723..0084476 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -195,18 +195,18 @@ public: void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti); - void drawVertexArrays(const float *data, const QVector<int> *stops, GLenum primitive); + void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive); void drawVertexArrays(QGL2PEXVertexArray &vertexArray, GLenum primitive) { - drawVertexArrays((const float *) vertexArray.data(), &vertexArray.stops(), primitive); + drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive); } // ^ draws whatever is in the vertex array void composite(const QGLRect& boundingRect); // ^ Composites the bounding rect onto dest buffer - void fillStencilWithVertexArray(const float *data, int count, const QVector<int> *stops, const QGLRect &bounds, StencilFillMode mode); + void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QGLRect &bounds, StencilFillMode mode); void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill) { - fillStencilWithVertexArray((const float *) vertexArray.data(), 0, &vertexArray.stops(), + fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(), vertexArray.boundingRect(), useWindingFill ? WindingFillMode : OddEvenFillMode); } @@ -221,6 +221,7 @@ public: void restoreDepthRangeForRenderText(); static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; } + static QGL2PaintEngineExPrivate *getData(QGL2PaintEngineEx *engine) { return engine->d_func(); } QGL2PaintEngineEx* q; QGLPaintDevice* device; @@ -294,6 +295,9 @@ public: QScopedPointer<QPixmapFilter> fastBlurFilter; QScopedPointer<QPixmapFilter> dropShadowFilter; QScopedPointer<QPixmapFilter> fastDropShadowFilter; + + QSet<QVectorPath::CacheEntry *> pathCaches; + QVector<GLuint> unusedVBOSToClean; }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index 1478b09..6082f49 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -209,6 +209,65 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen) } } +void QTriangulatingStroker::moveTo(const qreal *pts) +{ + m_cx = pts[0]; + m_cy = pts[1]; + + float x2 = pts[2]; + float y2 = pts[3]; + normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); + + + // To acheive jumps we insert zero-area tringles. This is done by + // adding two identical points in both the end of previous strip + // and beginning of next strip + bool invisibleJump = m_vertices.size(); + + switch (m_cap_style) { + case Qt::FlatCap: + if (invisibleJump) { + m_vertices.add(m_cx + m_nvx); + m_vertices.add(m_cy + m_nvy); + } + break; + case Qt::SquareCap: { + float sx = m_cx - m_nvy; + float sy = m_cy + m_nvx; + if (invisibleJump) { + m_vertices.add(sx + m_nvx); + m_vertices.add(sy + m_nvy); + } + emitLineSegment(sx, sy, m_nvx, m_nvy); + break; } + case Qt::RoundCap: { + QVarLengthArray<float> points; + arcPoints(m_cx, m_cy, m_cx + m_nvx, m_cy + m_nvy, m_cx - m_nvx, m_cy - m_nvy, points); + m_vertices.resize(m_vertices.size() + points.size() + 2 * int(invisibleJump)); + int count = m_vertices.size(); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.at(--count) = points[2 * end - 1]; + m_vertices.at(--count) = points[2 * end - 2]; + --end; + if (front == end) + break; + m_vertices.at(--count) = points[2 * front + 1]; + m_vertices.at(--count) = points[2 * front + 0]; + ++front; + } + + if (invisibleJump) { + m_vertices.at(count - 1) = m_vertices.at(count + 1); + m_vertices.at(count - 2) = m_vertices.at(count + 0); + } + break; } + default: break; // ssssh gcc... + } + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + void QTriangulatingStroker::cubicTo(const qreal *pts) { const QPointF *p = (const QPointF *) pts; @@ -246,6 +305,152 @@ void QTriangulatingStroker::cubicTo(const qreal *pts) m_nvy = vy; } +void QTriangulatingStroker::join(const qreal *pts) +{ + // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) + normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); + + switch (m_join_style) { + case Qt::BevelJoin: + break; + case Qt::SvgMiterJoin: + case Qt::MiterJoin: { + // Find out on which side the join should be. + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + float xprod = prevNvx * m_nvy - prevNvy * m_nvx; + float px, py, qx, qy; + + // If the segments are parallel, use bevel join. + if (qFuzzyIsNull(xprod)) + break; + + // Find the corners of the previous and next segment to join. + if (xprod < 0) { + px = m_vertices.at(count - 2); + py = m_vertices.at(count - 1); + qx = m_cx - m_nvx; + qy = m_cy - m_nvy; + } else { + px = m_vertices.at(count - 4); + py = m_vertices.at(count - 3); + qx = m_cx + m_nvx; + qy = m_cy + m_nvy; + } + + // Find intersection point. + float pu = px * prevNvx + py * prevNvy; + float qv = qx * m_nvx + qy * m_nvy; + float ix = (m_nvy * pu - prevNvy * qv) / xprod; + float iy = (prevNvx * qv - m_nvx * pu) / xprod; + + // Check that the distance to the intersection point is less than the miter limit. + if ((ix - px) * (ix - px) + (iy - py) * (iy - py) <= m_miter_limit * m_miter_limit) { + m_vertices.add(ix); + m_vertices.add(iy); + m_vertices.add(ix); + m_vertices.add(iy); + } + // else + // Do a plain bevel join if the miter limit is exceeded or if + // the lines are parallel. This is not what the raster + // engine's stroker does, but it is both faster and similar to + // what some other graphics API's do. + + break; } + case Qt::RoundJoin: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + if (m_nvx * prevNvy - m_nvy * prevNvx < 0) { + arcPoints(0, 0, m_nvx, m_nvy, -prevNvx, -prevNvy, points); + for (int i = points.size() / 2; i > 0; --i) + emitLineSegment(m_cx, m_cy, points[2 * i - 2], points[2 * i - 1]); + } else { + arcPoints(0, 0, -prevNvx, -prevNvy, m_nvx, m_nvy, points); + for (int i = 0; i < points.size() / 2; ++i) + emitLineSegment(m_cx, m_cy, points[2 * i + 0], points[2 * i + 1]); + } + break; } + default: break; // gcc warn-- + } + + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + +void QTriangulatingStroker::endCap(const qreal *) +{ + switch (m_cap_style) { + case Qt::FlatCap: + break; + case Qt::SquareCap: + emitLineSegment(m_cx + m_nvy, m_cy - m_nvx, m_nvx, m_nvy); + break; + case Qt::RoundCap: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + arcPoints(m_cx, m_cy, m_vertices.at(count - 2), m_vertices.at(count - 1), m_vertices.at(count - 4), m_vertices.at(count - 3), points); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.add(points[2 * end - 2]); + m_vertices.add(points[2 * end - 1]); + --end; + if (front == end) + break; + m_vertices.add(points[2 * front + 0]); + m_vertices.add(points[2 * front + 1]); + ++front; + } + break; } + default: break; // to shut gcc up... + } +} + +void QTriangulatingStroker::arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points) +{ + float dx1 = fromX - cx; + float dy1 = fromY - cy; + float dx2 = toX - cx; + float dy2 = toY - cy; + + // while more than 180 degrees left: + while (dx1 * dy2 - dx2 * dy1 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 90 degrees left: + while (dx1 * dx2 + dy1 * dy2 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 0 degrees left: + while (dx1 * dy2 - dx2 * dy1 > 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // remove last point which was rotated beyond [toX, toY]. + if (!points.isEmpty()) + points.resize(points.size() - 2); +} + static void qdashprocessor_moveTo(qreal x, qreal y, void *data) { ((QDashedStrokeProcessor *) data)->addElement(QPainterPath::MoveToElement, x, y); diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index a0117d5..2dba0ce 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -43,6 +43,7 @@ #define QTRIANGULATINGSTROKER_P_H #include <private/qdatabuffer_p.h> +#include <qvarlengtharray.h> #include <private/qvectorpath_p.h> #include <private/qbezier_p.h> #include <private/qnumeric_p.h> @@ -62,13 +63,13 @@ public: private: inline void emitLineSegment(float x, float y, float nx, float ny); - inline void moveTo(const qreal *pts); + void moveTo(const qreal *pts); inline void lineTo(const qreal *pts); void cubicTo(const qreal *pts); - inline void join(const qreal *pts); + void join(const qreal *pts); inline void normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny); - inline void endCap(const qreal *pts); - inline void arc(float x, float y); + void endCap(const qreal *pts); + void arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points); void endCapOrJoinClosed(const qreal *start, const qreal *cur, bool implicitClose, bool endsAtStart); @@ -116,10 +117,6 @@ private: qreal m_inv_scale; }; - - - - inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny) { @@ -139,8 +136,6 @@ inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, fl *ny = dx * pw; } - - inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, float vy) { m_vertices.add(x + vx); @@ -149,103 +144,6 @@ inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, f m_vertices.add(y - vy); } - - -// We draw a full circle for any round join or round cap which is a -// bit of overkill... -inline void QTriangulatingStroker::arc(float x, float y) -{ - float dx = m_width; - float dy = 0; - for (int i=0; i<=m_roundness; ++i) { - float tmpx = dx * m_cos_theta - dy * m_sin_theta; - float tmpy = dx * m_sin_theta + dy * m_cos_theta; - dx = tmpx; - dy = tmpy; - emitLineSegment(x, y, dx, dy); - } -} - - - -inline void QTriangulatingStroker::endCap(const qreal *pts) -{ - switch (m_cap_style) { - case Qt::FlatCap: - break; - case Qt::SquareCap: { - float dx = m_cx - *(pts - 2); - float dy = m_cy - *(pts - 1); - - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - - emitLineSegment(m_cx + dx, m_cy + dy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - arc(m_cx, m_cy); - break; - default: break; // to shut gcc up... - } -} - - -void QTriangulatingStroker::moveTo(const qreal *pts) -{ - m_cx = pts[0]; - m_cy = pts[1]; - - float x2 = pts[2]; - float y2 = pts[3]; - normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); - - - // To acheive jumps we insert zero-area tringles. This is done by - // adding two identical points in both the end of previous strip - // and beginning of next strip - bool invisibleJump = m_vertices.size(); - - switch (m_cap_style) { - case Qt::FlatCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - break; - case Qt::SquareCap: { - float dx = x2 - m_cx; - float dy = y2 - m_cy; - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - float sx = m_cx - dx; - float sy = m_cy - dy; - if (invisibleJump) { - m_vertices.add(sx + m_nvx); - m_vertices.add(sy + m_nvy); - } - emitLineSegment(sx, sy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - - // This emitLineSegment is not needed for the arc, but we need - // to start where we put the invisibleJump vertex, otherwise - // we'll have visible triangles between subpaths. - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); - arc(m_cx, m_cy); - break; - default: break; // ssssh gcc... - } - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - - - void QTriangulatingStroker::lineTo(const qreal *pts) { emitLineSegment(pts[0], pts[1], m_nvx, m_nvy); @@ -253,52 +151,6 @@ void QTriangulatingStroker::lineTo(const qreal *pts) m_cy = pts[1]; } - - -void QTriangulatingStroker::join(const qreal *pts) -{ - // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) - normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); - - switch (m_join_style) { - case Qt::BevelJoin: - break; - case Qt::MiterJoin: { - int p1 = m_vertices.size() - 6; - int p2 = m_vertices.size() - 2; - QLineF line(m_vertices.at(p1), m_vertices.at(p1+1), - m_vertices.at(p2), m_vertices.at(p2+1)); - QLineF nextLine(m_cx - m_nvx, m_cy - m_nvy, - pts[0] - m_nvx, pts[1] - m_nvy); - - QPointF isect; - if (line.intersect(nextLine, &isect) != QLineF::NoIntersection - && QLineF(line.p2(), isect).length() <= m_miter_limit) { - // The intersection point mirrored over the m_cx, m_cy point - m_vertices.add(m_cx - (isect.x() - m_cx)); - m_vertices.add(m_cy - (isect.y() - m_cy)); - - // The intersection point - m_vertices.add(isect.x()); - m_vertices.add(isect.y()); - } - // else - // Do a plain bevel join if the miter limit is exceeded or if - // the lines are parallel. This is not what the raster - // engine's stroker does, but it is both faster and similar to - // what some other graphics API's do. - - break; } - case Qt::RoundJoin: - arc(m_cx, m_cy); - break; - - default: break; // gcc warn-- - } - - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - QT_END_NAMESPACE #endif diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index d5ca218..5ada125 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2277,13 +2277,21 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - flipping bits over y (%d ms)\n", time.elapsed()); #endif - int ipl = img.bytesPerLine() / 4; - int h = img.height(); - for (int y=0; y<h/2; ++y) { - int *a = (int *) img.scanLine(y); - int *b = (int *) img.scanLine(h - y - 1); - for (int x=0; x<ipl; ++x) - qSwap(a[x], b[x]); + if (img.isDetached()) { + int ipl = img.bytesPerLine() / 4; + int h = img.height(); + for (int y=0; y<h/2; ++y) { + int *a = (int *) img.scanLine(y); + int *b = (int *) img.scanLine(h - y - 1); + for (int x=0; x<ipl; ++x) + qSwap(a[x], b[x]); + } + } else { + // Create a new image and copy across. If we use the + // above in-place code then a full copy of the image is + // made before the lines are swapped, which processes the + // data twice. This version should only do it once. + img = img.mirrored(); } } diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index fda4b10..6b829dd 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1570,12 +1570,6 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) d->dirty |= QPaintEngine::DirtyClipRegion; - // If we have a non-simple transform, then use path-based clipping. - if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { - QPaintEngineEx::clip(rect, op); - return; - } - switch (op) { case Qt::NoClip: { @@ -1612,12 +1606,6 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) d->dirty |= QPaintEngine::DirtyClipRegion; - // If we have a non-simple transform, then use path-based clipping. - if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { - QPaintEngineEx::clip(region, op); - return; - } - switch (op) { case Qt::NoClip: { @@ -3459,14 +3447,11 @@ void QVGCompositionHelper::endCompositing() } void QVGCompositionHelper::blitWindow - (QVGEGLWindowSurfacePrivate *surface, const QRect& rect, - const QPoint& topLeft, int opacity) + (VGImage image, const QSize& imageSize, + const QRect& rect, const QPoint& topLeft, int opacity) { - // Get the VGImage that is acting as a back buffer for the window. - VGImage image = surface->surfaceImage(); if (image == VG_INVALID_HANDLE) return; - QSize imageSize = surface->surfaceSize(); // Determine which sub rectangle of the window to draw. QRect sr = rect.translated(-topLeft); diff --git a/src/openvg/qvgcompositionhelper_p.h b/src/openvg/qvgcompositionhelper_p.h index 3afe31e..ed24e73 100644 --- a/src/openvg/qvgcompositionhelper_p.h +++ b/src/openvg/qvgcompositionhelper_p.h @@ -71,8 +71,8 @@ public: void startCompositing(const QSize& screenSize); void endCompositing(); - void blitWindow(QVGEGLWindowSurfacePrivate *surface, const QRect& rect, - const QPoint& topLeft, int opacity); + void blitWindow(VGImage image, const QSize& imageSize, + const QRect& rect, const QPoint& topLeft, int opacity); void fillBackground(const QRegion& region, const QBrush& brush); void drawCursorPixmap(const QPixmap& pixmap, const QPoint& offset); void setScissor(const QRegion& region); diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 29d82c8..62871cf 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -200,6 +200,42 @@ static QEglContext *createContext(QPaintDevice *device) else eglSwapInterval(context->display(), 1); +#ifdef EGL_RENDERABLE_TYPE + // Has the user specified an explicit EGL configuration to use? + QByteArray configId = qgetenv("QT_VG_EGL_CONFIG"); + if (!configId.isEmpty()) { + EGLint cfgId = configId.toInt(); + EGLint properties[] = { + EGL_CONFIG_ID, cfgId, + EGL_NONE + }; + EGLint matching = 0; + EGLConfig cfg; + if (eglChooseConfig + (context->display(), properties, &cfg, 1, &matching) && + matching > 0) { + // Check that the selected configuration actually supports OpenVG + // and then create the context with it. + EGLint id = 0; + EGLint type = 0; + eglGetConfigAttrib + (context->display(), cfg, EGL_CONFIG_ID, &id); + eglGetConfigAttrib + (context->display(), cfg, EGL_RENDERABLE_TYPE, &type); + if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) { + context->setConfig(cfg); + if (!context->createContext()) { + delete context; + return 0; + } + return context; + } else { + qWarning("QT_VG_EGL_CONFIG: %d is not a valid OpenVG configuration", int(cfgId)); + } + } + } +#endif + // Choose an appropriate configuration for rendering into the device. QEglProperties configProps; configProps.setPaintDeviceFormat(device); @@ -211,19 +247,19 @@ static QEglContext *createContext(QPaintDevice *device) configProps.setValue(EGL_ALPHA_MASK_SIZE, 1); #endif #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT | + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { // Try again without the "pre" bit. - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); if (!context->chooseConfig(configProps)) { delete context; return 0; } } #else - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { delete context; diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 2d9c489..37adfa9 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -90,7 +90,7 @@ symbian: { } contains(QT_CONFIG, phonon): { - qtlibraries.sources += Phonon.dll + qtlibraries.sources += phonon.dll } contains(QT_CONFIG, script): { diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index dc0e0d0..b6aa872 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1101,16 +1101,6 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) } } -#ifndef QT_NO_QOBJECT - { - QHash<QObject*, QScript::QObjectData*>::const_iterator it; - for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) { - QScript::QObjectData *qdata = it.value(); - qdata->mark(markStack); - } - } -#endif - { QHash<int, QScriptTypeInfo*>::const_iterator it; for (it = m_typeInfos.constBegin(); it != m_typeInfos.constEnd(); ++it) { @@ -1134,6 +1124,17 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) context = context->parentContext(); } } + +#ifndef QT_NO_QOBJECT + markStack.drain(); // make sure everything is marked before marking qobject data + { + QHash<QObject*, QScript::QObjectData*>::const_iterator it; + for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) { + QScript::QObjectData *qdata = it.value(); + qdata->mark(markStack); + } + } +#endif } bool QScriptEnginePrivate::isCollecting() const diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 559fcd3..63ba9ec 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -83,22 +83,23 @@ struct QObjectConnection void mark(JSC::MarkStack& markStack) { - // ### need to find out if senderWrapper is marked if (senderWrapper) { - // see if the sender should be marked or not + // see if the sender should be marked or not; + // if the C++ object is owned by script, we don't want + // it to stay alive due to a script connection. Q_ASSERT(senderWrapper.inherits(&QScriptObject::info)); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(senderWrapper)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); - QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate); - if ((inst->ownership() == QScriptEngine::ScriptOwnership) - || ((inst->ownership() == QScriptEngine::AutoOwnership) - && inst->value() && !inst->value()->parent())) { - // #### don't mark if not marked otherwise - //senderWrapper = JSC::JSValue(); - markStack.append(senderWrapper); - } else { - markStack.append(senderWrapper); + if (!JSC::Heap::isCellMarked(scriptObject)) { + QScriptObjectDelegate *delegate = scriptObject->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); + QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate); + if ((inst->ownership() == QScriptEngine::ScriptOwnership) + || ((inst->ownership() == QScriptEngine::AutoOwnership) + && inst->value() && !inst->value()->parent())) { + senderWrapper = JSC::JSValue(); + } else { + markStack.append(senderWrapper); + } } } if (receiver) diff --git a/src/script/script.pro b/src/script/script.pro index 008c556..771047a 100644 --- a/src/script/script.pro +++ b/src/script/script.pro @@ -1,7 +1,7 @@ TARGET = QtScript QPRO_PWD = $$PWD QT = core -DEFINES += JSC=QTJSC jscyyparse=qtjscyyparse jscyylex=qtjscyylex jscyyerror=qtjscyyerror +DEFINES += JSC=QTJSC jscyyparse=qtjscyyparse jscyylex=qtjscyylex jscyyerror=qtjscyyerror WTF=QTWTF DEFINES += QT_BUILD_SCRIPT_LIB DEFINES += QT_NO_USING_NAMESPACE DEFINES += QLALR_NO_QSCRIPTGRAMMAR_DEBUG_INFO diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index b99cb28..86898e6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -292,7 +292,8 @@ void Generator::generateCode() QList<QByteArray> extraList; for (int i = 0; i < cdef->propertyList.count(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); - if (!isVariantType(p.type) && !metaTypes.contains(p.type)) { + if (!isVariantType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') && + !p.type.contains('<') && !p.type.contains('>')) { int s = p.type.lastIndexOf("::"); if (s > 0) { QByteArray scope = p.type.left(s); |